DLangExtensions is coming back

By | November 23, 2008

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.

12 thoughts on “DLangExtensions is coming back

  1. El Cy

    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 ?! 🙂

  2. Kyriacos Michael

    I cannot wait to install these extensions in D2009, as I used to have in D2007.

    Thank you for all your efforts.

  3. Oliver Giesen

    Hi Andy!
    Great stuff!
    Have you thought about implementing a ternary operator, too? That would really rock I think.

    Something like:

    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).

  4. Andreas Hausladen Post author

    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.

    (a > b) ?<Integer> a : b;

    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”

    (condition) ?<T> true-value : false-value


    SyntaxHelpers.ternary<T>(function: T;
        if Condition then
          Result := TrueValue
          Result := FalseValue;
  5. Oliver Giesen

    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;


  6. Andreas Hausladen Post author

    That would be the simple version. But what about this:

    MyFunc(AnotherFunc(), (a > b) ? a : b, (c < d) ? c : d);

    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.

  7. Oliver Giesen

    Well, I would probably write that as:

    MyFunc(AnotherFunc(), Max(a,b), Min(c,d));


    No, seriously, you got a point there.


  8. Andreas Hausladen Post author

    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.

    if a > b then
      if c < d then
        MyFunc(AnotherFunc(a, c))
        MyFunc(AnotherFunc(a, d));
    end else
      if c < d then
        MyFunc(AnotherFunc(b, c))
        MyFunc(AnotherFunc(b, d));

    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.

  9. Erik Knowles

    Hello Andreas,

    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.

  10. Andreas Hausladen Post author

    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.

Comments are closed.