home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 02 / scancode.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-02-12  |  32.0 KB  |  1,126 lines

  1. UNIT ScanCode;
  2.  
  3. INTERFACE
  4.  
  5. USES Global;
  6.  
  7.  
  8. PROCEDURE LoadErrorText;
  9. PROCEDURE WriteErrorText (No: INTEGER);
  10. PROCEDURE WriteErrorLine;
  11. PROCEDURE Error (ErrorNo: INTEGER);
  12. PROCEDURE DoEoLn;
  13. PROCEDURE EnterLine (c: CHAR);
  14. PROCEDURE GetSymbol;
  15. PROCEDURE InsertId (BezPtr: KonstP);
  16. PROCEDURE FindRecFields (BezPtr: KonstP; VAR BezPtr1: KonstP);
  17. PROCEDURE FindeBez (IdKind: BezMenge; VAR BezPtr: KonstP);
  18. PROCEDURE GetBounds (St: StP; VAR Minimum, Maximum: INTEGER);
  19. PROCEDURE GLab (VAR NxtLab: INTEGER);
  20. PROCEDURE Recover (ESets: Symbolmenge);
  21. PROCEDURE GConstant (ESets: Symbolmenge; VAR St: StP; VAR ParKonst: Value);
  22. FUNCTION HasEqualBounds (st1, st2: StP): BOOLEAN;
  23. FUNCTION IsCompatible (st1, st2: StP): BOOLEAN;
  24. FUNCTION Strng (St: StP): BOOLEAN;
  25. FUNCTION IsFileOfFile (SavSp: StP): BOOLEAN;
  26. PROCEDURE MovStk (i: INTEGER; VAR TopNew, StkMax: INTEGER);
  27. PROCEDURE PutIC;
  28. PROCEDURE GenDBG (VAR Name: ALPHA);
  29. PROCEDURE GenPopDBG;
  30. PROCEDURE G0 (Operator: OpRange; VAR TopNew, StkMax: INTEGER);
  31. PROCEDURE G1 (Operator: OpRange; Param2: INTEGER;
  32.               VAR TopNew, StkMax: INTEGER; VAR KonstPtr: CstPtrArray);
  33. PROCEDURE G2 (Operator: OpRange; Param1, Param2: INTEGER;
  34.               VAR TopNew, StkMax: INTEGER; VAR KonstPtr: CstPtrArray);
  35. PROCEDURE GenTypIndicator (St: StP);
  36. PROCEDURE G0T (Operator: OpRange; St: StP; VAR TopNew, StkMax: INTEGER);
  37. PROCEDURE G1T (Operator: OpRange; Param2: INTEGER; St: StP;
  38.                VAR TopNew, StkMax: INTEGER);
  39. PROCEDURE G2T (Operator: OpRange; Param1, Param2: INTEGER;
  40.                St: StP; VAR TopNew, StkMax: INTEGER);
  41. PROCEDURE PushContents (VAR TopNew, StkMax: INTEGER;
  42.                         VAR KonstPtr: CstPtrArray; VAR KonstPtrIndex: INTEGER);
  43. PROCEDURE Store (VAR StoreAttr: Attribut; VAR TopNew, StkMax: INTEGER);
  44. PROCEDURE PushAddress (VAR TopNew, StkMax: INTEGER;
  45.                        VAR KonstPtr: CstPtrArray; VAR KonstPtrIndex: INTEGER);
  46. PROCEDURE GJump (JumpTo: INTEGER; VAR TopNew, StkMax: INTEGER;
  47.                  VAR KonstPtr: CstPtrArray; VAR KonstPtrIndex: INTEGER);
  48. PROCEDURE GCase (Operator: OpRange; Param2: INTEGER;
  49.                  VAR TopNew, StkMax: INTEGER);
  50. PROCEDURE GProcCall (Operator: OpRange;
  51.                      Param1, Param2: INTEGER; VAR TopNew, StkMax: INTEGER);
  52. PROCEDURE CheckBounds (St: StP; VAR TopNew, StkMax: INTEGER);
  53. PROCEDURE PushLabel (LabName: INTEGER);
  54.  
  55.  
  56. IMPLEMENTATION
  57.  
  58. PROCEDURE LoadErrorText;
  59.  
  60. VAR
  61.   f: TEXT;
  62.   s: ErrorString;
  63.   No: INTEGER;
  64.  
  65. BEGIN
  66.   (* RESET(F,'errors.txt');  *)
  67.   Assign(f,'errors.txt');
  68.   ReSet(f);
  69.   WasLoadErrorText := TRUE;
  70.   MaxErrors := 0;
  71.   WHILE NOT Eof(f) DO BEGIN
  72.     MaxErrors := MaxErrors+1;
  73.     ReadLn(f,No,s);
  74.     WITH ErrorTable[MaxErrors] DO BEGIN
  75.       ErrorNo := No;  ErrorText := s;
  76.     END;
  77.   END
  78. END;
  79.  
  80.  
  81. PROCEDURE WriteErrorText (No: INTEGER);
  82.  
  83.  
  84.   PROCEDURE SearchNo (PassFuncProc, ub:INTEGER);
  85.  
  86.   VAR mid: INTEGER;
  87.  
  88.   BEGIN
  89.     IF PassFuncProc <> ub THEN BEGIN
  90.       mid := (PassFuncProc+ub) DIV 2;
  91.       WITH ErrorTable[mid] DO
  92.         IF No < ErrorNo THEN SearchNo(PassFuncProc,mid)
  93.         ELSE IF No > ErrorNo THEN SearchNo(mid,ub)
  94.         ELSE WriteLn(ErrorText);
  95.     END
  96.     ELSE WriteLn('>> unbekannter Fehler <<');
  97.   END;
  98.  
  99. BEGIN
  100.   SearchNo(1,MaxErrors)
  101. END;
  102.  
  103.  
  104. PROCEDURE WriteErrorLine;
  105.  
  106. VAR i: INTEGER;
  107.  
  108. BEGIN
  109.   FOR i := 1 TO LinePos-1 DO Write(Line[i]);
  110.   WriteLn;
  111. END;
  112.  
  113.  
  114. PROCEDURE Error (ErrorNo: INTEGER);
  115.  
  116. BEGIN
  117.   IF ErrorIndex >= 9 THEN BEGIN
  118.     ErrorList[10].No := 255;  ErrorIndex := 10
  119.   END
  120.   ELSE BEGIN
  121.     ErrorIndex := ErrorIndex+1;
  122.     ErrorList[ErrorIndex].No := ErrorNo
  123.   END;
  124.   ErrorList[ErrorIndex].Pos := SymbStart;
  125. END;
  126.  
  127.  
  128. PROCEDURE DoEoLn;
  129.  
  130. VAR LastPos, ActErrorPos, ActErrorNo, k: INTEGER;
  131.  
  132. BEGIN
  133.   IF ErrorIndex > 0 THEN BEGIN
  134.     WriteLn;  WriteLn;  WriteLn('Zeile: ',LineCount);
  135.     WriteErrorLine;
  136.     LastPos := 0;
  137.     FOR k := 1 TO ErrorIndex DO BEGIN
  138.       WITH ErrorList[k] DO BEGIN
  139.         ActErrorPos := Pos;  ActErrorNo := No
  140.       END;
  141.       IF ActErrorPos <> LastPos THEN BEGIN
  142.         Write('^':ActErrorPos,ActErrorNo:4);
  143.         NoOfErrors := NoOfErrors+1;
  144.         IF IsErrorText THEN BEGIN
  145.           IF NOT WasLoadErrorText THEN LoadErrorText;
  146.           WriteErrorText(ActErrorNo);
  147.         END;
  148.         WriteLn;
  149.       END;
  150.     END; (* FOR *)
  151.     WriteLn;  ErrorIndex := 0;
  152.   END;
  153.   IF LineCount MOD 20 = 0 THEN BEGIN
  154.     WriteLn;  Write('<',LineCount+1:5,'>');
  155.   END;
  156.   LineCount := LineCount+1;  Write('.');
  157.   IthChar := 0;
  158. END;
  159.  
  160.  
  161. PROCEDURE EnterLine (c: CHAR);
  162.  
  163. BEGIN
  164.   Line[LinePos] := c;  LinePos := LinePos+1
  165. END;
  166.  
  167.  
  168. PROCEDURE GetSymbol;
  169.  
  170. LABEL 1;
  171.  
  172. VAR
  173.   i,k: INTEGER;
  174.   Ziffer: PACKED ARRAY[1..StringLength] OF CHAR;
  175.   Strng : PACKED ARRAY[1..StringLength] OF CHAR;
  176.   SavKonstPtr: KonstPointer;
  177.   Stop: BOOLEAN;
  178.   Wert: Long_Integer;
  179.  
  180.  
  181.   PROCEDURE GetChar;
  182.  
  183.   BEGIN
  184.     IF EoL THEN BEGIN
  185.       DoEoLn;  LinePos := 1;
  186.     END;
  187.     IF NOT EoF(Source) THEN BEGIN
  188.       EoL := EoLn(Source);  Read(Source,Zeichen);
  189.       IF Zeichen < ' ' THEN Zeichen := ' ';
  190.       EnterLine(Zeichen);  IthChar := IthChar+1;
  191.     END
  192.     ELSE BEGIN
  193.       WriteLn(' *** Dateiende erreicht');
  194.       Stop := FALSE
  195.     END;
  196.   END;
  197.  
  198.  
  199.   PROCEDURE CompilerOptionen;
  200.  
  201.   BEGIN
  202.     REPEAT
  203.       GetChar;
  204.       IF (Zeichen <> '*') AND (Zeichen <> '}') THEN BEGIN
  205.         CASE UpCase(Zeichen) OF
  206.           'D' : BEGIN
  207.                   GetChar;  Debug := Zeichen = '+'
  208.                 END;
  209.           'C' : BEGIN
  210.                   GetChar;  IsPrtCode := Zeichen = '+'
  211.                 END;
  212.           'E' : BEGIN
  213.                   GetChar;  IsErrorText := Zeichen = '+'
  214.                 END;
  215.         END;
  216.         GetChar;
  217.       END;
  218.     UNTIL Zeichen <> ',';
  219.   END;
  220.  
  221.  
  222.   PROCEDURE SaveConstant (i: INTEGER);
  223.  
  224.   VAR k: INTEGER;
  225.  
  226.   BEGIN
  227.     IF i > MaxZiffer THEN BEGIN
  228.       Error(203);  LastConstVal.GanzeZahl := 0
  229.     END
  230.     ELSE
  231.       WITH LastConstVal DO BEGIN
  232.         Wert := 0;
  233.         FOR k := 1 TO i DO
  234.           Wert := Wert * 10 + (Ord(Ziffer[k]) - Ord('0'));
  235.         IF Wert <= MaxInt THEN BEGIN
  236.           Symb := IntConst;
  237.           GanzeZahl := Wert;        (* GANZEZAHL := INT(WERT); *)
  238.         END
  239.         ELSE BEGIN
  240.           Symb := LongConst;
  241.           New(SavKonstPtr);
  242.           SavKonstPtr^.KonstArt := Long;
  243.           SavKonstPtr^.SavVal := Wert;
  244.           LastConstVal.ValuePointer := SavKonstPtr;
  245.         END;
  246.       END
  247.   END;
  248.  
  249.  
  250.   PROCEDURE LiesZahl (VAR i,k: INTEGER);
  251.  
  252.   LABEL 1;
  253.  
  254.   VAR j: INTEGER;
  255.  
  256.   BEGIN
  257.     Oper := NoOp;  i := 0;
  258.     REPEAT
  259.       i := i+1;
  260.       IF i <= MaxZiffer THEN Ziffer[i] := Zeichen;
  261.       GetChar
  262.     UNTIL CharKind[Zeichen] <> Zahl;
  263.     IF (Zeichen = '.') OR (UpCase(Zeichen) = 'E' ) THEN BEGIN
  264.       k := i;
  265.       IF Zeichen = '.' THEN BEGIN
  266.         k := k+1;
  267.         IF k <= MaxZiffer THEN Ziffer[k] := Zeichen;
  268.         GetChar;
  269.         IF Zeichen = '.' THEN BEGIN
  270.           Zeichen := ':';  GOTO 1
  271.         END;
  272.         IF CharKind[Zeichen] <> Zahl THEN Error(201)
  273.         ELSE
  274.           REPEAT
  275.             k := k+1;
  276.             IF k <= MaxZiffer THEN Ziffer[k] := Zeichen;
  277.             GetChar
  278.           UNTIL CharKind[Zeichen] <> Zahl
  279.     END;
  280.     IF UpCase(Zeichen) = 'E' THEN BEGIN
  281.       k := k+1;
  282.       IF k <= MaxZiffer THEN Ziffer[k] := Zeichen;
  283.       GetChar;
  284.       IF(Zeichen = '+') OR (Zeichen = '-') THEN BEGIN
  285.         k := k+1;
  286.         IF k <= MaxZiffer THEN Ziffer[k] := Zeichen;
  287.         GetChar
  288.       END;
  289.       IF CharKind[Zeichen] <> Zahl THEN Error(201)
  290.       ELSE
  291.         REPEAT
  292.           k := k+1;
  293.           IF k <= MaxZiffer THEN Ziffer[k] := Zeichen;
  294.           GetChar
  295.         UNTIL CharKind[Zeichen] <> Zahl
  296.     END;
  297.     New(SavKonstPtr);  Symb := RealConst;  SavKonstPtr^.KonstArt := Reell;
  298.     WITH SavKonstPtr^ DO BEGIN
  299.       FOR j := 1 TO StringLength DO RVal[j] := ' ';
  300.       IF k <= MaxZiffer THEN
  301.         FOR j := 2 TO k+1 DO RVal[j] := Ziffer[j-1]
  302.       ELSE BEGIN
  303.         Error(203);  RVal[2] := '0';  RVal[3] := '.';  RVal[4] := '0'
  304.       END
  305.     END;
  306.     LastConstVal.ValuePointer := SavKonstPtr
  307.     END
  308.     ELSE
  309.       1:
  310.       SaveConstant(i)
  311.   END;
  312.  
  313.  
  314.   PROCEDURE LiesBezeichner (VAR k: INTEGER);
  315.  
  316.   LABEL 1;
  317.  
  318.   VAR i: INTEGER;
  319.  
  320.   BEGIN
  321.     k := 0;
  322.     REPEAT
  323.       IF k < MaxId THEN BEGIN
  324.         k := k+1;  Bez[k] := UpCase(Zeichen);
  325.       END;
  326.       GetChar
  327.     UNTIL NOT (CharKind[UpCase(Zeichen)] IN [Buchst,Zahl]);
  328.     IF k >= LBezLaenge THEN LBezLaenge := k
  329.     ELSE BEGIN
  330.       FOR i := k+1 TO LBezLaenge DO Bez[i] := ' ';
  331.       LBezLaenge := k
  332.     END;
  333.     FOR i := RWindex[k] TO RWindex[k+1]-1 DO
  334.       IF ResWord[i] = Bez THEN BEGIN
  335.         Symb := ReSymb[i];  Oper := ROp[i];  GOTO 1
  336.       END;
  337.     Symb := Bezeich;  Oper := NoOp;
  338.   1:
  339.   END;
  340.  
  341.  
  342.   PROCEDURE LiesString;
  343.  
  344.   VAR i: INTEGER;
  345.  
  346.   BEGIN
  347.     Lgth := 0;  Symb := StringConst;  Oper := NoOp;
  348.     REPEAT
  349.       REPEAT
  350.         GetChar;  Lgth := Lgth+1;
  351.         IF Lgth <= StringLength THEN Strng[Lgth] := Zeichen
  352.       UNTIL EoL OR (Zeichen = '''');
  353.       IF EoL THEN Error(202)
  354.       ELSE GetChar
  355.     UNTIL Zeichen <> '''';
  356.     Lgth := Lgth-1;
  357.     IF Lgth = 0 THEN Error(205)
  358.     ELSE IF Lgth = 1 THEN LastConstVal.GanzeZahl := Ord(Strng[1])
  359.     ELSE BEGIN
  360.       New(SavKonstPtr);  SavKonstPtr^.KonstArt := Strg;
  361.       IF Lgth > StringLength THEN BEGIN
  362.         Error(399);  Lgth := StringLength
  363.       END;
  364.       WITH SavKonstPtr^ DO BEGIN
  365.         SLgth := Lgth;
  366.         FOR i := 1 TO Lgth DO StringValue[i] := Strng[i]
  367.       END;
  368.       LastConstVal.ValuePointer := SavKonstPtr;
  369.     END
  370.   END;
  371.  
  372.  
  373. BEGIN (* GetSymbol *)
  374.   1:
  375.   REPEAT
  376.     WHILE (Zeichen = ' ') AND NOT EoL DO GetChar;
  377.     Stop := EoL;
  378.     IF Stop THEN GetChar
  379.   UNTIL NOT Stop;
  380.   SymbStart := IthChar;
  381.   IF CharKind[UpCase(Zeichen)] = Illegal THEN BEGIN
  382.     Symb := OtherSymb;  Oper := NoOp;
  383.     Error(399);  GetChar
  384.   END
  385.   ELSE
  386.     CASE CharKind[UpCase(Zeichen)] OF
  387.       Buchst     : LiesBezeichner(k);
  388.       Zahl       : LiesZahl(i,k);
  389.       QuotMark   : LiesString;
  390.       Colon      : BEGIN
  391.                      Oper := NoOp;  GetChar;
  392.                      IF Zeichen = '=' THEN BEGIN
  393.                        Symb := AssignTo;  GetChar
  394.                      END
  395.                      ELSE Symb := ColonSymb
  396.                    END;
  397.       Period     : BEGIN
  398.                      Oper := NoOp;  GetChar;
  399.                      IF Zeichen = '.' THEN BEGIN
  400.                        Symb := ColonSymb;  GetChar
  401.                      END
  402.                      ELSE Symb := UpTo
  403.                    END;
  404.       LessThan   : BEGIN
  405.                      GetChar;  Symb := VergleichOp;
  406.                      IF Zeichen = '=' THEN BEGIN
  407.                        Oper := LessOp;  GetChar
  408.                      END
  409.                      ELSE IF Zeichen = '>' THEN BEGIN
  410.                        Oper := NotEqualOp;  GetChar
  411.                      END
  412.                      ELSE Oper := LessThanOp
  413.                    END;
  414.       GreaterThan: BEGIN
  415.                      GetChar;  Symb := VergleichOp;
  416.                      IF Zeichen = '=' THEN BEGIN
  417.                        Oper := GrEqualOp;  GetChar
  418.                      END
  419.                      ELSE Oper := GrThanOp
  420.                    END;
  421.       oBrace     : BEGIN
  422.                      GetChar;
  423.                      IF Zeichen = '*' THEN BEGIN
  424.                        GetChar;
  425.                        IF Zeichen = '$' THEN CompilerOptionen;
  426.                        REPEAT
  427.                          WHILE (Zeichen <> '*') AND NOT Eof(Source) DO GetChar;
  428.                          GetChar
  429.                        UNTIL (Zeichen = ')') OR Eof(Source);
  430.                        GetChar;
  431.                        GOTO 1
  432.                      END;
  433.                      Symb := lBraces;  Oper := NoOp
  434.                    END;
  435.       Special    : BEGIN
  436.                      Symb := StdSymb[Zeichen];  Oper := OpS[Zeichen];
  437.                      GetChar
  438.                    END;
  439.       Blank      : Symb := OtherSymb;
  440.       lBrace     : BEGIN
  441.                      GetChar;
  442.                      IF Zeichen = '$' THEN CompilerOptionen;
  443.                      WHILE (Zeichen <> '}') AND NOT Eof(Source) DO GetChar;
  444.                      GetChar;
  445.                      GOTO 1
  446.                    END;
  447.     END;
  448. END; (* GetSymbol *)
  449.  
  450.  
  451. PROCEDURE InsertId (BezPtr: KonstP);
  452.  
  453. VAR Nam: ALPHA;  locc, locc1: KonstP;  IsLeftSon: BOOLEAN;
  454.  
  455. BEGIN
  456.   Nam := BezPtr^.Name;
  457.   locc := DispVec[DispTop].FirstDeclID;
  458.   IF locc = NIL THEN
  459.     DispVec[DispTop].FirstDeclID := BezPtr
  460.   ELSE BEGIN
  461.     REPEAT
  462.       locc1 := locc;
  463.       IF locc^.Name = Nam THEN BEGIN
  464.         Error(101);  locc := locc^.RightSon;  IsLeftSon := FALSE
  465.       END
  466.       ELSE IF locc^.Name<Nam THEN BEGIN
  467.         locc := locc^.RightSon;  IsLeftSon := FALSE
  468.       END
  469.       ELSE BEGIN
  470.         locc := locc^.LeftSon;  IsLeftSon := TRUE
  471.       END
  472.     UNTIL locc = NIL;
  473.     IF IsLeftSon THEN locc1^.LeftSon := BezPtr
  474.     ELSE locc1^.RightSon := BezPtr
  475.   END;
  476.   BezPtr^.LeftSon := NIL;  BezPtr^.RightSon := NIL;
  477. END;
  478.  
  479.  
  480. PROCEDURE FindRecFields (BezPtr: KonstP; VAR BezPtr1: KonstP);
  481.  
  482. LABEL 1;
  483.  
  484. BEGIN
  485.   WHILE BezPtr <> NIL DO
  486.     IF BezPtr^.Name = Bez THEN GOTO 1
  487.     ELSE IF BezPtr^.Name<Bez THEN BezPtr := BezPtr^.RightSon
  488.     ELSE BezPtr := BezPtr^.LeftSon;
  489.   1:
  490.   BezPtr1 := BezPtr;
  491. END;
  492.  
  493.  
  494. PROCEDURE FindeBez (IdKind: BezMenge; VAR BezPtr: KonstP);
  495.  
  496. LABEL 1;
  497.  
  498. VAR locc: KonstP;
  499.     Ende: BOOLEAN;
  500.  
  501. BEGIN
  502.   LastBst := DispTop;
  503.   Ende := FALSE;
  504.   WHILE NOT Ende DO BEGIN
  505.     locc := DispVec[LastBst].FirstDeclID;
  506.     WHILE locc <> NIL DO
  507.       IF locc^.Name = Bez THEN
  508.         IF locc^.Klass IN IdKind THEN GOTO 1
  509.         ELSE BEGIN
  510.           IF AllowsErrors THEN Error(103);
  511.           locc := locc^.RightSon
  512.         END
  513.       ELSE IF locc^.Name < Bez THEN
  514.         locc := locc^.RightSon
  515.       ELSE locc := locc^.LeftSon;
  516.     IF LastBst = 0 THEN Ende := TRUE
  517.     ELSE LastBst := LastBst-1
  518.   END;
  519.   IF AllowsErrors THEN BEGIN
  520.     Error(104);
  521.     IF TypeClass IN IdKind THEN locc := UTypPtr
  522.     ELSE IF VarClass IN IdKind THEN locc := UVarPtr
  523.     ELSE IF FieldClass IN IdKind THEN locc := UFldPtr
  524.     ELSE IF KonstKlasse IN IdKind THEN locc := UCstPtr
  525.     ELSE IF ProcClass IN IdKind THEN locc := UPrcPtr
  526.     ELSE locc := UFctPtr;
  527.   END;
  528.   1:
  529.   BezPtr := locc;
  530. END;
  531.  
  532.  
  533. PROCEDURE GetBounds (St: StP; VAR Minimum, Maximum: INTEGER);
  534.  
  535. BEGIN
  536.   Minimum := 0;  Maximum := 0;
  537.   IF St <> NIL THEN
  538.     WITH ST^ DO
  539.       IF Form = SubRange THEN BEGIN
  540.         Minimum := Min.GanzeZahl;  Maximum := Max.GanzeZahl
  541.       END
  542.       ELSE IF St = CharPtr THEN BEGIN
  543.         Minimum := OrdMinChar;  Maximum := OrdMaxChar;
  544.       END
  545.       ELSE IF ScalConst <> NIL THEN
  546.         Maximum := ScalConst^.Values.GanzeZahl;
  547. END;
  548.  
  549.  
  550. PROCEDURE GLab (VAR NxtLab: INTEGER);
  551.  
  552. BEGIN
  553.   IntLabel := IntLabel+1;
  554.   NxtLab := IntLabel;
  555. END;
  556.  
  557.  
  558. PROCEDURE Recover (ESets: Symbolmenge);
  559.  
  560. BEGIN
  561.   IF NOT Eof(Source) THEN BEGIN
  562.     WHILE NOT(Symb IN ESets) AND (NOT Eof(Source)) DO GetSymbol;
  563.     IF NOT (Symb IN ESets) THEN GetSymbol
  564.   END;
  565. END;
  566.  
  567.  
  568. PROCEDURE GConstant (ESets: Symbolmenge;
  569.                      VAR St: StP;
  570.                      VAR ParKonst: Value);
  571.  
  572. VAR
  573.   SavSp: StP;
  574.   locc: KonstP;
  575.   Sign: (NoSign,Pos,UnMinus);
  576.   SavKonstPtr: KonstPointer;
  577.   i: 2..StringLength;
  578.  
  579. BEGIN
  580.   SavSp := NIL;  ParKonst.GanzeZahl := 0;
  581.   IF NOT(Symb IN KonstStartSy) THEN BEGIN
  582.     Error(50);  Recover(ESets+KonstStartSy)
  583.   END;
  584.   IF Symb IN KonstStartSy THEN BEGIN
  585.     IF Symb = StringConst THEN BEGIN
  586.       IF Lgth = 1 THEN SavSp := CharPtr
  587.       ELSE BEGIN
  588.         New(SavSp);
  589.         WITH SavSp^ DO BEGIN
  590.           ElemType := CharPtr;  IndexType := NIL;
  591.           Size := Lgth*CharSize;  Form := Arrays
  592.         END
  593.       END;
  594.       ParKonst := LastConstVal;  GetSymbol
  595.     END
  596.     ELSE BEGIN
  597.       Sign := NoSign;
  598.       IF (Symb = AddOpr) AND (Oper IN [Plus,Minus]) THEN BEGIN
  599.         IF Oper = Plus THEN Sign := Pos ELSE Sign := UnMinus;
  600.         GetSymbol
  601.       END;
  602.       IF Symb = Bezeich THEN BEGIN
  603.         FindeBez([KonstKlasse],locc);
  604.         WITH locc^ DO BEGIN
  605.           SavSp := BezType;  ParKonst := Values
  606.         END;
  607.         IF Sign <> NoSign THEN
  608.           IF SavSp = IntPtr THEN BEGIN
  609.             IF Sign = UnMinus THEN
  610.               ParKonst.GanzeZahl := -ParKonst.GanzeZahl
  611.           END
  612.           ELSE IF SavSp = RealPtr THEN BEGIN
  613.             IF Sign = UnMinus THEN BEGIN
  614.               New(SavKonstPtr);
  615.               IF ParKonst.ValuePointer^.RVal[1] = '-' THEN
  616.                 SavKonstPtr^.RVal[1] := '+'
  617.               ELSE SavKonstPtr^.RVal[1] := '-';
  618.               FOR i := 2 TO StringLength DO
  619.                 SavKonstPtr^.RVal[i] := ParKonst.ValuePointer^.RVal[i];
  620.               ParKonst.ValuePointer := SavKonstPtr;
  621.             END
  622.           END
  623.           ELSE Error(105);
  624.         GetSymbol;
  625.       END
  626.       ELSE IF Symb = IntConst THEN BEGIN
  627.         IF Sign = UnMinus THEN
  628.           LastConstVal.GanzeZahl := -LastConstVal.GanzeZahl;
  629.         SavSp := IntPtr;  ParKonst := LastConstVal;  GetSymbol
  630.       END
  631.       ELSE IF Symb = RealConst THEN BEGIN
  632.         IF Sign=UnMinus THEN
  633.           LastConstVal.ValuePointer^.RVal[1] := '-';
  634.         SavSp := RealPtr;  ParKonst := LastConstVal;  GetSymbol
  635.       END
  636.       ELSE BEGIN
  637.         Error(106);  Recover(ESets)
  638.       END
  639.     END;
  640.     IF NOT (Symb IN ESets) THEN BEGIN
  641.       Error(6);  Recover(ESets)
  642.     END
  643.   END;
  644.   St := SavSp;
  645. END;
  646.  
  647.  
  648. FUNCTION HasEqualBounds (st1, st2: StP): BOOLEAN;
  649.  
  650. VAR lmin1, lmin2, lmax1, lmax2: INTEGER;
  651.  
  652. BEGIN
  653.   IF (st1 = NIL) OR (st2 = NIL) THEN HasEqualBounds := TRUE
  654.   ELSE BEGIN
  655.     GetBounds(st1,lmin1,lmax1);
  656.     GetBounds(st2,lmin2,lmax2);
  657.     HasEqualBounds := (lmin1 = lmin2) AND (lmax1 = lmax2)
  658.   END;
  659. END;
  660.  
  661.  
  662. FUNCTION IsCompatible (st1, st2: StP): BOOLEAN;
  663.  
  664. VAR
  665.   nxt1, nxt2: KonstP;
  666.   compatible: BOOLEAN;
  667.   LTestP1, LTestP2: TestP;
  668.  
  669. BEGIN
  670.   IF st1 = st2 THEN IsCompatible := TRUE
  671.   ELSE IF (st1 <> NIL) AND (st2 <> NIL) THEN
  672.    IF St1^.Form = St2^.Form THEN
  673.      CASE St1^.Form OF
  674.        Scalar  : IsCompatible := FALSE;
  675.        SubRange: IsCompatible := IsCompatible(St1^.RangeType,St2^.RangeType);
  676.        Pointers: BEGIN
  677.                    compatible := FALSE;
  678.                    LTestP1 := GlobTestP;
  679.                    LTestP2 := GlobTestP;
  680.                    WHILE LTestP1 <> NIL DO
  681.                      WITH LTestP1^ DO BEGIN
  682.                        IF (ElT1 = St1^.ElType) AND (ElT2 = St2^.ElType) THEN
  683.                          compatible := TRUE;
  684.                        LTestP1 := LastTestP
  685.                      END;
  686.                    IF NOT compatible THEN BEGIN
  687.                      New(LTestP1);
  688.                      WITH LTestP1^ DO BEGIN
  689.                        ElT1 := St1^.ElType;
  690.                        ElT2 := St2^.ElType;
  691.                        LastTestP := GlobTestP
  692.                      END;
  693.                      GlobTestP := LTestP1;
  694.                      compatible := IsCompatible(St1^.ElType,St2^.ElType)
  695.                    END;
  696.                    IsCompatible := compatible;  GlobTestP := LTestP2
  697.                  END;
  698.        Power   : IsCompatible := IsCompatible(St1^.ElemSet,St2^.ElemSet);
  699.        Arrays  : BEGIN
  700.                    compatible := IsCompatible(St1^.ElemType,St2^.ElemType)
  701.                                  AND IsCompatible(St1^.IndexType,St2^.IndexType);
  702.                    IsCompatible := compatible AND (St1^.Size=St2^.Size) AND
  703.                                    HasEqualBounds(St1^.IndexType,St2^.IndexType)
  704.                  END;
  705.        Records : BEGIN
  706.                    nxt1 := St1^.FirstField;  nxt2 := St2^.FirstField;
  707.                    compatible := TRUE;
  708.                    WHILE (nxt1 <> NIL) AND (nxt2 <> NIL) DO BEGIN
  709.                      compatible := compatible
  710.                                    AND IsCompatible(Nxt1^.BezType,Nxt2^.BezType);
  711.                      nxt1 := Nxt1^.Next;  nxt2 := Nxt2^.Next
  712.                    END;
  713.                    IsCompatible := compatible AND (nxt1 = NIL) AND (nxt2 = NIL)
  714.                                    AND (St1^.RecVar = NIL) AND (St2^.RecVar = NIL)
  715.                  END;
  716.        Files   : IsCompatible := IsCompatible(St1^.FileType,St2^.FileType)
  717.      END
  718.    ELSE IF St1^.Form = SubRange THEN
  719.      IsCompatible := IsCompatible(St1^.RangeType,st2)
  720.    ELSE
  721.      IF St2^.Form = SubRange THEN
  722.        IsCompatible := IsCompatible(st1,St2^.RangeType)
  723.      ELSE IsCompatible := FALSE
  724.    ELSE IsCompatible := TRUE;
  725. END;
  726.  
  727.  
  728. FUNCTION Strng (St: StP): BOOLEAN;
  729.  
  730. BEGIN
  731.   Strng := FALSE;
  732.   IF St <> NIL THEN
  733.     IF ST^.Form = Arrays THEN
  734.       IF IsCompatible(ST^.ElemType,CharPtr) THEN Strng := TRUE;
  735. END;
  736.  
  737.  
  738. FUNCTION IsFileOfFile (SavSp: StP): BOOLEAN;
  739.  
  740. LABEL 1;
  741.  
  742. VAR SavSP1: StP;  First: KonstP;  Erg: BOOLEAN;
  743.  
  744. BEGIN
  745.   Erg := FALSE;
  746.   IF SavSp <> NIL THEN
  747.     IF SavSp^.Form = Files THEN Erg := TRUE
  748.     ELSE IF SavSp^.Form >= Power THEN
  749.       WITH SavSp^ DO BEGIN
  750.         CASE Form OF
  751.           Pointers: SavSP1 := ElType;
  752.           Power   : SavSP1 := ElemSet;
  753.           Arrays  : BEGIN
  754.                       Erg := IsFileOfFile(ElemType);
  755.                       IF NOT Erg THEN Erg := IsFileOfFile(IndexType);
  756.                       GOTO 1
  757.                     END;
  758.           Records : BEGIN
  759.                       Erg := IsFileOfFile(RecVar);
  760.                       First := FirstField;
  761.                       WHILE NOT Erg AND (First <> NIL) DO BEGIN
  762.                         Erg := IsFileOfFile(First^.BezType);
  763.                         IF NOT Erg THEN First := First^.Next
  764.                       END;
  765.                       GOTO 1;
  766.                     END;
  767.           TagFld  : BEGIN
  768.                       Erg := IsFileOfFile(TagFieldP^.BezType);
  769.                       IF NOT Erg THEN Erg := IsFileOfFile(FirstVar);
  770.                       GOTO 1
  771.                     END;
  772.           Variant : BEGIN
  773.                       Erg := IsFileOfFile(NxtVar);
  774.                       IF NOT Erg THEN Erg := IsFileOfFile(VarTVar);
  775.                       GOTO 1
  776.                     END;
  777.         END;
  778.         Erg := IsFileOfFile(SavSP1);
  779.       END;
  780.   1:
  781.   IsFileOfFile := Erg;
  782. END;
  783.  
  784.  
  785. PROCEDURE MovStk (i: INTEGER; VAR TopNew, StkMax: INTEGER);
  786.  
  787. BEGIN
  788.   TopNew := TopNew + StkMov[i] * MaxStack;
  789.   IF TopNew > StkMax THEN StkMax := TopNew;
  790. END;
  791.  
  792.  
  793. PROCEDURE PutIC;
  794.  
  795. BEGIN
  796.   IF (ICount MOD 10) = 0 THEN WriteLn(Dat,'i',ICount:5);
  797. END;
  798.  
  799.  
  800. PROCEDURE GenDBG (VAR Name: ALPHA);
  801.  
  802. BEGIN
  803.   IF IsPrtCode AND Debug THEN WriteLn(Dat,' dbg ''' ,Name,'''');
  804. END;
  805.  
  806.  
  807. PROCEDURE GenPopDBG;
  808.  
  809. BEGIN
  810.   IF IsPrtCode AND Debug THEN WriteLn(Dat,' pop');
  811. END;
  812.  
  813.  
  814. PROCEDURE G0 (Operator: OpRange; VAR TopNew, StkMax: INTEGER);
  815.  
  816. BEGIN
  817.   IF IsPrtCode THEN BEGIN
  818.     PutIC;  WriteLn(Dat,PCo[Operator]:4)
  819.   END;
  820.   ICount := ICount+1;  MovStk(Operator,TopNew,StkMax);
  821. END;
  822.  
  823.  
  824. PROCEDURE G1 (Operator: OpRange;
  825.               Param2: INTEGER;
  826.               VAR TopNew, StkMax: INTEGER;
  827.               VAR KonstPtr: CstPtrArray);
  828.  
  829. VAR k: INTEGER;
  830.  
  831. BEGIN
  832.   IF IsPrtCode THEN BEGIN
  833.     PutIC;  Write(Dat,PCo[Operator]:4);
  834.     IF Operator = 30 THEN BEGIN
  835.       WriteLn(Dat,StdNames[Param2]:12);
  836.       TopNew := TopNew + StdStkMov[Param2] * MaxStack;
  837.       IF TopNew > StkMax THEN StkMax := TopNew
  838.     END
  839.     ELSE BEGIN
  840.       IF Operator = 38 THEN BEGIN
  841.         Write(Dat,' ''' );
  842.         WITH KonstPtr[Param2]^ DO BEGIN
  843.           FOR k := 1 TO SLgth DO Write(Dat,StringValue[k]:1);
  844.         END;
  845.         WriteLn(Dat,'''')
  846.       END
  847.       ELSE IF Operator = 42 THEN WriteLn(Dat,Chr(Param2))
  848.       ELSE WriteLn(Dat,Param2:12);
  849.       MovStk(Operator,TopNew,StkMax);
  850.     END
  851.   END;
  852.   ICount := ICount+1;
  853. END;
  854.  
  855.  
  856. PROCEDURE G2 (Operator: OpRange;
  857.               Param1, Param2: INTEGER;
  858.               VAR TopNew, StkMax: INTEGER;
  859.               VAR KonstPtr: CstPtrArray);
  860.  
  861. VAR k: INTEGER;
  862.  
  863. BEGIN
  864.   IF IsPrtCode THEN BEGIN
  865.     PutIC;  Write(Dat,PCo[Operator]:4);
  866.     CASE Operator OF
  867.                     30 : WriteLn(Dat,StdNames[Param1]:12,' ',Param2);
  868.            45,50,54,56 : WriteLn(Dat,' ',Param1:3,Param2:8);
  869.       47,48,49,52,53,55: BEGIN
  870.                            Write(Dat,Chr(Param1));
  871.                            IF Chr(Param1) = 'm' THEN Write(Dat,Param2:11);
  872.                            WriteLn(Dat)
  873.                          END;
  874.                      51: CASE Param1 OF
  875.                            1: WriteLn(Dat,'i ',Param2);
  876.                            2: BEGIN
  877.                                 Write(Dat,'r ');
  878.                                 WITH KonstPtr[Param2]^ DO
  879.                                   FOR k := 1 TO StringLength DO
  880.                                     Write(Dat,RVal[k]);
  881.                                 WriteLn(Dat)
  882.                               END;
  883.                            3: WriteLn(Dat,'b ',Param2);
  884.                            4: WriteLn(Dat,'n');
  885.                            5: BEGIN
  886.                                 Write(Dat,'(');
  887.                                 WITH KonstPtr[Param2]^ DO
  888.                                   FOR k := SetMin TO SetMax DO
  889.                                     IF k IN Menge THEN Write(Dat,k:4,' ');
  890.                                 WriteLn(Dat,')')
  891.                               END;
  892.                            6: WriteLn(Dat,'c ''':3,Chr(Param2),'''');
  893.                            7: WriteLn(Dat,'l ',Param2);
  894.                          END
  895.     END
  896.   END;
  897.   ICount := ICount+1;  MovStk(Operator,TopNew,StkMax);
  898. END;
  899.  
  900.  
  901. PROCEDURE GenTypIndicator (St: StP);
  902.  
  903. BEGIN
  904.   IF St <> NIL THEN
  905.     WITH St^ DO
  906.       CASE Form OF
  907.           Scalar: IF St = IntPtr THEN Write(Dat,'i')
  908.                   ELSE IF St = BooleanPtr THEN Write(Dat,'b')
  909.                   ELSE IF St = CharPtr THEN Write(Dat,'c')
  910.                   ELSE IF St = LongPtr THEN Write(Dat,'l')
  911.                   ELSE IF ScalKind = Declared THEN Write(Dat,'i')
  912.                   ELSE Write(Dat,'r');
  913.         SubRange: GenTypIndicator(RangeType);
  914.         Pointers: Write(Dat,'a');
  915.         Power   : Write(Dat,'s');
  916.         Records,
  917.         Arrays  : Write(Dat,'m');
  918.         Files,
  919.         TagFld,
  920.         Variant : Error(500)
  921.     END;
  922. END;
  923.  
  924.  
  925. PROCEDURE G0T (Operator: OpRange;
  926.                St: StP;
  927.                VAR TopNew, StkMax: INTEGER);
  928.  
  929. BEGIN
  930.   IF IsPrtCode THEN BEGIN
  931.     PutIC;
  932.     Write(Dat,PCo[Operator]:4);
  933.     GenTypIndicator(St);
  934.     WriteLn(Dat);
  935.   END;
  936.   ICount := ICount+1;  MovStk(Operator,TopNew,StkMax);
  937. END;
  938.  
  939.  
  940. PROCEDURE G1T (Operator: OpRange;
  941.                Param2: INTEGER;
  942.                St: StP;
  943.                VAR TopNew, StkMax: INTEGER);
  944.  
  945. BEGIN
  946.   IF IsPrtCode THEN BEGIN
  947.     PutIC;
  948.     Write(Dat,PCo[Operator]:4);
  949.     GenTypIndicator(St);
  950.     WriteLn(Dat,Param2:11)
  951.   END;
  952.   ICount := ICount+1;  MovStk(Operator,TopNew,StkMax);
  953. END;
  954.  
  955.  
  956. PROCEDURE G2T (Operator: OpRange;
  957.                Param1, Param2: INTEGER;
  958.                St: StP;
  959.                VAR TopNew, StkMax: INTEGER);
  960.  
  961. BEGIN
  962.   IF IsPrtCode THEN BEGIN
  963.     PutIC;
  964.     Write(Dat,PCo[Operator]:4);
  965.     GenTypIndicator(St);
  966.     WriteLn(Dat,Param1:3 (* +5 * Ord(Abs(FP1)>99) *),Param2:8)
  967.   END;
  968.   ICount := ICount+1;  MovStk(Operator,TopNew,StkMax);
  969. END;
  970.  
  971.  
  972. PROCEDURE PushContents (VAR TopNew, StkMax:INTEGER;
  973.                         VAR KonstPtr: CstPtrArray;
  974.                         VAR KonstPtrIndex: INTEGER);
  975.  
  976. BEGIN
  977.   WITH Attr DO
  978.     IF TyPtr <> NIL THEN BEGIN
  979.       CASE Art OF
  980.          IsKonst: IF (TyPtr^.Form = Scalar) AND (TyPtr <> RealPtr) THEN
  981.                     IF TyPtr = BooleanPtr THEN
  982.                       G2(51,3,KonstVal.GanzeZahl,TopNew,StkMax,KonstPtr)
  983.                     ELSE IF TyPtr = CharPtr THEN
  984.                       G2(51,6,KonstVal.GanzeZahl,TopNew,StkMax,KonstPtr)
  985.                     ELSE IF TyPtr = LongPtr THEN
  986.                       WriteLn(Dat,' ldcl ',KonstVal.ValuePointer^.SavVal)
  987.                     ELSE G2(51,1,KonstVal.GanzeZahl,TopNew,StkMax,KonstPtr)
  988.                   ELSE IF TyPtr = NilPtr THEN
  989.                     G2(51,4,0,TopNew,StkMax,KonstPtr)
  990.                   ELSE IF KonstPtrIndex >= MaxKonstants THEN Error(254)
  991.                   ELSE BEGIN
  992.                     KonstPtrIndex := KonstPtrIndex+1;
  993.                     KonstPtr[KonstPtrIndex] := KonstVal.ValuePointer;
  994.                     IF TyPtr = RealPtr THEN
  995.                       G2(51,2,KonstPtrIndex,TopNew,StkMax,KonstPtr)
  996.                     ELSE
  997.                       G2(51,5,KonstPtrIndex,TopNew,StkMax,KonstPtr)
  998.                   END;
  999.            IsVar: CASE Zugriff OF
  1000.                       Direkt: IF VarBSt <= 1 THEN
  1001.                                 G1T(39,OffSet,TyPtr,TopNew,StkMax)
  1002.                               ELSE
  1003.                                 G2T(54,Bst-VarBSt,OffSet,TyPtr,TopNew,StkMax);
  1004.                     Indirekt: G1T(35,IOffSet,TyPtr,TopNew,StkMax);
  1005.                      Indexed: Error(400)
  1006.                   END;
  1007.           IsExpr:
  1008.       END;
  1009.       Art := IsExpr
  1010.     END;
  1011. END;
  1012.  
  1013.  
  1014. PROCEDURE Store (VAR StoreAttr: Attribut; VAR TopNew, StkMax: INTEGER);
  1015.  
  1016. BEGIN
  1017.   WITH StoreAttr DO
  1018.     IF TyPtr <> NIL THEN
  1019.       CASE Zugriff OF
  1020.           Direkt: IF VarBSt <= 1 THEN G1T(43,OffSet,TyPtr,TopNew,StkMax)
  1021.                   ELSE G2T(56,Bst-VarBSt,OffSet,TyPtr,TopNew,StkMax);
  1022.         Indirekt: IF IOffSet <> 0 THEN Error(400)
  1023.                   ELSE G0T(26,TyPtr,TopNew,StkMax);
  1024.          Indexed: Error(400)
  1025.       END;
  1026. END;
  1027.  
  1028.  
  1029. PROCEDURE PushAddress (VAR TopNew, StkMax: INTEGER;
  1030.                        VAR KonstPtr: CstPtrArray;
  1031.                        VAR KonstPtrIndex: INTEGER);
  1032.  
  1033. BEGIN
  1034.   WITH Attr DO
  1035.     IF TyPtr <> NIL THEN BEGIN
  1036.       CASE Art OF
  1037.         IsKonst: IF Strng(TyPtr) THEN
  1038.                    IF KonstPtrIndex >= MaxKonstants THEN Error(254)
  1039.                    ELSE BEGIN
  1040.                      KonstPtrIndex := KonstPtrIndex+1;
  1041.                      KonstPtr[KonstPtrIndex] := KonstVal.ValuePointer;
  1042.                      G1(38,KonstPtrIndex,TopNew,StkMax,KonstPtr)
  1043.                    END
  1044.                  ELSE Error(400);
  1045.           IsVar: CASE Zugriff OF
  1046.                      Direkt: IF VarBSt <= 1 THEN
  1047.                                G1(37,OffSet,TopNew,StkMax,KonstPtr)
  1048.                              ELSE
  1049.                                G2(50,Bst-VarBSt,OffSet,TopNew,StkMax,KonstPtr);
  1050.                    Indirekt: IF IOffSet <> 0 THEN
  1051.                                G1T(34,IOffSet,NilPtr,TopNew,StkMax);
  1052.                     Indexed: Error(400)
  1053.                  END;
  1054.         IsExpr : Error(400)
  1055.       END;
  1056.       Art := IsVar; Zugriff := Indirekt; IOffSet := 0
  1057.     END;
  1058. END;
  1059.  
  1060.  
  1061. PROCEDURE GJump (JumpTo: INTEGER;
  1062.                  VAR TopNew, StkMax: INTEGER;
  1063.                  VAR KonstPtr: CstPtrArray;
  1064.                  VAR KonstPtrIndex:INTEGER);
  1065.  
  1066. BEGIN
  1067.   PushContents(TopNew,StkMax,KonstPtr,KonstPtrIndex);
  1068.   IF Attr.TyPtr <> NIL THEN
  1069.     IF Attr.TyPtr <> BooleanPtr THEN Error(144);
  1070.   IF IsPrtCode THEN BEGIN
  1071.     PutIC;  WriteLn(Dat,PCo[33]:4,' l':8, JumpTo:4)
  1072.   END;
  1073.   ICount := ICount+1;  MovStk(33,TopNew,StkMax);
  1074. END;
  1075.  
  1076.  
  1077. PROCEDURE GCase (Operator: OpRange;
  1078.                  Param2: INTEGER;
  1079.                  VAR TopNew, StkMax: INTEGER);
  1080.  
  1081. BEGIN
  1082.   IF IsPrtCode THEN BEGIN
  1083.     PutIC;  WriteLn(Dat,PCo[Operator]:4,' l':8, Param2:4)
  1084.   END;
  1085.   ICount := ICount+1;  MovStk(Operator,TopNew,StkMax);
  1086. END;
  1087.  
  1088.  
  1089. PROCEDURE GProcCall (Operator: OpRange;
  1090.                      Param1, Param2: INTEGER;
  1091.                      VAR TopNew, StkMax: INTEGER);
  1092.  
  1093. BEGIN
  1094.   IF IsPrtCode THEN BEGIN
  1095.     (* PutIC;  ABGEAENDERT AM 27.02.87 *)
  1096.     WriteLn(Dat,PCo[Operator]:4,Param1:4,'l':4, Param2:4)
  1097.   END;
  1098.   ICount := ICount+1;  MovStk(Operator,TopNew,StkMax);
  1099. END;
  1100.  
  1101.  
  1102. PROCEDURE CheckBounds (St: StP; VAR TopNew, StkMax: INTEGER);
  1103.  
  1104. VAR lmin, lmax: INTEGER;
  1105.  
  1106. BEGIN
  1107.   IF St <> NIL THEN
  1108.     IF St <> IntPtr THEN
  1109.       IF St <> RealPtr THEN
  1110.        IF St <> LongPtr THEN
  1111.          IF St^.Form <=  SubRange THEN BEGIN
  1112.            GetBounds(St,lmin,lmax);
  1113.            G2T(45,lmin,lmax,St,TopNew,StkMax)
  1114.          END;
  1115. END;
  1116.  
  1117.  
  1118. PROCEDURE PushLabel (LabName:INTEGER);
  1119.  
  1120. BEGIN
  1121.   IF IsPrtCode THEN WriteLn(Dat,'l',LabName:4);
  1122. END;
  1123.  
  1124. BEGIN
  1125. END.
  1126.