Skip to content

Feature: Statement Expressions

Adding some statements as expressions

if-then-else

Probably the most common one in other languages, if-then-else expressions allow to return a value based on a condition:

s := if condition then 'True' else 'False';

Nothing too special.

case-of-else

Similar to if-then-else this would also be useful for case statements, especially as they can have ranges:

s := case Value of
  0: 'Foo';
  1..10: 'Bar';
  else 'Baz';

If the case is not exhaustive, there must be an else or otherwise branch.

Small note: to make it look similar to the if-then-else after the else there is no need for an end. if there is no else (so the case is exhaustive) then end is needed instead.

Also, I currently left the ; in, there might be a case to get rid of them for the expression case:

s := case Value of
  0: 'Foo'
  1..10: 'Bar'
  else 'Baz';

try-except-else

Lastly theres an expression variant for try-except statements:

// Generic except
s := try SomethingThatCanRaise except 'Error';
// Exception type matching
s := try SomethingThatCanRaise except on E: MyException do 'MyError' else 'GenericError';

Like with the case, this must be exhaustive, which means that there always must be a generic case.

See the tests for some examples

Other Statements

This MR adds the functionality to the pstatmt unit, trying to change as little to the parsing of the statements as possible. While this ensures syntactic equivalence between the expression and statement versions of these constructs, it also means this would be generally easily extensible to other statements.

I did not add the other statements, but it may be something to consider:

  • Loops: There can be made the case for something like the following but really it doesn't make much sense to me
last := while not queue.empty do queue.pop;
  • With: doing something like with MyObject do Member is rather pointless, but it actually may be of interest in combination with the others:
s := with MyObject do if condition then Member1 else Member2;
  • Raise: there may be the case for having a "if you get to this point in the evaluation of an expression something has gone really wrong" kind of thing, but after looking into it, it seems more complicated than it is worth. Still something like this would be interesting:
// Utilizing short circuit bool eval
if ComplexCondition Or Raise ShouldNeverHappen And ComplexCondition2 then ...
// Or in combination with the others
s := case MyValue of ... else raise EUnexpectedValue.Create;
  • Break, Continue, Exit: Similar to raise I guess it could be a shortcut jump if things go unexpected
  • Goto: I have absolutely no Idea what this would even mean

Merge request reports

Loading