Explorar o código

* case statement inlining added
* fixed inlining of write()
* switched statementnode left and right parts so the statements are
processed in the correct order when getcopy is used. This is
required for tempnodes

peter %!s(int64=23) %!d(string=hai) anos
pai
achega
34e8266af4
Modificáronse 6 ficheiros con 209 adicións e 128 borrados
  1. 74 68
      compiler/nbas.pas
  2. 12 5
      compiler/ncgbas.pas
  3. 60 6
      compiler/ncgset.pas
  4. 19 19
      compiler/ninl.pas
  5. 23 16
      compiler/nset.pas
  6. 21 14
      compiler/pstatmnt.pas

+ 74 - 68
compiler/nbas.pas

@@ -186,17 +186,17 @@ implementation
     function internalstatements(var laststatement:tstatementnode):tblocknode;
       begin
         { create dummy initial statement }
-        laststatement := cstatementnode.create(nil,cnothingnode.create);
+        laststatement := cstatementnode.create(cnothingnode.create,nil);
         internalstatements := cblocknode.create(laststatement);
       end;
 
 
     procedure addstatement(var laststatement:tstatementnode;n:tnode);
       begin
-        if assigned(laststatement.left) then
+        if assigned(laststatement.right) then
          internalerror(200204201);
-        laststatement.left:=cstatementnode.create(nil,n);
-        laststatement:=tstatementnode(laststatement.left);
+        laststatement.right:=cstatementnode.create(n,nil);
+        laststatement:=tstatementnode(laststatement.right);
       end;
 
 
@@ -260,22 +260,22 @@ implementation
          result:=nil;
          resulttype:=voidtype;
 
-         { right is the statement itself calln assignn or a complex one }
-         resulttypepass(right);
+         { left is the statement itself calln assignn or a complex one }
+         resulttypepass(left);
          if (not (cs_extsyntax in aktmoduleswitches)) and
-            assigned(right.resulttype.def) and
-            not((right.nodetype=calln) and
+            assigned(left.resulttype.def) and
+            not((left.nodetype=calln) and
                 { don't complain when funcretrefnode is set, because then the
                   value is already used. And also not for constructors }
-                (assigned(tcallnode(right).funcretrefnode) or
-                 (tcallnode(right).procdefinition.proctypeoption=potype_constructor))) and
-            not(is_void(right.resulttype.def)) then
+                (assigned(tcallnode(left).funcretrefnode) or
+                 (tcallnode(left).procdefinition.proctypeoption=potype_constructor))) and
+            not(is_void(left.resulttype.def)) then
            CGMessage(cg_e_illegal_expression);
          if codegenerror then
            exit;
 
-         { left is the next in the list }
-         resulttypepass(left);
+         { right is the next statement in the list }
+         resulttypepass(right);
          if codegenerror then
            exit;
       end;
@@ -285,28 +285,20 @@ implementation
          result:=nil;
          { no temps over several statements }
          rg.cleartempgen;
-         { right is the statement itself calln assignn or a complex one }
-         firstpass(right);
+         { left is the statement itself calln assignn or a complex one }
+         firstpass(left);
          if codegenerror then
            exit;
-         location.loc:=right.location.loc;
-         registers32:=right.registers32;
-         registersfpu:=right.registersfpu;
+         location.loc:=left.location.loc;
+         registers32:=left.registers32;
+         registersfpu:=left.registersfpu;
 {$ifdef SUPPORT_MMX}
-         registersmmx:=right.registersmmx;
+         registersmmx:=left.registersmmx;
 {$endif SUPPORT_MMX}
-         { left is the next in the list }
-         firstpass(left);
+         { right is the next in the list }
+         firstpass(right);
          if codegenerror then
            exit;
-         if right.registers32>registers32 then
-           registers32:=right.registers32;
-         if right.registersfpu>registersfpu then
-           registersfpu:=right.registersfpu;
-{$ifdef SUPPORT_MMX}
-         if right.registersmmx>registersmmx then
-           registersmmx:=right.registersmmx;
-{$endif}
       end;
 
 {$ifdef extdebug}
@@ -319,11 +311,11 @@ implementation
          writeln(',');
          { write the statement }
          writenodeindention:=writenodeindention+'    ';
-         writenode(right);
+         writenode(left);
          writeln(')');
          delete(writenodeindention,1,4);
          { go on with the next statement }
-         writenode(left);
+         writenode(right);
       end;
 {$endif}
 
@@ -347,26 +339,26 @@ implementation
          hp:=tstatementnode(left);
          while assigned(hp) do
            begin
-              if assigned(hp.right) then
+              if assigned(hp.left) then
                 begin
                    codegenerror:=false;
-                   resulttypepass(hp.right);
+                   resulttypepass(hp.left);
                    if (not (cs_extsyntax in aktmoduleswitches)) and
-                      assigned(hp.right.resulttype.def) and
-                      not((hp.right.nodetype=calln) and
+                      assigned(hp.left.resulttype.def) and
+                      not((hp.left.nodetype=calln) and
                           { don't complain when funcretrefnode is set, because then the
                             value is already used. And also not for constructors }
-                          (assigned(tcallnode(hp.right).funcretrefnode) or
-                           (tcallnode(hp.right).procdefinition.proctypeoption=potype_constructor))) and
-                      not(is_void(hp.right.resulttype.def)) then
-                     CGMessagePos(hp.right.fileinfo,cg_e_illegal_expression);
+                          (assigned(tcallnode(hp.left).funcretrefnode) or
+                           (tcallnode(hp.left).procdefinition.proctypeoption=potype_constructor))) and
+                      not(is_void(hp.left.resulttype.def)) then
+                     CGMessagePos(hp.left.fileinfo,cg_e_illegal_expression);
                    { the resulttype of the block is the last type that is
                      returned. Normally this is a voidtype. But when the
                      compiler inserts a block of multiple statements then the
                      last entry can return a value }
-                   resulttype:=hp.right.resulttype;
+                   resulttype:=hp.left.resulttype;
                 end;
-              hp:=tstatementnode(hp.left);
+              hp:=tstatementnode(hp.right);
            end;
       end;
 
@@ -390,51 +382,51 @@ implementation
                    if {ret_in_acc(aktprocdef.rettype.def) and }
                       (is_ordinal(aktprocdef.rettype.def) or
                        is_smallset(aktprocdef.rettype.def)) and
-                      assigned(hp.left) and
-                      assigned(tstatementnode(hp.left).right) and
-                      (tstatementnode(hp.left).right.nodetype=exitn) and
-                      (hp.right.nodetype=assignn) and
+                      assigned(hp.right) and
+                      assigned(tstatementnode(hp.right).left) and
+                      (tstatementnode(hp.right).left.nodetype=exitn) and
+                      (hp.left.nodetype=assignn) and
                       { !!!! this tbinarynode should be tassignmentnode }
-                      (tbinarynode(hp.right).left.nodetype=funcretn) then
+                      (tbinarynode(hp.left).left.nodetype=funcretn) then
                       begin
-                         if assigned(texitnode(tstatementnode(hp.left).right).left) then
+                         if assigned(texitnode(tstatementnode(hp.right).left).left) then
                            CGMessage(cg_n_inefficient_code)
                          else
                            begin
-                              texitnode(tstatementnode(hp.left).right).left:=tassignmentnode(hp.right).right;
-                              tassignmentnode(hp.right).right:=nil;
-                              hp.right.free;
-                              hp.right:=nil;
+                              texitnode(tstatementnode(hp.right).left).left:=tassignmentnode(hp.left).right;
+                              tassignmentnode(hp.left).right:=nil;
+                              hp.left.free;
+                              hp.left:=nil;
                            end;
                       end
                    { warning if unreachable code occurs and elimate this }
-                   else if (hp.right.nodetype in
+                   else if (hp.left.nodetype in
                      [exitn,breakn,continuen,goton]) and
                      { statement node (JM) }
-                     assigned(hp.left) and
+                     assigned(hp.right) and
                      { kind of statement! (JM) }
-                     assigned(tstatementnode(hp.left).right) and
-                     (tstatementnode(hp.left).right.nodetype<>labeln) then
+                     assigned(tstatementnode(hp.right).left) and
+                     (tstatementnode(hp.right).left.nodetype<>labeln) then
                      begin
                         { use correct line number }
-                        aktfilepos:=hp.left.fileinfo;
-                        hp.left.free;
-                        hp.left:=nil;
+                        aktfilepos:=hp.right.fileinfo;
+                        hp.right.free;
+                        hp.right:=nil;
                         CGMessage(cg_w_unreachable_code);
                         { old lines }
-                        aktfilepos:=hp.right.fileinfo;
+                        aktfilepos:=hp.left.fileinfo;
                      end;
                 end;
-              if assigned(hp.right) then
+              if assigned(hp.left) then
                 begin
                    rg.cleartempgen;
                    codegenerror:=false;
-                   firstpass(hp.right);
+                   firstpass(hp.left);
 
-                   hp.registers32:=hp.right.registers32;
-                   hp.registersfpu:=hp.right.registersfpu;
+                   hp.registers32:=hp.left.registers32;
+                   hp.registersfpu:=hp.left.registersfpu;
 {$ifdef SUPPORT_MMX}
-                   hp.registersmmx:=hp.right.registersmmx;
+                   hp.registersmmx:=hp.left.registersmmx;
 {$endif SUPPORT_MMX}
                 end
               else
@@ -450,7 +442,7 @@ implementation
 {$endif}
               location.loc:=hp.location.loc;
               inc(count);
-              hp:=tstatementnode(hp.left);
+              hp:=tstatementnode(hp.right);
            end;
       end;
 
@@ -464,9 +456,9 @@ implementation
         hp:=Tstatementnode(left);
         while assigned(hp) do
             begin
-                if hp.right.track_state_pass(exec_known) then
+                if hp.left.track_state_pass(exec_known) then
                     track_state_pass:=true;
-                hp:=Tstatementnode(hp.left);
+                hp:=Tstatementnode(hp.right);
             end;
       end;
 {$endif state_tracking}
@@ -592,6 +584,11 @@ implementation
         fillchar(n.tempinfo^,sizeof(n.tempinfo^),0);
         n.tempinfo^.restype := tempinfo^.restype;
 
+        { when the tempinfo has already a hookoncopy then it is not
+          reset by a tempdeletenode }
+        if assigned(tempinfo^.hookoncopy) then
+          internalerror(200211262);
+
         { signal the temprefs that the temp they point to has been copied, }
         { so that if the refs get copied as well, they can hook themselves }
         { to the copy of the temp                                          }
@@ -723,6 +720,8 @@ implementation
           begin
             { hook the tempdeletenode to the copied temp }
             n.tempinfo := tempinfo^.hookoncopy;
+            { the temp shall not be used, reset hookoncopy }
+            tempinfo^.hookoncopy:=nil;
           end
         else
           { if the temp we refer to hasn't been copied, we have a }
@@ -767,7 +766,14 @@ begin
 end.
 {
   $Log$
-  Revision 1.37  2002-11-25 17:43:17  peter
+  Revision 1.38  2002-11-27 02:37:12  peter
+    * case statement inlining added
+    * fixed inlining of write()
+    * switched statementnode left and right parts so the statements are
+      processed in the correct order when getcopy is used. This is
+      required for tempnodes
+
+  Revision 1.37  2002/11/25 17:43:17  peter
     * splitted defbase in defutil,symutil,defcmp
     * merged isconvertable and is_equal into compare_defs(_ext)
     * made operator search faster by walking the list only once

+ 12 - 5
compiler/ncgbas.pas

@@ -90,14 +90,14 @@ interface
          hp:=self;
          while assigned(hp) do
           begin
-            if assigned(tstatementnode(hp).right) then
+            if assigned(tstatementnode(hp).left) then
              begin
                rg.cleartempgen;
-               secondpass(tstatementnode(hp).right);
+               secondpass(tstatementnode(hp).left);
                { Compiler inserted blocks can return values }
-               location_copy(location,tstatementnode(hp).right.location);
+               location_copy(location,tstatementnode(hp).left.location);
              end;
-            hp:=tstatementnode(hp).left;
+            hp:=tstatementnode(hp).right;
           end;
       end;
 
@@ -288,7 +288,14 @@ begin
 end.
 {
   $Log$
-  Revision 1.26  2002-11-17 16:31:56  carl
+  Revision 1.27  2002-11-27 02:37:13  peter
+    * case statement inlining added
+    * fixed inlining of write()
+    * switched statementnode left and right parts so the statements are
+      processed in the correct order when getcopy is used. This is
+      required for tempnodes
+
+  Revision 1.26  2002/11/17 16:31:56  carl
     * memory optimization (3-4%) : cleanup of tai fields,
        cleanup of tdef and tsym fields.
     * make it work for m68k

+ 60 - 6
compiler/ncgset.pas

@@ -90,7 +90,7 @@ implementation
       symconst,symdef,defutil,
       paramgr,
       pass_2,
-      ncon,
+      nbas,ncon,nflw,
       tgobj,ncgutil,regvars,rgobj,cpuinfo;
 
 
@@ -837,6 +837,29 @@ implementation
       end;
 
 
+    procedure ReLabel(var p:tasmsymbol);
+      begin
+        if p.defbind = AB_LOCAL then
+         begin
+           if not assigned(p.altsymbol) then
+             objectlibrary.GenerateAltSymbol(p);
+           p:=p.altsymbol;
+           p.increfs;
+         end;
+      end;
+
+
+    procedure relabelcaserecord(p : pcaserecord);
+      begin
+         Relabel(p^.statement);
+         Relabel(p^._at);
+         if assigned(p^.greater) then
+           relabelcaserecord(p^.greater);
+         if assigned(p^.less) then
+           relabelcaserecord(p^.less);
+      end;
+
+
     procedure tcgcasenode.pass_2;
       var
          lv,hv,
@@ -847,8 +870,16 @@ implementation
          isjump : boolean;
          max_dist,
          dist : cardinal;
-         hp : tnode;
+         hp : tstatementnode;
       begin
+         { Relabel for inlining? }
+         if inlining_procedure and
+            assigned(nodes) then
+          begin
+            objectlibrary.CreateUsedAsmSymbolList;
+            relabelcaserecord(nodes);
+          end;
+
          objectlibrary.getlabel(endlabel);
          objectlibrary.getlabel(elselabel);
          with_sign:=is_signed(left.resulttype.def);
@@ -983,16 +1014,23 @@ implementation
          rg.ungetregister(exprasmlist,hregister);
 
          { now generate the instructions }
-         hp:=right;
+         hp:=tstatementnode(right);
          while assigned(hp) do
            begin
               rg.cleartempgen;
-              secondpass(tbinarynode(hp).right);
+              { relabel when inlining }
+              if inlining_procedure then
+                begin
+                  if hp.left.nodetype<>labeln then
+                    internalerror(200211261);
+                  Relabel(tlabelnode(hp.left).labelnr);
+                end;
+              secondpass(hp.left);
               { don't come back to case line }
               aktfilepos:=exprasmList.getlasttaifilepos^;
               load_all_regvars(exprasmlist);
               cg.a_jmp_always(exprasmlist,endlabel);
-              hp:=tbinarynode(hp).left;
+              hp:=tstatementnode(hp.right);
            end;
          cg.a_label(exprasmlist,elselabel);
          { ...and the else block }
@@ -1003,6 +1041,15 @@ implementation
               load_all_regvars(exprasmlist);
            end;
          cg.a_label(exprasmlist,endlabel);
+
+         { Remove relabels for inlining }
+         if inlining_procedure and
+            assigned(nodes) then
+          begin
+             { restore used symbols }
+             objectlibrary.UsedAsmSymbolListResetAltSym;
+             objectlibrary.DestroyUsedAsmSymbolList;
+          end;
       end;
 
 
@@ -1015,7 +1062,14 @@ begin
 end.
 {
   $Log$
-  Revision 1.23  2002-11-25 17:43:18  peter
+  Revision 1.24  2002-11-27 02:37:13  peter
+    * case statement inlining added
+    * fixed inlining of write()
+    * switched statementnode left and right parts so the statements are
+      processed in the correct order when getcopy is used. This is
+      required for tempnodes
+
+  Revision 1.23  2002/11/25 17:43:18  peter
     * splitted defbase in defutil,symutil,defcmp
     * merged isconvertable and is_equal into compare_defs(_ext)
     * made operator search faster by walking the list only once

+ 19 - 19
compiler/ninl.pas

@@ -424,7 +424,7 @@ implementation
                 addstatement(newstatement,
                   cassignmentnode.create(ctemprefnode.create(filetemp),
                     caddrnode.create(filepara.left)));
-                resulttypepass(newstatement.right);
+                resulttypepass(newstatement.left);
                 { create a new fileparameter as follows: file_type(temp^)    }
                 { (so that we pass the value and not the address of the temp }
                 { to the read/write routine)                                 }
@@ -899,8 +899,8 @@ implementation
 
         { create the blocknode which will hold the generated statements + }
         { an initial dummy statement                                      }
-        newstatement := cstatementnode.create(nil,cnothingnode.create);
-        newblock := cblocknode.create(newstatement);
+
+        newblock:=internalstatements(newstatement);
 
         { do we need a temp for code? Yes, if no code specified, or if  }
         { code is not a 32bit parameter (we already checked whether the }
@@ -909,8 +909,7 @@ implementation
            (torddef(codepara.resulttype.def).typ in [u8bit,u16bit,s8bit,s16bit]) then
           begin
             tempcode := ctempcreatenode.create(s32bittype,4,true);
-            newstatement.left := cstatementnode.create(nil,tempcode);
-            newstatement := tstatementnode(newstatement.left);
+            addstatement(newstatement,tempcode);
             { set the resulttype of the temp (needed to be able to get }
             { the resulttype of the tempref used in the new code para) }
             resulttypepass(tnode(tempcode));
@@ -970,7 +969,8 @@ implementation
         { the shortstring-longint val routine by default                   }
         if (sourcepara.resulttype.def.deftype = stringdef) then
           procname := procname + tstringdef(sourcepara.resulttype.def).stringtypname
-        else procname := procname + 'shortstr';
+        else
+          procname := procname + 'shortstr';
 
         { set up the correct parameters for the call: the code para... }
         newparas := codepara;
@@ -985,9 +985,8 @@ implementation
         { create the call and assign the result to dest  }
         { (val helpers are functions)                    }
         { the assignment will take care of rangechecking }
-        newstatement.left := cstatementnode.create(nil,cassignmentnode.create(
+        addstatement(newstatement,cassignmentnode.create(
           destpara.left,ccallnode.createintern(procname,newparas)));
-        newstatement := tstatementnode(newstatement.left);
 
         { dispose of the enclosing paranode of the destination }
         destpara.left := nil;
@@ -997,19 +996,13 @@ implementation
         { check if we used a temp for code and whether we have to store }
         { it to the real code parameter                                 }
         if assigned(orgcode) then
-          begin
-            newstatement.left := cstatementnode.create(nil,cassignmentnode.create(
-              orgcode,ctemprefnode.create(tempcode)));
-            newstatement := tstatementnode(newstatement.left);
-          end;
+          addstatement(newstatement,cassignmentnode.create(
+              orgcode,
+              ctemprefnode.create(tempcode)));
 
         { release the temp if we allocated one }
         if assigned(tempcode) then
-          begin
-            newstatement.left := cstatementnode.create(nil,
-              ctempdeletenode.create(tempcode));
-            newstatement := tstatementnode(newstatement.left);
-          end;
+          addstatement(newstatement,ctempdeletenode.create(tempcode));
 
         { free the errornode }
         result.free;
@@ -2408,7 +2401,14 @@ begin
 end.
 {
   $Log$
-  Revision 1.98  2002-11-25 17:43:19  peter
+  Revision 1.99  2002-11-27 02:37:13  peter
+    * case statement inlining added
+    * fixed inlining of write()
+    * switched statementnode left and right parts so the statements are
+      processed in the correct order when getcopy is used. This is
+      required for tempnodes
+
+  Revision 1.98  2002/11/25 17:43:19  peter
     * splitted defbase in defutil,symutil,defcmp
     * merged isconvertable and is_equal into compare_defs(_ext)
     * made operator search faster by walking the list only once

+ 23 - 16
compiler/nset.pas

@@ -118,7 +118,7 @@ implementation
       verbose,
       symconst,symdef,symsym,defutil,defcmp,
       htypechk,pass_1,
-      ncnv,ncon,cpubase,nld,rgobj,cgbase;
+      nbas,ncnv,ncon,cpubase,nld,rgobj,cgbase;
 
     function gencasenode(l,r : tnode;nodes : pcaserecord) : tnode;
 
@@ -265,17 +265,17 @@ implementation
            elements.with the in operator.
          }
          if  (
-               (left.resulttype.def.deftype = orddef) and not 
+               (left.resulttype.def.deftype = orddef) and not
                (torddef(left.resulttype.def).typ in [s8bit,u8bit,uchar,bool8bit])
-             ) 
+             )
             or
              (
-               (left.resulttype.def.deftype = enumdef) 
+               (left.resulttype.def.deftype = enumdef)
               and (tenumdef(left.resulttype.def).size <> 1)
              )
           then
              Message(type_h_in_range_check);
- 
+
          { type conversion/check }
          if assigned(tsetdef(right.resulttype.def).elementtype.def) then
            begin
@@ -587,7 +587,7 @@ implementation
     function tcasenode.pass_1 : tnode;
       var
          old_t_times : longint;
-         hp : tbinarynode;
+         hp : tstatementnode;
       begin
          result:=nil;
          { evalutes the case expression }
@@ -613,23 +613,23 @@ implementation
                 rg.t_times:=1;
            end;
          { first case }
-         hp:=tbinarynode(right);
+         hp:=tstatementnode(right);
          while assigned(hp) do
            begin
               rg.cleartempgen;
-              firstpass(hp.right);
+              firstpass(hp.left);
 
               { searchs max registers }
-              if hp.right.registers32>registers32 then
-                registers32:=hp.right.registers32;
-              if hp.right.registersfpu>registersfpu then
-                registersfpu:=hp.right.registersfpu;
+              if hp.left.registers32>registers32 then
+                registers32:=hp.left.registers32;
+              if hp.left.registersfpu>registersfpu then
+                registersfpu:=hp.left.registersfpu;
 {$ifdef SUPPORT_MMX}
-              if hp.right.registersmmx>registersmmx then
-                registersmmx:=hp.right.registersmmx;
+              if hp.left.registersmmx>registersmmx then
+                registersmmx:=hp.left.registersmmx;
 {$endif SUPPORT_MMX}
 
-              hp:=tbinarynode(hp.left);
+              hp:=tstatementnode(hp.right);
            end;
 
          { may be handle else tree }
@@ -709,7 +709,14 @@ begin
 end.
 {
   $Log$
-  Revision 1.36  2002-11-26 21:52:38  carl
+  Revision 1.37  2002-11-27 02:37:14  peter
+    * case statement inlining added
+    * fixed inlining of write()
+    * switched statementnode left and right parts so the statements are
+      processed in the correct order when getcopy is used. This is
+      required for tempnodes
+
+  Revision 1.36  2002/11/26 21:52:38  carl
     + hint for in operator with non byte sized operand
 
   Revision 1.35  2002/11/25 17:43:21  peter

+ 21 - 14
compiler/pstatmnt.pas

@@ -105,13 +105,13 @@ implementation
            begin
               if first=nil then
                 begin
-                   last:=cstatementnode.create(nil,statement);
+                   last:=cstatementnode.create(statement,nil);
                    first:=last;
                 end
               else
                 begin
-                   last.left:=cstatementnode.create(nil,statement);
-                   last:=tstatementnode(last.left);
+                   last.right:=cstatementnode.create(statement,nil);
+                   last:=tstatementnode(last.right);
                 end;
               if not try_to_consume(_SEMICOLON) then
                 break;
@@ -274,7 +274,7 @@ implementation
            p:=clabelnode.createcase(aktcaselabel,statement);
 
            { concats instruction }
-           instruc:=cstatementnode.create(instruc,p);
+           instruc:=cstatementnode.create(p,instruc);
 
            if not((token=_ELSE) or (token=_OTHERWISE) or (token=_END)) then
              consume(_SEMICOLON);
@@ -315,13 +315,13 @@ implementation
            begin
               if first=nil then
                 begin
-                   last:=cstatementnode.create(nil,statement);
+                   last:=cstatementnode.create(statement,nil);
                    first:=last;
                 end
               else
                 begin
-                   tstatementnode(last).left:=cstatementnode.create(nil,statement);
-                   last:=tstatementnode(last).left;
+                   tstatementnode(last).right:=cstatementnode.create(statement,nil);
+                   last:=tstatementnode(last).right;
                 end;
               if not try_to_consume(_SEMICOLON) then
                 break;
@@ -541,13 +541,13 @@ implementation
            begin
               if first=nil then
                 begin
-                   last:=cstatementnode.create(nil,statement);
+                   last:=cstatementnode.create(statement,nil);
                    first:=last;
                 end
               else
                 begin
-                   tstatementnode(last).left:=cstatementnode.create(nil,statement);
-                   last:=tstatementnode(last).left;
+                   tstatementnode(last).right:=cstatementnode.create(statement,nil);
+                   last:=tstatementnode(last).right;
                 end;
               if not try_to_consume(_SEMICOLON) then
                 break;
@@ -961,13 +961,13 @@ implementation
            begin
               if first=nil then
                 begin
-                   last:=cstatementnode.create(nil,statement);
+                   last:=cstatementnode.create(statement,nil);
                    first:=last;
                 end
               else
                 begin
-                   tstatementnode(last).left:=cstatementnode.create(nil,statement);
-                   last:=tstatementnode(last).left;
+                   tstatementnode(last).right:=cstatementnode.create(statement,nil);
+                   last:=tstatementnode(last).right;
                 end;
               if (token in [_END,_FINALIZATION]) then
                 break
@@ -1147,7 +1147,14 @@ implementation
 end.
 {
   $Log$
-  Revision 1.80  2002-11-25 17:43:22  peter
+  Revision 1.81  2002-11-27 02:37:14  peter
+    * case statement inlining added
+    * fixed inlining of write()
+    * switched statementnode left and right parts so the statements are
+      processed in the correct order when getcopy is used. This is
+      required for tempnodes
+
+  Revision 1.80  2002/11/25 17:43:22  peter
     * splitted defbase in defutil,symutil,defcmp
     * merged isconvertable and is_equal into compare_defs(_ext)
     * made operator search faster by walking the list only once