The code below:
type
JClass = class external
foo: String;
end;
function BuildRequest(bar: String): JClass;
begin
Result := JClass(class
foo := bar;
end);
end;
should compile to something like:
function BuildRequest(bar) {
return {
"foo" : bar
};
};
However, it does compile to:
function BuildRequest(bar) {
var Result = null;
Result = {
"foo" : bar
};
return Result
};
It’s not that it is incorrect, but too verbose.
Now looking at the DWS code it seems that the optimize block is not really executed:
// optimize to a straight "return" statement for trivial functions
if (not resultIsBoxed) and (proc.Table.Count = 0)
and ((proc.InitExpr = nil) or (proc.InitExpr.SubExprCount = 0))
and (proc.Expr is TAssignExpr) then begin
since proc.Table.Count = 1 instead of 0 in most other trivial cases.
Now looking at proc.Table[0] there is an empty symbol (name = ‘’, description = ‘', typ = nil). I’m not sure why it is there in the first place, but as it does nothing it should be removed or at least taken into account like this:
// optimize to a straight "return" statement for trivial functions
if (not resultIsBoxed) and ((proc.Table.Count = 0) or
((proc.Table.Count = 1) and (proc.Table[0].Typ = nil)))
and ((proc.InitExpr = nil) or (proc.InitExpr.SubExprCount = 0))
and (proc.Expr is TAssignExpr) then begin
With this, the code is again optimized as expected.
The empty symbol is for the anonymous class symbol (the class..end within the cast).
I wonder if rather than looking at the local table symbol count, which holds both local variables and types (and could miss some in case of a sub-scope within a single expression, not possible yet, but could be added to the language later on), it should be possible to check the local stack size instead.
If it is allocated only for the “Result” value (and Result is not “boxed”, ie. not passed as a “var” parameter), I guess it should be safe to allow the “return” optimization even when there are multiple expressions, provided Result is assigned only once, and that assignment is the last expression ?
Edit: an extra condition would be the absence of any form of “exit” in the procedure, and that “Result” is never read-accessed, as in both those case the initialization to a default value would be required.