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;
end;
TJSElementClass = Class of TJSElement;
TJSElementArray = array of TJSElement;
{ TJSEmptyBlockStatement - empty curly brackets }
@ -1758,9 +1759,38 @@ end;
{ TJSBinary }
destructor TJSBinary.Destroy;
var
El: TJSElement;
BinCnt: Integer;
Bins: TJSElementArray;
SubBin: TJSBinary;
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(FB);
inherited Destroy;
end;

View File

@ -1372,11 +1372,26 @@ begin
end;
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
S : String;
AllowCompact, WithBrackets: Boolean;
ElC: TClass;
Left: TJSElement;
SubBin: TJSBinaryExpression;
Binaries: TJSElementArray;
BinariesCnt: integer;
begin
{$IFDEF VerboseJSWriter}
System.writeln('TJSWriter.WriteBinary SkipRoundBrackets=',FSkipRoundBrackets);
@ -1386,20 +1401,10 @@ begin
Write('(');
FSkipRoundBrackets:=false;
ElC:=El.ClassType;
if El.A is TJSBinaryExpression then
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;
Left:=El.A;
AllowCompact:=False;
S:='';
if (El is TJSBinaryExpression) then
begin
S:=TJSBinaryExpression(El).OperatorString;
@ -1412,17 +1417,47 @@ begin
else
S:=' '+S+' ';
end;
FSkipRoundBrackets:=false;
ElC:=El.ClassType;
if El.B is TJSBinaryExpression then
if (El.B.ClassType=ElC)
and ((ElC=TJSLogicalOrExpression)
or (ElC=TJSLogicalAndExpression)) then
FSkipRoundBrackets:=true;
// Note: a+(b+c) <> a+b+c e.g. floats, 0+string
Write(S);
WriteJS(El.B);
Writer.CurElement:=El;
if (Left is TJSBinaryExpression)
and (Left.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
begin
// handle left handed multi add without stack
FSkipRoundBrackets:=true;
SetLength(Binaries{%H-},8);
BinariesCnt:=0;
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;
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
Write(')');
end;