2
0
Эх сурвалжийг харах

* foreachnodestatic extended so it can do pre processing of child nodes
* simplify processes first the children and determines their result type

git-svn-id: trunk@211 -

florian 20 жил өмнө
parent
commit
c53b3e5928
1 өөрчлөгдсөн 57 нэмэгдсэн , 35 устгасан
  1. 57 35
      compiler/nutils.pas

+ 57 - 35
compiler/nutils.pas

@@ -45,12 +45,15 @@ interface
       fen_norecurse_true
     );
 
+    tforeachprocmethod = (pm_preprocess,pm_postprocess);
+
 
     foreachnodefunction = function(var n: tnode; arg: pointer): foreachnoderesult of object;
     staticforeachnodefunction = function(var n: tnode; arg: pointer): foreachnoderesult;
 
     function foreachnode(var n: tnode; f: foreachnodefunction; arg: pointer): boolean;
     function foreachnodestatic(var n: tnode; f: staticforeachnodefunction; arg: pointer): boolean;
+    function foreachnodestatic(procmethod : tforeachprocmethod;var n: tnode; f: staticforeachnodefunction; arg: pointer): boolean;
 
     procedure load_procvar_from_calln(var p1:tnode);
     function maybe_call_procvar(var p1:tnode;tponly:boolean):boolean;
@@ -138,13 +141,52 @@ implementation
     end;
 
 
-  function foreachnodestatic(var n: tnode; f: staticforeachnodefunction; arg: pointer): boolean;
-    var
-      i: longint;
+  function foreachnodestatic(procmethod : tforeachprocmethod;var n: tnode; f: staticforeachnodefunction; arg: pointer): boolean;
+
+    function process_children(res : boolean) : boolean;
+      var
+        i: longint;
+      begin
+        result:=res;
+        case n.nodetype of
+          calln:
+            begin
+              result := foreachnodestatic(procmethod,tcallnode(n).methodpointer,f,arg) or result;
+{$ifdef PASS2INLINE}
+              result := foreachnodestatic(procmethod,tcallnode(n).inlinecode,f,arg) or result;
+{$endif PASS2INLINE}
+            end;
+          ifn, whilerepeatn, forn:
+            begin
+              { not in one statement, won't work because of b- }
+              result := foreachnodestatic(procmethod,tloopnode(n).t1,f,arg) or result;
+              result := foreachnodestatic(procmethod,tloopnode(n).t2,f,arg) or result;
+            end;
+          raisen:
+            result := foreachnodestatic(traisenode(n).frametree,f,arg) or result;
+          casen:
+            begin
+              for i := 0 to tcasenode(n).blocks.count-1 do
+                if assigned(tcasenode(n).blocks[i]) then
+                  result := foreachnodestatic(procmethod,pcaseblock(tcasenode(n).blocks[i])^.statement,f,arg) or result;
+              result := foreachnodestatic(procmethod,tcasenode(n).elseblock,f,arg) or result;
+            end;
+        end;
+        if n.inheritsfrom(tbinarynode) then
+          begin
+            result := foreachnodestatic(procmethod,tbinarynode(n).right,f,arg) or result;
+            result := foreachnodestatic(procmethod,tbinarynode(n).left,f,arg) or result;
+          end
+        else if n.inheritsfrom(tunarynode) then
+          result := foreachnodestatic(procmethod,tunarynode(n).left,f,arg) or result;
+      end;
+
     begin
       result := false;
       if not assigned(n) then
         exit;
+      if procmethod=pm_preprocess then
+        result:=process_children(result);
       case f(n,arg) of
         fen_norecurse_false:
           exit;
@@ -159,40 +201,17 @@ implementation
         fen_false:
           result := false; }
       end;
-      case n.nodetype of
-        calln:
-          begin
-            result := foreachnodestatic(tcallnode(n).methodpointer,f,arg) or result;
-{$ifdef PASS2INLINE}
-            result := foreachnodestatic(tcallnode(n).inlinecode,f,arg) or result;
-{$endif PASS2INLINE}
-          end;
-        ifn, whilerepeatn, forn:
-          begin
-            { not in one statement, won't work because of b- }
-            result := foreachnodestatic(tloopnode(n).t1,f,arg) or result;
-            result := foreachnodestatic(tloopnode(n).t2,f,arg) or result;
-          end;
-        raisen:
-          result := foreachnodestatic(traisenode(n).frametree,f,arg) or result;
-        casen:
-          begin
-            for i := 0 to tcasenode(n).blocks.count-1 do
-              if assigned(tcasenode(n).blocks[i]) then
-                result := foreachnodestatic(pcaseblock(tcasenode(n).blocks[i])^.statement,f,arg) or result;
-            result := foreachnodestatic(tcasenode(n).elseblock,f,arg) or result;
-          end;
-      end;
-      if n.inheritsfrom(tbinarynode) then
-        begin
-          result := foreachnodestatic(tbinarynode(n).right,f,arg) or result;
-          result := foreachnodestatic(tbinarynode(n).left,f,arg) or result;
-        end
-      else if n.inheritsfrom(tunarynode) then
-        result := foreachnodestatic(tunarynode(n).left,f,arg) or result;
+      if procmethod=pm_postprocess then
+        result:=process_children(result);
     end;
 
 
+    function foreachnodestatic(var n: tnode; f: staticforeachnodefunction; arg: pointer): boolean;
+      begin
+        foreachnodestatic(pm_postprocess,n,f,arg);
+      end;
+
+
     procedure load_procvar_from_calln(var p1:tnode);
       var
         p2 : tnode;
@@ -574,6 +593,9 @@ implementation
         hn : tnode;
       begin
         result:=fen_false;
+
+        do_resulttypepass(n);
+
         hn:=n.simplify;
         if assigned(hn) then
           begin
@@ -588,7 +610,7 @@ implementation
       begin
         repeat
           treechanged:=false;
-          foreachnodestatic(n,@callsimplify,nil);
+          foreachnodestatic(pm_preprocess,n,@callsimplify,nil);
         until not(treechanged);
       end;