My tool DLangExtensions which has added case-string-of, extended for-in loops, FreePascal generics, multi line strings and an extended Exit to Delphi 5-2007 is returning to life. I have successfully migrated the tool to Delphi 2009 and removed the FreePascal generics and the extended Exit because both are superseded by Delphi 2009’s features. The tool will be available only for Delphi 2009. And no, I won’t port it back to Delphi 2007 or older. The migration to Delphi 2009 was hard enough because I not only had to do the usual and straight forward Delphi 2007 to Delphi 2009 migration but I also had to migrate the code that interoperates with the IDE. And that is the reason why DLangExtensions won’t be available for older IDE versions. Even the IDE version-independent CompileInterceptor.dll is now migrated to Delphi 2009 or newer and its name changed to CompileInterceptorW.dll. The next DDevExtension version will be based on the CompileInterceptorW.dll cutting off the last thing that was compatible with Delphi 2007.
With a working DLangExtensions the UniSwitch language extension (former Ansifyer) should be doable in less than 3 hours. Maybe I can spent them tomorrow or next weekend.
That’s just great Andy ….
You are doing (as usuall) a very good job with advancing the Delphi language (hopefully CG will catch on soon in Commodore ..or so!)
Just wondering what’s next ? …
Maybe you might consider to start a “Prismification” of the Delphi/Win32 2009 ?! 🙂
I cannot wait to install these extensions in D2009, as I used to have in D2007.
Thank you for all your efforts.
Have you thought about implementing a ternary operator, too? That would really rock I think.
value := condition ? trueValue : falseValue;
(though I don’t really like that syntax – doesn’t feel like Pascal)
The current IfThen function has the drawback that it always evaluates both values, so you couldn’t use it in something like:
ShowMessage(‘Component is ‘ + IfThen(Assigned(AComp), AComp.Name, ‘nil’));
furthermore, it needs overloads for uncommon data types (or, if implemented as a generic function, it requires the types to be explicitly specified).
I can only create new language features based on the existing syntax.
If I use anonymous methods to emulate the ternary operator it would look like.
The type must be specified because I do not have access to the type of “a” or “b”. It could be possible to use “Variant” as default for the type if you type “(a > b) ? a : b” => “(a > b) ?<Variant> a : b”
Andy, can you give some points on how a user/programmer can add new custom extensions, I have a couple of them in mind?.
There will be a plugin interface that allows you to add your own extensions.
Andy, couldn’t you simply replace the ternary syntax with an if-statement and an assignment to a local variable preceding the statement in which it occurs?
if condition then
temp := trueValue
temp := falseValue;
That would be the simple version. But what about this:
Moving the ternary operators out of the function call would change the execution order because AnotherFunc() would be called after both ternary operators were evaluated.
Well, I would probably write that as:
MyFunc(AnotherFunc(), Max(a,b), Min(c,d));
No, seriously, you got a point there.
The thing is that I had already tried to implement it last year. And something like the following was the ultimate brain killer I came up.
But even then you change the execution order if a, b, c or d is a function.
But with anonymous methods and generics it becomes a lot easier to implement. And with the $LINE compiler command I can insert as many lines as I want.
This isn’t really the place for this, and I apologize for leaving the note here, but you don’t leave contact info in your downloads nor anywhere on your site that I can find 🙁
Anyways, I’ve run across a problem with the previous version of DLangExtensions that may affect the current version, so I thought I’d let you know:
* In the string case code, if you compile with overflow checking on, the following line in FindIndex can trigger an overflow exception:
C := HashTbl[Result].Hash – Hash;
The problem is that both Hash field and variable are declared as Cardinal (i.e., unsigned integers), so the results of the subtraction overflow if Hash>HashTbl[Result].Hash.
I worked around the problem by using a resource editor on DLangExtensions.dll to change both instances of the line to be:
C := integer(HashTbl[Result].Hash) – integer(Hash);
Anyways, sorry for not checking first to see if you’ve fixed the problem with the current version, but I don’t have Delphi 2009 yet, so no reason to have that version. Thanks for the great add-on, though, and feel free to e-mail if you need clarification.
Thanks for this bug report.
BTW you can click on the “Andreas Hausladen” in “Copyright (C) Andreas Hausladen” on every page’s bottom, to send me an email.