소스 검색

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

git-svn-id: trunk@49029 -
(cherry picked from commit de0e5919c988d5687e136b74b998e057bf9a5d9d)
Mattias Gaertner 4 년 전
부모
커밋
2833c60373
2개의 변경된 파일92개의 추가작업 그리고 27개의 파일을 삭제
  1. 31 1
      packages/fcl-js/src/jstree.pp
  2. 61 26
      packages/fcl-js/src/jswriter.pp

+ 31 - 1
packages/fcl-js/src/jstree.pp

@@ -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;
 

+ 61 - 26
packages/fcl-js/src/jswriter.pp

@@ -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;