Metropoli BBS
VIEWER: hcodegen.pas MODE: TEXT (CP437)
{****************************************************************************

                       Copyright (c) 1996 by Florian Klämpfl

 ****************************************************************************}

unit hcodegen;

  interface

     uses
        cobjects,systems,globals,tree,asmgen,symtable,tempad,types,strings,
        i386;

    type
       tprocinfo = record
          { aktuelle Klasse }
          _class : pclassdef;
          { Returntyp }
          retdef : pdef;
          { true, falls Eceptions behandelt werden sollen }
          exceptions : boolean;
          { true, falls das Unterprogramm exportiert werden soll (OS/2) }
          exported : boolean;
          { Framepointeroffset }
          framepointer : longint;
          { Self-Pointer rel. zu EBP }
          ESI_offset : longint;
          { Resultatwertoffset }
          retoffset : longint;
          { Parameteroffset }
          call_offset : longint;
          { Adresse für die einzutragende VMT }
          { (Verwendung nur in Kon- und Destrktoren) }
          vmt_table : longint;

          { it's true, if the procedure uses asm }
          uses_asm : boolean;

          { true, if the procedure is exported by an unit }
          globalsymbol : boolean;
       end;

    var
       { Info über das momentan geparste Unterprogramm }
       procinfo : tprocinfo;

       { Die Nummer der Label die bei BREAK bzw CONTINUE }
       { angesprungen werden sollen }
       aktbreaklabel,aktcontinuelabel : longint;

       { truelabel wird angesprungen, wenn ein Ausdruck true ist, falselabel }
       { entsprechend                                                        }
       truelabel,falselabel : longint;

       { Nr des Labels welches zum Verlassen eines Unterprogramm }
       { angesprungen wird                                       }
       aktexitlabel : longint;

       { Exitlabel, welches angesprungen werden muß, um nur den  }
       { Stack aufzuräumen                                       }
       aktexit2label : longint;

       { Nummer des Labels zu dem bei einer Exception zurück gekehrt }
       { werden soll                                                 }
       aktexceptlabel : longint;

       { Der Code der beim Eintritt in ein Unterprogramm abgearbeitet }
       { wird                                                         }
       aktentrycode : tasmlist;

       { Der Code der beim Austritt aus einem Unterprogramm }
       { abgearbeitet wird                                  }
       aktexitcode : tasmlist;

       { Der Code der beim Austritt aus einem Unterprogramm }
       { mit einer Exception abgearbeitet wird              }
       aktexceptcode : tasmlist;

       { Der Code der aktuellen Procedure }
       aktproccode : tasmlist;

       { die asmlist für das Datensegment ist in asmgen deklariert, }
       { da sie von symtable gebraucht wird                         }

       { Assemblerliste in der der Code fuer den aktuellen Ausdruck eingefuegt wird }
       exprasmlist : tasmlist;

       { Assemblerliste mit Debuggerinfos }
       debuginfos : tasmlist;

       { Boolean, wenn eine loadn kein Assembler erzeugt hat }
       simple_loadn : boolean;

       { enthält die geschätzte Durchlaufanzahl*100 für den }
       { momentan bearbeiteten Baum                         }
       t_times : longint;

       { true, if an error while code generation occurs }
       codegenerror : boolean;

    { some support routines for the case instruction }

    { counts the labels }
    function case_count_labels(wurzel : pcaserecord) : longint;

    { searches the highest label }
    function case_get_max(wurzel : pcaserecord) : longint;

    { searches the lowest label }
    function case_get_min(wurzel : pcaserecord) : longint;

  implementation

    function case_count_labels(wurzel : pcaserecord) : longint;

      var
         _l : longint;

      procedure count(p : pcaserecord);

        begin
           inc(_l);
           if assigned(p^.less) then
             count(p^.less);
           if assigned(p^.greater) then
             count(p^.greater);
        end;

      begin
         _l:=0;
         count(wurzel);
         case_count_labels:=_l;
      end;

    function case_get_max(wurzel : pcaserecord) : longint;

      var
         hp : pcaserecord;

      begin
         hp:=wurzel;
         while assigned(hp^.greater) do
           hp:=hp^.greater;
         case_get_max:=hp^.high;
      end;

    function case_get_min(wurzel : pcaserecord) : longint;

      var
         hp : pcaserecord;

      begin
         hp:=wurzel;
         while assigned(hp^.less) do
           hp:=hp^.less;
         case_get_min:=hp^.low;
      end;

end.

[ RETURN TO DIRECTORY ]