fcl-js: write and free TBinaryExpr left lists without stack

git-svn-id: trunk@49029 -
This commit is contained in:
Mattias Gaertner 2021-03-22 17:28:35 +00:00
parent a32a870f33
commit de0e5919c9
2 changed files with 92 additions and 27 deletions

View File

@ -158,6 +158,7 @@ Type
Property Flags : TJSElementFlags Read FFlags Write FFlags; Property Flags : TJSElementFlags Read FFlags Write FFlags;
end; end;
TJSElementClass = Class of TJSElement; TJSElementClass = Class of TJSElement;
TJSElementArray = array of TJSElement;
{ TJSEmptyBlockStatement - empty curly brackets } { TJSEmptyBlockStatement - empty curly brackets }
@ -1758,9 +1759,38 @@ end;
{ TJSBinary } { TJSBinary }
destructor TJSBinary.Destroy; destructor TJSBinary.Destroy;
var
El: TJSElement;
BinCnt: Integer;
Bins: TJSElementArray;
SubBin: TJSBinary;
begin begin
FreeAndNil(FB); if FA is TJSBinary then
begin
// free El binary chains without stack
El:=FA;
SetLength(Bins{%H-},8);
BinCnt:=0;
while El is TJSBinary do
begin
SubBin:=TJSBinary(El);
if BinCnt=length(Bins) then
SetLength(Bins,BinCnt*2);
Bins[BinCnt]:=SubBin;
inc(BinCnt);
El:=SubBin.FA;
end;
while BinCnt>0 do
begin
dec(BinCnt);
SubBin:=TJSBinary(Bins[BinCnt]);
FreeAndNil(SubBin.FA);
FreeAndNil(SubBin.FB);
end;
end;
FreeAndNil(FA); FreeAndNil(FA);
FreeAndNil(FB);
inherited Destroy; inherited Destroy;
end; end;

View File

@ -1372,11 +1372,26 @@ begin
end; end;
procedure TJSWriter.WriteBinary(El: TJSBinary); procedure TJSWriter.WriteBinary(El: TJSBinary);
var
ElC: TClass;
S : String;
procedure WriteRight(Bin: TJSBinary);
begin
FSkipRoundBrackets:=(Bin.B.ClassType=ElC)
and ((ElC=TJSLogicalOrExpression)
or (ElC=TJSLogicalAndExpression));
Write(S);
WriteJS(Bin.B);
Writer.CurElement:=Bin;
end;
Var Var
S : String;
AllowCompact, WithBrackets: Boolean; AllowCompact, WithBrackets: Boolean;
ElC: TClass; Left: TJSElement;
SubBin: TJSBinaryExpression;
Binaries: TJSElementArray;
BinariesCnt: integer;
begin begin
{$IFDEF VerboseJSWriter} {$IFDEF VerboseJSWriter}
System.writeln('TJSWriter.WriteBinary SkipRoundBrackets=',FSkipRoundBrackets); System.writeln('TJSWriter.WriteBinary SkipRoundBrackets=',FSkipRoundBrackets);
@ -1386,20 +1401,10 @@ begin
Write('('); Write('(');
FSkipRoundBrackets:=false; FSkipRoundBrackets:=false;
ElC:=El.ClassType; ElC:=El.ClassType;
if El.A is TJSBinaryExpression then Left:=El.A;
if (El.A.ClassType=ElC)
and ((ElC=TJSLogicalOrExpression)
or (ElC=TJSLogicalAndExpression)
or (ElC=TJSBitwiseAndExpression)
or (ElC=TJSBitwiseOrExpression)
or (ElC=TJSBitwiseXOrExpression)
or (ElC=TJSAdditiveExpressionPlus)
or (ElC=TJSAdditiveExpressionMinus)
or (ElC=TJSMultiplicativeExpressionMul)) then
FSkipRoundBrackets:=true;
WriteJS(El.A);
Writer.CurElement:=El;
AllowCompact:=False; AllowCompact:=False;
S:='';
if (El is TJSBinaryExpression) then if (El is TJSBinaryExpression) then
begin begin
S:=TJSBinaryExpression(El).OperatorString; S:=TJSBinaryExpression(El).OperatorString;
@ -1412,17 +1417,47 @@ begin
else else
S:=' '+S+' '; S:=' '+S+' ';
end; end;
FSkipRoundBrackets:=false;
ElC:=El.ClassType; if (Left is TJSBinaryExpression)
if El.B is TJSBinaryExpression then and (Left.ClassType=ElC)
if (El.B.ClassType=ElC)
and ((ElC=TJSLogicalOrExpression) and ((ElC=TJSLogicalOrExpression)
or (ElC=TJSLogicalAndExpression)) then or (ElC=TJSLogicalAndExpression)
or (ElC=TJSBitwiseAndExpression)
or (ElC=TJSBitwiseOrExpression)
or (ElC=TJSBitwiseXOrExpression)
or (ElC=TJSAdditiveExpressionPlus)
or (ElC=TJSAdditiveExpressionMinus)
or (ElC=TJSMultiplicativeExpressionMul)) then
begin
// handle left handed multi add without stack
FSkipRoundBrackets:=true; FSkipRoundBrackets:=true;
// Note: a+(b+c) <> a+b+c e.g. floats, 0+string SetLength(Binaries{%H-},8);
Write(S); BinariesCnt:=0;
WriteJS(El.B); while Left is TJSBinaryExpression do
begin
SubBin:=TJSBinaryExpression(Left);
if SubBin.ClassType<>ElC then break;
if BinariesCnt=length(Binaries) then
SetLength(Binaries,BinariesCnt*2);
Binaries[BinariesCnt]:=SubBin;
inc(BinariesCnt);
Left:=SubBin.A;
end;
WriteJS(Left);
Writer.CurElement:=El; Writer.CurElement:=El;
while BinariesCnt>0 do
begin
dec(BinariesCnt);
WriteRight(TJSBinaryExpression(Binaries[BinariesCnt]));
end;
end
else
begin;
WriteJS(Left);
Writer.CurElement:=El;
end;
WriteRight(El);
if WithBrackets then if WithBrackets then
Write(')'); Write(')');
end; end;