Ver código fonte

* 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 23 anos atrás
pai
commit
34e8266af4
6 arquivos alterados com 209 adições e 128 exclusões
  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