Hi all,
FPC trunk (3.3.1) now supports statement expressions. You can use if,
case and try..except as expressions that return a value.
Big thanks to Frederic Kehrein who implemented most parts.
Enabling
{$modeswitch StatementExpressions}
The modeswitch is on by default in {$mode delphi} and {$mode
delphiunicode}. All other modes, including objfpc, need the modeswitch.
if-expression
s := if Count > 0 then 'some' else 'none';
s := if i < 10 then 'small' else
if i < 100 then 'medium' else
'large';
DoSomething(if Verbose then LogLevelDebug else LogLevelInfo);
- The else part is required.
- Only the selected branch is evaluated.
- The else branch extends as far to the right as possible, so if b then
'A' else 'B' + 'C' means if b then 'A' else ('B' + 'C'). To use the
result in a larger expression, put the if-expression in brackets:
i := (if b then 10 else 20) + 1;
case-expression
s := case Color of
clRed: 'red';
clGreen: 'green';
else 'other'
end;
- It must end with end.
- It must cover every possible value. Either the labels cover the whole
ordinal range, e.g. all enum values or False/True, or there is an
else/otherwise branch. If neither holds, you get "Statement expression
does not handle all cases".
- Ranges (1..9:) and string case labels work as they do in case statements.
- The semicolon before else and before end is optional.
try..except-expression
n := try StrToInt(s) except -1 end;
s := try LoadName(Id)
except
on E: EFileNotFound do '<missing>';
else '<error>'
end;
- If there are on-do handlers, an else branch is required so that every
exception produces a value.
- try..finally cannot be used as an expression.
Result type
The branches must be type-compatible. The result has their common type,
e.g.:
- ShortString + UnicodeString gives UnicodeString.
- Two sibling classes give their common ancestor.
- A class + nil gives that class.
- A string + Variant gives Variant.
Overload resolution works on the result type. For example, Fly(if b then
1.5 else 2.5) selects the same overload as Fly(1.5).
Incompatible branches give an error, e.g. if b then 'Foo' else 32.
Nesting and anonymous functions
Statement expressions can be nested, and a branch can be an anonymous
function. The target must be a procedure variable or a reference to type:
{$mode delphi}
var
Handler: TProc;
begin
Handler :=
if Debug then
procedure begin WriteLn('debug'); end
else
procedure begin end;
Enjoy!
Mattias
_______________________________________________
fpc-pascal maillist - [email protected]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal