home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 02 / declare.pas next >
Encoding:
Pascal/Delphi Source File  |  1988-02-08  |  32.0 KB  |  894 lines

  1.     PROCEDURE Typ (ESets: Symbolmenge;
  2.                    VAR St: StP;
  3.                    VAR SizeOfT: AddressRange;
  4.                    VAR Stop: BOOLEAN);
  5.  
  6.  
  7.     VAR
  8.       SavSp,SavSP1,SavSP2: StP;
  9.       OldDispIndex: DispRange;
  10.       locc: KonstP;
  11.       ActSize, OffS: AddressRange;
  12.       LMIN,LMAX: INTEGER;
  13.  
  14.  
  15.       PROCEDURE FieldList (ESets: Symbolmenge;
  16.                            VAR RVars: StP;
  17.                            VAR Stop: BOOLEAN;
  18.                            VAR OffS: AddressRange);
  19.  
  20.       VAR
  21.         locc,locc1,Nxt,nxt1: KonstP;
  22.         SavSp,SavSP1,SavSP2,SavSP3,SavSP4: StP;
  23.         MinSize,MaxSize,ActSize: AddressRange;
  24.         SavValu: Value;
  25.  
  26.       BEGIN
  27.         nxt1 := NIL;  SavSp := NIL;
  28.         IF NOT(Symb IN (ESets+[Bezeich,CaseSymb])) THEN BEGIN
  29.           Error(19);  Recover(ESets+[Bezeich,CaseSymb])
  30.         END;
  31.         WHILE Symb = Bezeich DO BEGIN
  32.           Nxt := nxt1;
  33.           REPEAT
  34.             IF Symb = Bezeich THEN BEGIN
  35.               New(locc);
  36.               WITH locc^ DO BEGIN
  37.                 Name := Bez;  BezType := NIL;  Next := Nxt;
  38.                 Klass := FieldClass
  39.               END;
  40.               Nxt := locc;
  41.               InsertId(locc);
  42.               GetSymbol
  43.             END
  44.             ELSE Error(2);
  45.             IF NOT (Symb IN [CommaSymb,ColonSymb]) THEN BEGIN
  46.               Error(6);
  47.               Recover(ESets+[CommaSymb,ColonSymb,Semicolon,CaseSymb])
  48.             END;
  49.             Stop := Symb <> CommaSymb;
  50.             IF NOT Stop THEN GetSymbol
  51.           UNTIL Stop;
  52.           IF Symb = ColonSymb THEN GetSymbol ELSE Error(5);
  53.           Typ(ESets+[CaseSymb,Semicolon],SavSp,ActSize,Stop);
  54.           WHILE Nxt <> nxt1 DO
  55.             WITH Nxt^ DO BEGIN
  56.               BezType := SavSp; FieldAddress := OffS;
  57.               Nxt := Next; OffS := OffS+ActSize
  58.             END;
  59.             nxt1 := locc;
  60.             WHILE Symb = Semicolon DO BEGIN
  61.               GetSymbol;
  62.               IF NOT (Symb IN ESets+[Bezeich,CaseSymb,Semicolon]) THEN BEGIN
  63.                 Error(19);  Recover(ESets+[Bezeich,CaseSymb])
  64.               END
  65.             END
  66.           END;
  67.           Nxt := NIL;
  68.           WHILE nxt1 <> NIL DO
  69.             WITH Nxt1^ DO BEGIN
  70.               locc := Next;  Next := Nxt;  Nxt := nxt1;  nxt1 := locc
  71.             END;
  72.           IF Symb = CaseSymb THEN BEGIN
  73.             New(SavSp);
  74.             WITH SavSp^ DO BEGIN
  75.               TagFieldP := NIL;  FirstVar := NIL;  Form := TagFld
  76.             END;
  77.             RVars := SavSp;
  78.             GetSymbol;
  79.             IF Symb = Bezeich THEN BEGIN
  80.               New(locc);
  81.               WITH locc^ DO BEGIN
  82.                 Name := Bez;  BezType := NIL;  Klass := FieldClass;
  83.                 Next := NIL;  FieldAddress := OffS
  84.               END;
  85.               InsertId(locc);
  86.               GetSymbol;
  87.               IF Symb = ColonSymb THEN GetSymbol ELSE Error(5);
  88.               IF Symb = Bezeich THEN BEGIN
  89.                 FindeBez([TypeClass],locc1);
  90.                 SavSP1 := locc1^.BezType;
  91.                 IF SavSP1 <> NIL THEN BEGIN
  92.                   locc^.FieldAddress := OffS;
  93.                   OffS := OffS+SavSP1^.Size;
  94.                   IF (SavSP1^.Form <= SubRange) OR Strng(SavSP1) THEN BEGIN
  95.                     IF IsCompatible(RealPtr,SavSP1) THEN Error(109)
  96.                     ELSE IF Strng(SavSP1) THEN Error(399);
  97.                     locc^.BezType := SavSP1;  SavSp^.TagFieldP := locc
  98.                   END
  99.                   ELSE Error(110);
  100.                 END;
  101.                 GetSymbol;
  102.               END
  103.               ELSE BEGIN
  104.                 Error(2);  Recover(ESets+[OfSymb,lBraces])
  105.               END
  106.             END
  107.             ELSE BEGIN
  108.               Error(2);  Recover(ESets+[OfSymb,lBraces])
  109.             END;
  110.             SavSp^.Size := OffS;
  111.             IF Symb = OfSymb THEN GetSymbol ELSE Error(8);
  112.             SavSP1 := NIL;  MinSize := OffS;  MaxSize := OffS;
  113.               REPEAT
  114.               SavSP2 := NIL;
  115.               IF NOT(Symb IN ESets+[Semicolon]) THEN BEGIN
  116.                 REPEAT
  117.                   GConstant(ESets+[CommaSymb,ColonSymb,lBraces],SavSP3,SavValu);
  118.                   IF SavSp^.TagFieldP <> NIL THEN
  119.                     IF NOT IsCompatible(SavSp^.TagFieldP^.BezType,SavSP3) THEN
  120.                       Error(111);
  121.                   New(SavSP3);
  122.                   WITH SavSP3^ DO BEGIN
  123.                     NxtVar := SavSP1;  VarTVar := SavSP2;  VarWert := SavValu;
  124.                     Form := Variant
  125.                   END;
  126.                   SavSP4 := SavSP1;
  127.                   WHILE SavSP4 <> NIL DO
  128.                     WITH SavSP4^ DO BEGIN
  129.                       IF VarWert.GanzeZahl = SavValu.GanzeZahl THEN Error(178);
  130.                       SavSP4 := NxtVar
  131.                     END;
  132.                   SavSP1 := SavSP3;  SavSP2 := SavSP3;
  133.                   Stop := Symb <> CommaSymb;
  134.                   IF NOT Stop THEN GetSymbol
  135.                 UNTIL Stop;
  136.                 IF Symb = ColonSymb THEN GetSymbol ELSE Error(5);
  137.                 IF Symb = lBraces THEN GetSymbol ELSE Error(9);
  138.                 FieldList(ESets+[rBrace,Semicolon],SavSP2,Stop,OffS);
  139.                 IF OffS > MaxSize THEN MaxSize := OffS;
  140.                 WHILE SavSP3 <> NIL DO BEGIN
  141.                   SavSP4 := SavSP3^.VarTVar;  SavSP3^.VarTVar := SavSP2;
  142.                   SavSP3^.Size := OffS;  SavSP3 := SavSP4
  143.                 END;
  144.                 IF Symb = rBrace THEN BEGIN
  145.                   GetSymbol;
  146.                   IF NOT (Symb IN ESets+[Semicolon]) THEN BEGIN
  147.                     Error(6);  Recover(ESets+[Semicolon])
  148.                   END
  149.                 END
  150.                 ELSE Error(4);
  151.               END;
  152.               Stop := Symb <> Semicolon;
  153.               IF NOT Stop THEN BEGIN
  154.                 OffS := MinSize;
  155.                 GetSymbol
  156.               END
  157.             UNTIL Stop;
  158.             OffS := MaxSize;
  159.             SavSp^.FirstVar := SavSP1;
  160.           END
  161.           ELSE RVars := NIL;
  162.       END; (* FieldList *)
  163.  
  164.  
  165.       PROCEDURE SimpleType (ESets: Symbolmenge;
  166.                             VAR St: StP;
  167.                             VAR SizeOfT: AddressRange);
  168.   
  169.       VAR SavSp,SavSP1: StP;
  170.           locc,locc1: KonstP;
  171.           SaveTop: DispRange;
  172.           HasOrd: INTEGER;
  173.           SavValu: Value;
  174.   
  175.       BEGIN
  176.         SizeOfT := 1;
  177.         IF NOT (Symb IN SimpleStartSymb) THEN BEGIN
  178.           Error(1);  Recover(ESets+SimpleStartSymb)
  179.         END;
  180.         IF Symb IN SimpleStartSymb THEN BEGIN
  181.           IF Symb=lBraces THEN BEGIN
  182.             SaveTop := DispTop;
  183.             WHILE DispVec[DispTop].OccursIn <> IsBlock DO DispTop := DispTop-1;
  184.             New(SavSp);
  185.             WITH SavSp^ DO BEGIN
  186.               Size := IntSize; Form := Scalar;
  187.               ScalKind := Declared
  188.             END;
  189.             locc1 := NIL;  HasOrd := 0;
  190.             REPEAT
  191.               GetSymbol;
  192.               IF Symb = Bezeich THEN BEGIN
  193.                 New(locc);
  194.                 WITH locc^ DO BEGIN
  195.                   Name := Bez;  BezType := SavSp;  Next := locc1;
  196.                   Values.GanzeZahl := HasOrd;  Klass := KonstKlasse
  197.                 END;
  198.                 InsertId(locc);
  199.                 HasOrd := HasOrd+1;
  200.                 locc1 := locc;  GetSymbol
  201.               END
  202.               ELSE Error(2);
  203.               IF NOT (Symb IN ESets + [CommaSymb,rBrace]) THEN BEGIN
  204.                 Error(6); Recover(ESets+[CommaSymb,rBrace])
  205.               END
  206.             UNTIL Symb <> CommaSymb;
  207.             SavSp^.ScalConst := locc1;  DispTop := SaveTop;
  208.             IF Symb=rBrace THEN GetSymbol ELSE Error(4)
  209.           END
  210.           ELSE BEGIN
  211.             IF Symb = Bezeich THEN BEGIN
  212.               FindeBez([TypeClass,KonstKlasse],locc);
  213.               GetSymbol;
  214.               IF locc^.Klass = KonstKlasse THEN BEGIN
  215.                 New(SavSp);
  216.                 WITH SavSp^,locc^ DO BEGIN
  217.                   RangeType := BezType;  Form := SubRange;
  218.                   IF Strng(RangeType) THEN BEGIN
  219.                     Error(148);  RangeType := NIL
  220.                   END;
  221.                   Min := Values;  Size := IntSize
  222.                 END;
  223.                 IF Symb = ColonSymb THEN GetSymbol ELSE Error(5);
  224.                 GConstant(ESets,SavSP1,SavValu);
  225.                 SavSp^.Max := SavValu;
  226.                 IF SavSp^.RangeType <> SavSP1 THEN Error(107)
  227.               END
  228.               ELSE BEGIN
  229.                 SavSp := locc^.BezType;
  230.                 IF SavSp <> NIL THEN SizeOfT := SavSp^.Size
  231.               END
  232.             END
  233.             ELSE BEGIN
  234.               New(SavSp);  SavSp^.Form := SubRange;
  235.               GConstant(ESets+[ColonSymb],SavSP1,SavValu);
  236.               IF Strng(SavSP1) THEN BEGIN
  237.                 Error(148);  SavSP1 := NIL
  238.               END;
  239.               WITH SavSp^ DO BEGIN
  240.                 RangeType := SavSP1;  Min := SavValu;  Size := IntSize
  241.               END;
  242.               IF Symb = ColonSymb THEN GetSymbol ELSE Error(5);
  243.               GConstant(ESets,SavSP1,SavValu);
  244.               SavSp^.Max := SavValu;
  245.               IF SavSp^.RangeType <> SavSP1 THEN Error(107)
  246.             END;
  247.             IF SavSp <> NIL THEN
  248.                WITH SavSp^ DO
  249.                  IF Form = SubRange THEN
  250.                    IF RangeType <> NIL THEN
  251.                      IF RangeType = RealPtr THEN Error(399)
  252.                      ELSE IF Min.GanzeZahl > Max.GanzeZahl THEN Error(102)
  253.           END;
  254.           St := SavSp;
  255.           IF NOT (Symb IN ESets) THEN BEGIN
  256.             Error(6);  Recover(ESets)
  257.           END
  258.         END
  259.         ELSE St := NIL;
  260.       END; (* SimpleTyp *)
  261.  
  262.  
  263.     BEGIN (* Typ *)
  264.       IF NOT (Symb IN TypeStartSymb) THEN BEGIN
  265.         Error(10);  Recover(ESets+TypeStartSymb)
  266.       END;
  267.       IF Symb IN TypeStartSymb THEN BEGIN
  268.         IF Symb IN SimpleStartSymb THEN SimpleType(ESets,St,SizeOfT)
  269.         ELSE IF Symb = Pointer THEN BEGIN
  270.           New(SavSp);  St := SavSp;
  271.           WITH SavSp^ DO BEGIN
  272.             ElType := NIL;  Size := PtrSize;  Form := Pointers
  273.           END;
  274.           GetSymbol;
  275.           IF Symb = Bezeich THEN BEGIN
  276.             AllowsErrors := FALSE;
  277.             FindeBez([TypeClass],locc);  AllowsErrors := TRUE;
  278.             IF locc = NIL THEN BEGIN
  279.               New(locc);
  280.               WITH locc^ DO BEGIN
  281.                 Name := Bez;  BezType := SavSp;
  282.                 Next := ForwDeclType;  Klass := TypeClass
  283.               END;
  284.               ForwDeclType := locc
  285.             END
  286.             ELSE BEGIN
  287.               IF locc^.BezType <> NIL THEN
  288.                 IF locc^.BEZTYPE^.Form=Files THEN Error(108)
  289.                 ELSE SavSp^.ElType := locc^.BezType
  290.             END;
  291.             GetSymbol;
  292.           END
  293.           ELSE Error(2);
  294.         END
  295.         ELSE BEGIN
  296.           IF Symb = PackedSymb THEN BEGIN
  297.             GetSymbol;
  298.             IF NOT (Symb IN TypeDels) THEN BEGIN
  299.               Error(10);  Recover(ESets+TypeDels)
  300.             END
  301.           END;
  302.           IF Symb = ArraySymb THEN BEGIN
  303.             GetSymbol;
  304.             IF Symb=lBrack THEN GetSymbol ELSE Error(11);
  305.             SavSP1 := NIL;
  306.             REPEAT
  307.               New(SavSp);
  308.               WITH SavSp^ DO BEGIN
  309.                 ElemType := SavSP1;  IndexType := NIL;  Form := Arrays
  310.               END;
  311.               SavSP1 := SavSp;
  312.               SimpleType(ESets+[CommaSymb,rBrack,OfSymb],SavSP2,ActSize);
  313.               SavSP1^.Size := ActSize;
  314.               IF SavSP2 <> NIL THEN
  315.                 IF SAVSP2^.Form <= SubRange THEN BEGIN
  316.                   IF SavSP2 = RealPtr THEN BEGIN
  317.                     Error(109);  SavSP2 := NIL
  318.                   END
  319.                   ELSE IF SavSP2 = IntPtr THEN BEGIN
  320.                     Error(149);  SavSP2 := NIL
  321.                   END;
  322.                   SavSp^.IndexType := SavSP2
  323.                 END
  324.                 ELSE BEGIN
  325.                   Error(113);  SavSP2 := NIL
  326.                 END;
  327.                 Stop := Symb <> CommaSymb;
  328.                 IF NOT Stop THEN GetSymbol
  329.             UNTIL Stop;
  330.             IF Symb = rBrack THEN GetSymbol ELSE Error(12);
  331.             IF Symb = OfSymb THEN GetSymbol ELSE Error(8);
  332.             Typ(ESets,SavSp,ActSize,Stop);
  333.             REPEAT
  334.               WITH SavSP1^ DO BEGIN
  335.                 SavSP2 := ElemType;  ElemType := SavSp;
  336.                 IF IndexType <> NIL THEN BEGIN
  337.                   GetBounds(IndexType,LMIN,LMAX);
  338.                   ActSize := ActSize*(LMAX-LMIN+1);
  339.                   Size := ActSize
  340.                 END
  341.               END;
  342.               SavSp := SavSP1;  SavSP1 := SavSP2
  343.             UNTIL SavSP1 = NIL
  344.           END
  345.           ELSE IF Symb = RecordSymb THEN BEGIN
  346.             GetSymbol;
  347.             OldDispIndex := DispTop;
  348.             IF DispTop < MaxDispVec THEN BEGIN
  349.               DispTop := DispTop+1;
  350.               WITH DispVec[DispTop] DO BEGIN
  351.                 FirstDeclID := NIL;
  352.                 FirstLab := NIL;
  353.                 OccursIn := InRec
  354.               END
  355.             END
  356.             ELSE Error(250);
  357.             OffS := 0;
  358.             FieldList(ESets-[Semicolon]+[EndSymb],SavSP1,Stop,OffS);
  359.             New(SavSp);
  360.             WITH SavSp^ DO BEGIN
  361.               FirstField := DispVec[DispTop].FirstDeclID;
  362.               RecVar := SavSP1;  Size := OffS;  Form := Records
  363.             END;
  364.             DispTop := OldDispIndex;
  365.             IF Symb = EndSymb THEN GetSymbol ELSE Error(13)
  366.           END
  367.           ELSE IF Symb = SetSymb THEN BEGIN
  368.             GetSymbol;
  369.             IF Symb = OfSymb THEN GetSymbol ELSE Error(8);
  370.             SimpleType(ESets,SavSP1,ActSize);
  371.             IF SavSP1 <> NIL THEN
  372.               IF SavSP1^.Form > SubRange THEN BEGIN
  373.                 Error(115);  SavSP1 := NIL
  374.               END
  375.               ELSE IF SavSP1 = RealPtr THEN BEGIN
  376.                 Error(114);  SavSP1 := NIL
  377.               END
  378.               ELSE IF SavSP1 = IntPtr THEN BEGIN
  379.                 Error(169);  SavSP1 := NIL
  380.               END
  381.               ELSE BEGIN
  382.                 GetBounds(SavSP1,LMIN,LMAX);
  383.                 IF (LMIN < SetMin) OR (LMAX > SetMax) THEN Error(169);
  384.               END;
  385.             New(SavSp);
  386.             WITH SavSp^ DO BEGIN
  387.               ElemSet := SavSP1;  Size := SetSize;  Form := Power
  388.             END;
  389.           END
  390.           ELSE IF Symb = FileSymb THEN BEGIN
  391.             GetSymbol;
  392.             IF Symb = OfSymb THEN GetSymbol ELSE Error(8);
  393.             Typ(ESets,SavSP1,ActSize,Stop);
  394.             IF IsFileOfFile(SavSP1) THEN BEGIN
  395.               Error(108);  Recover(ESets);  SavSp := NIL
  396.             END
  397.             ELSE BEGIN
  398.               New(SavSp);
  399.               WITH SavSp^ DO BEGIN
  400.                 FileType := SavSP1;
  401.                 Size := SavSP1^.Size+1;  Form := Files
  402.               END;
  403.             END;
  404.           END;
  405.           St := SavSp
  406.         END;
  407.         IF NOT (Symb IN ESets) THEN BEGIN
  408.           Error(6);  Recover(ESets)
  409.         END
  410.       END
  411.       ELSE St := NIL;
  412.       IF St = NIL THEN SizeOfT := 1 ELSE SizeOfT := ST^.Size;
  413.     END; (* Typ *)
  414.  
  415.  
  416.     PROCEDURE LabelDeclaration (VAR Stop: BOOLEAN; VAR ESets: Symbolmenge);
  417.  
  418.     VAR ActLab: LabPointer;  MultDeclLab: BOOLEAN;  LabName:INTEGER;
  419.  
  420.     BEGIN
  421.       REPEAT
  422.         IF Symb = IntConst THEN
  423.           WITH DispVec[DispTop] DO BEGIN
  424.             ActLab := FirstLab;  MultDeclLab := FALSE;
  425.             WHILE (ActLab <> NIL) AND NOT MultDeclLab DO
  426.               IF ActLab^.LabValue <> LastConstVal.GanzeZahl THEN
  427.                 ActLab := ActLab^.NextLab
  428.               ELSE BEGIN
  429.                 MultDeclLab := TRUE;  Error(166)
  430.               END;
  431.             IF NOT MultDeclLab THEN BEGIN
  432.               New(ActLab);
  433.               WITH ActLab^ DO BEGIN
  434.                 LabValue := LastConstVal.GanzeZahl;  GLab(LabName);
  435.                 Defined := FALSE;  NextLab := FirstLab;  LabName := LabName
  436.               END;
  437.               FirstLab := ActLab
  438.             END;
  439.             GetSymbol
  440.           END
  441.         ELSE Error(15);
  442.         IF NOT (Symb IN ESets+[CommaSymb,Semicolon]) THEN BEGIN
  443.           Error(6);  Recover(ESets+[CommaSymb,Semicolon])
  444.         END;
  445.         Stop := Symb <> CommaSymb;
  446.         IF NOT Stop THEN GetSymbol
  447.       UNTIL Stop;
  448.       IF Symb = Semicolon THEN GetSymbol ELSE Error(14);
  449.     END; (* LabelDeclaration *)
  450.  
  451.  
  452.     PROCEDURE ConstDeclaration (VAR ESets: Symbolmenge);
  453.  
  454.     VAR locc: KonstP;  SavSp: StP;  SavValu: Value;
  455.  
  456.     BEGIN
  457.       IF Symb <> Bezeich THEN BEGIN
  458.         Error(2);  Recover(ESets+[Bezeich])
  459.       END;
  460.       WHILE Symb = Bezeich DO BEGIN
  461.         New(locc);
  462.         WITH locc^ DO BEGIN
  463.           Name := Bez;  BezType := NIL;  Next := NIL;  Klass := KonstKlasse
  464.         END;
  465.         GetSymbol;
  466.         IF (Symb = VergleichOp) AND (Oper = EqualOp) THEN GetSymbol
  467.         ELSE Error(16);
  468.         GConstant(ESets+[Semicolon],SavSp,SavValu);
  469.         InsertId(locc);
  470.         locc^.BezType := SavSp;  locc^.Values := SavValu;
  471.         IF Symb = Semicolon THEN BEGIN
  472.           GetSymbol;
  473.           IF NOT (Symb IN ESets+[Bezeich]) THEN BEGIN
  474.             Error(6);  Recover(ESets+[Bezeich])
  475.           END
  476.         END
  477.         ELSE Error(14)
  478.       END;
  479.     END; (* ConstDeclaration *)
  480.  
  481.  
  482.     PROCEDURE TypeDeclaration (VAR Stop: BOOLEAN; VAR ESets: Symbolmenge);
  483.  
  484.     VAR
  485.       locc,locc1,Locc2: KonstP;
  486.       SavSp: StP;
  487.       ActSize: AddressRange;
  488.  
  489.     BEGIN
  490.       IF Symb <> Bezeich THEN BEGIN
  491.         Error(2);  Recover(ESets+[Bezeich])
  492.       END;
  493.       WHILE Symb = Bezeich DO BEGIN
  494.         New(locc);
  495.         WITH locc^ DO BEGIN
  496.           Name := Bez;  BezType := NIL;  Klass := TypeClass
  497.         END;
  498.         GetSymbol;
  499.         IF (Symb = VergleichOp) AND (Oper = EqualOp) THEN GetSymbol
  500.         ELSE Error(16);
  501.         Typ(ESets+[Semicolon],SavSp,ActSize,Stop);
  502.         InsertId(locc);
  503.         locc^.BezType := SavSp;
  504.         locc1 := ForwDeclType;
  505.         WHILE locc1 <> NIL DO BEGIN
  506.           IF locc1^.Name=locc^.Name THEN BEGIN
  507.             locc1^.BEZTYPE^.ElType := locc^.BezType;
  508.             IF locc1 <> ForwDeclType THEN locc2^.Next := locc1^.Next
  509.             ELSE ForwDeclType := locc1^.Next
  510.           END
  511.           ELSE Locc2 := locc1;
  512.           locc1 := locc1^.Next
  513.         END;
  514.         IF Symb = Semicolon THEN BEGIN
  515.           GetSymbol;
  516.           IF NOT (Symb IN ESets+[Bezeich]) THEN BEGIN
  517.             Error(6);  Recover(ESets+[Bezeich])
  518.           END
  519.         END
  520.         ELSE Error(14)
  521.       END;
  522.       IF ForwDeclType <> NIL THEN Error(117);
  523.     END; (* TypeDeclaration *)
  524.  
  525.  
  526.     PROCEDURE VarDeclaration (VAR Stop: BOOLEAN; VAR ESets: Symbolmenge);
  527.  
  528.     VAR locc,Nxt: KonstP;  SavSp: StP;  ActSize: AddressRange;
  529.  
  530.     BEGIN
  531.       Nxt := NIL;
  532.       REPEAT
  533.         REPEAT
  534.           IF Symb = Bezeich THEN BEGIN
  535.             New(locc);
  536.             WITH locc^ DO BEGIN
  537.               Name := Bez;  Next := Nxt;  Klass := VarClass;
  538.               BezType := NIL;  VarKind := Actual;  VarsBSt := Bst
  539.             END;
  540.             InsertId(locc);
  541.             Nxt := locc;
  542.             GetSymbol;
  543.           END
  544.           ELSE Error(2);
  545.           IF NOT (Symb IN ESets+[CommaSymb,ColonSymb]+TypeDels) THEN BEGIN
  546.             Error(6);
  547.             Recover(ESets+[CommaSymb,ColonSymb,Semicolon]+TypeDels)
  548.           END;
  549.           Stop := Symb <> CommaSymb;
  550.           IF NOT Stop THEN GetSymbol
  551.         UNTIL Stop;
  552.         IF Symb = ColonSymb THEN GetSymbol ELSE Error(5);
  553.         Typ(ESets+[Semicolon]+TypeDels,SavSp,ActSize,Stop);
  554.         WHILE Nxt <> NIL DO
  555.           WITH Nxt^ DO BEGIN
  556.             BezType := SavSp;  VarAddr := LocStk;  LocStk := LocStk+ActSize;
  557.             IF SavSp^.Form=Files THEN BEGIN
  558.               NoOfFiles := NoOfFiles+1;
  559.               IF NoOfFiles>MaxFiles THEN BEGIN
  560.                 Error(258);  Next := NIL
  561.               END;
  562.             END;
  563.             Nxt := Next
  564.           END;
  565.         IF Symb = Semicolon THEN BEGIN
  566.           GetSymbol;
  567.           IF NOT (Symb IN ESets+[Bezeich]) THEN BEGIN
  568.             Error(6);  Recover(ESets+[Bezeich])
  569.           END
  570.         END
  571.         ELSE Error(14)
  572.       UNTIL (Symb <> Bezeich) AND NOT (Symb IN TypeDels);
  573.       IF ForwDeclType <> NIL THEN Error(117);
  574.     END; (* VarDeclaration *)
  575.  
  576.  
  577.     PROCEDURE Anbindung (VAR locc: KonstP);
  578.     BEGIN
  579.       WITH locc^ DO BEGIN
  580.         Extern := TRUE;
  581.         CASE Symb OF
  582.           GemDosSy : ProcLabel := 24;
  583.           BiosSy   : ProcLabel := 25;
  584.           XBiosSy  : ProcLabel := 26;
  585.           VdiAesSy : ProcLabel := 27;
  586.         END;
  587.         GetSymbol;
  588.         IF Symb = lBraces THEN GetSymbol ELSE Error(9);
  589.         IF Symb = IntConst THEN Zahl := LastConstVal.GanzeZahl
  590.         ELSE Error(15);
  591.         GetSymbol;
  592.         IF Symb <> rBrace THEN Error(4);
  593.       END;
  594.     END; (* Anbindung *)
  595.  
  596.  
  597.     PROCEDURE ProcDeclaration (ESet: Symbol;
  598.                                VAR Stop: BOOLEAN;
  599.                                VAR ESets: Symbolmenge);
  600.  
  601.     VAR oldBSt: 0..MaxBSt;
  602.         LastSymb: Symbol;
  603.         locc, locc1: KonstP;
  604.         SavSP: StP;
  605.         isForward: BOOLEAN;
  606.         oldDispIndex: DispRange;
  607.         ParCnt: INTEGER;
  608.         SavLocStk, TempLC: AddressRange;
  609.         LabName: INTEGER;
  610.         MarkP: ^INTEGER;
  611.  
  612.  
  613.       PROCEDURE ParameterList (ESet: Symbolmenge;
  614.                                VAR Paramlist: KonstP;
  615.                                VAR Stop: BOOLEAN;
  616.                                VAR ESets: Symbolmenge;
  617.                                VAR isForward: BOOLEAN);
  618.   
  619.       VAR locc, locc1, locc2, locc3: KonstP;
  620.           SavSp: StP;
  621.           LBezArt: BezArt;
  622.           SavLocStk: AddressRange;
  623.           NoOfParams, ActSize: INTEGER;
  624.   
  625.       BEGIN
  626.         locc1 := NIL;
  627.         IF NOT (Symb IN ESet+[lBraces]) THEN BEGIN
  628.           Error(7);  Recover(ESets+ESet+[lBraces])
  629.         END;
  630.         IF Symb = lBraces THEN BEGIN
  631.           IF isForward THEN Error(119);
  632.           GetSymbol;
  633.           IF NOT (Symb IN [Bezeich,VarSymb,ProcSymb,FuncSymb]) THEN BEGIN
  634.             Error(7); Recover(ESets+[Bezeich,rBrace])
  635.           END;
  636.           WHILE Symb IN [Bezeich,VarSymb,ProcSymb,FuncSymb] DO BEGIN
  637.             IF Symb = ProcSymb THEN BEGIN
  638.               Error(399);
  639.               REPEAT
  640.                 GetSymbol;
  641.                 IF Symb = Bezeich THEN BEGIN
  642.                   New(locc);
  643.                   WITH locc^ DO BEGIN
  644.                     Name := Bez;  BezType := NIL;  Next := locc1;
  645.                     ProcBSt := Bst;  Klass := ProcClass;
  646.                     IsDecldAs := Declared;  IsKind := Formal;
  647.                   END;
  648.                   InsertID(locc);
  649.                   locc1:=locc;
  650.                   GetSymbol;
  651.                 END
  652.                 ELSE Error(2);
  653.                 IF NOT (Symb IN ESets+[CommaSymb,Semicolon,rBrace]) THEN BEGIN
  654.                   Error(7);  Recover(ESets+[CommaSymb,Semicolon,rBrace]);
  655.                 END;
  656.               UNTIL Symb <> CommaSymb;
  657.             END
  658.             ELSE BEGIN
  659.               IF Symb = FuncSymb THEN BEGIN
  660.                 Error(399);  locc2 := NIL;
  661.                 REPEAT
  662.                   GetSymbol;
  663.                   IF Symb = Bezeich THEN BEGIN
  664.                     New(locc);
  665.                     WITH locc^ DO BEGIN
  666.                       Name := Bez;  BezType := NIL;  Next := locc2;
  667.                       ProcBSt := Bst;  Klass := FuncClass;
  668.                       IsDecldAs := Declared;  IsKind := Formal;
  669.                     END;
  670.                     InsertID(locc);  locc2 := locc;  GetSymbol;
  671.                   END;
  672.                   IF NOT (Symb IN [CommaSymb,ColonSymb]+ESets) THEN BEGIN
  673.                     Error(7);  Recover(ESets+[CommaSymb,Semicolon,rBrace])
  674.                   END
  675.                 UNTIL Symb<>CommaSymb;
  676.                 IF Symb = ColonSymb THEN BEGIN
  677.                   GetSymbol;
  678.                   IF Symb = Bezeich THEN BEGIN
  679.                     FindeBez([TypeClass],locc);  SavSp := locc^.BezType;
  680.                     IF SavSp <> NIL THEN
  681.                       IF NOT(SavSp^.Form IN [Scalar,SubRange,Pointers]) THEN BEGIN
  682.                         Error(120);  SavSp := NIL
  683.                       END;
  684.                     locc3 := locc2;
  685.                     WHILE locc2 <> NIL DO BEGIN
  686.                       locc2^.BezType := SavSp;  locc := locc2;
  687.                       locc2 := locc2^.Next
  688.                     END;
  689.                     locc^.Next := locc1;  locc1 := locc3;
  690.                     GetSymbol;
  691.                   END
  692.                   ELSE Error(2);
  693.                   IF NOT (Symb IN ESets+[Semicolon,rBrace]) THEN BEGIN
  694.                     Error(7);  Recover(ESets+[Semicolon,rBrace])
  695.                   END
  696.                 END
  697.                 ELSE Error(5)
  698.               END (* Symb = FuncSymb *)
  699.               ELSE BEGIN
  700.                 IF Symb = VarSymb THEN BEGIN
  701.                   LBezArt := Formal;  GetSymbol
  702.                 END
  703.                 ELSE LBezArt := Actual;
  704.                 locc2 := NIL;  NoOfParams := 0;
  705.                 REPEAT
  706.                   IF Symb = Bezeich THEN BEGIN
  707.                     New(locc);
  708.                     WITH locc^ DO BEGIN
  709.                       Name := Bez;  BezType := NIL;  Klass := VarClass;
  710.                       VarKind := LBezArt;  Next := locc2;  VarsBSt := Bst;
  711.                     END;
  712.                     InsertID(locc);
  713.                     locc2 := locc;  NoOfParams := NoOfParams+1;  GetSymbol;
  714.                   END;
  715.                   IF NOT (Symb IN [CommaSymb,ColonSymb]+ESets) THEN BEGIN
  716.                     Error(7);  Recover(ESets+[CommaSymb,Semicolon,rBrace])
  717.                   END;
  718.                   Stop := Symb <> CommaSymb;
  719.                   IF NOT Stop THEN GetSymbol;
  720.                 UNTIL Stop;
  721.                 IF Symb = ColonSymb THEN BEGIN
  722.                   GetSymbol;
  723.                   IF Symb = Bezeich THEN BEGIN
  724.                     FindeBez([TypeClass],locc);
  725.                     SavSp := locc^.BezType;
  726.                     ActSize := PtrSize;
  727.                     IF SavSp <> NIL THEN
  728.                       IF LBezArt = Actual THEN
  729.                         IF SavSp^.Form <= Power THEN ActSize := SavSp^.Size
  730.                         ELSE IF SavSp^.Form = Files THEN Error(121);
  731.                     locc3 := locc2;
  732.                     LocStk := LocStk + NoOfParams * ActSize;
  733.                     SavLocStk := LocStk;
  734.                     WHILE locc2<>NIL DO BEGIN
  735.                       locc := locc2;
  736.                       WITH locc2^ DO BEGIN
  737.                         BezType := SavSp;
  738.                         SavLocStk := SavLocStk-ActSize;
  739.                         VarAddr := SavLocStk;
  740.                       END;
  741.                       locc2 := locc2^.Next
  742.                     END;
  743.                     locc^.Next := locc1;  locc1 := locc3;
  744.                     GetSymbol
  745.                   END
  746.                   ELSE Error(2);
  747.                   IF NOT (Symb IN ESets+[Semicolon,rBrace]) THEN BEGIN
  748.                     Error(7); Recover(ESets+[Semicolon,rBrace])
  749.                   END
  750.                 END
  751.                 ELSE Error(5);
  752.               END
  753.             END;
  754.             IF Symb = Semicolon THEN BEGIN
  755.               GetSymbol;
  756.               IF NOT (Symb IN ESets+[Bezeich,VarSymb,ProcSymb,FuncSymb]) THEN BEGIN
  757.                 Error(7); Recover(ESets+[Bezeich,rBrace])
  758.               END
  759.             END
  760.           END;
  761.           IF Symb = rBrace THEN BEGIN
  762.             GetSymbol;
  763.             IF NOT (Symb IN ESet+ESets) THEN BEGIN
  764.               Error(6); Recover(ESet+ESets)
  765.             END
  766.           END
  767.           ELSE Error(4);
  768.           locc3 := NIL;
  769.           WHILE locc1<>NIL DO
  770.             WITH locc1^ DO BEGIN
  771.               locc2 := Next;  Next := locc3;
  772.               IF Klass = VarClass THEN
  773.                 IF BezType <> NIL THEN
  774.                   IF (VarKind = Actual) AND (BezType^.Form > Power) THEN BEGIN
  775.                     VarAddr := LocStk;
  776.                     LocStk := LocStk + BezType^.Size;
  777.                   END;
  778.               locc3 := locc1;  locc1 := locc2;
  779.             END;
  780.             Paramlist := locc3
  781.           END
  782.         ELSE Paramlist := NIL;
  783.       END; (* ParameterList *)
  784.  
  785.   
  786.     BEGIN (* ProcDeclaration *)
  787.       SavLocStk := LocStk;  LocStk := VirginLocStk;  isForward := FALSE;
  788.       IF Symb = Bezeich THEN BEGIN
  789.         FindRecFields(DispVec[DispTop].FirstDeclID,locc);
  790.         IF locc <> NIL THEN BEGIN
  791.           IF locc^.Klass = ProcClass THEN
  792.             isForward := locc^.IsForwDecl AND (ESet = ProcSymb)
  793.                                           AND (locc^.IsKind = Actual)
  794.           ELSE IF locc^.Klass = FuncClass THEN
  795.             isForward := locc^.IsForwDecl AND (ESet = FuncSymb)
  796.                                           AND (locc^.IsKind = Actual)
  797.           ELSE isForward := FALSE;
  798.           IF NOT isForward THEN Error(160)
  799.         END;
  800.         IF NOT isForward THEN BEGIN
  801.           IF ESet = ProcSymb THEN New(locc)
  802.           ELSE New(locc);
  803.           WITH locc^ DO BEGIN
  804.             Name := Bez;  BezType := NIL;
  805.             Extern := FALSE;  ProcBSt := Bst;  GLab(LabName);
  806.             IsDecldAs := Declared;  IsKind := Actual;  ProcLabel := LabName;
  807.             IF ESet = ProcSymb THEN Klass := ProcClass
  808.             ELSE Klass := FuncClass
  809.           END;
  810.           InsertId(locc)
  811.         END
  812.         ELSE BEGIN
  813.           locc1 := locc^.Next;
  814.           WHILE locc1 <> NIL DO BEGIN
  815.             WITH locc1^ DO
  816.              IF Klass = VarClass THEN
  817.                IF BezType <> NIL THEN BEGIN
  818.                  TempLC := VarAddr+BezType^.Size;
  819.                  IF TempLC > LocStk THEN LocStk := TempLC
  820.                END;
  821.             locc1 := locc1^.Next
  822.           END
  823.         END;
  824.         GetSymbol
  825.       END
  826.       ELSE BEGIN
  827.         Error(2);  locc := UFctPtr
  828.       END;
  829.       oldBSt := Bst;  oldDispIndex := DispTop;
  830.       IF Bst < MaxBSt THEN Bst := Bst+1 ELSE Error(251);
  831.       IF DispTop < MaxDispVec THEN BEGIN
  832.         DispTop := DispTop+1;
  833.         WITH DispVec[DispTop] DO BEGIN
  834.           IF isForward THEN FirstDeclID := locc^.Next
  835.           ELSE FirstDeclID := NIL;
  836.           FirstLab := NIL;
  837.           OccursIn := IsBlock
  838.         END
  839.       END
  840.       ELSE Error(250);
  841.       IF ESet = ProcSymb THEN BEGIN
  842.         ParameterList([Semicolon],locc1,Stop,ESets,isForward);
  843.         IF NOT isForward THEN locc^.Next := locc1
  844.       END
  845.       ELSE BEGIN
  846.         ParameterList([Semicolon,ColonSymb],locc1,Stop,ESets,isForward);
  847.         IF NOT isForward THEN locc^.Next := locc1;
  848.         IF Symb = ColonSymb THEN BEGIN
  849.           GetSymbol;
  850.           IF Symb = Bezeich THEN BEGIN
  851.             IF isForward THEN Error(122);
  852.             FindeBez([TypeClass],locc1);
  853.             SavSP := locc1^.BezType;
  854.             locc^.BezType := SavSP;
  855.             IF SavSP <> NIL THEN
  856.               IF NOT (SavSP^.Form IN [Scalar,SubRange,Pointers]) THEN BEGIN
  857.                 Error(120);  locc^.BezType := NIL
  858.               END;
  859.             GetSymbol
  860.           END
  861.           ELSE BEGIN
  862.             Error(2); Recover(ESets+[Semicolon])
  863.           END
  864.         END
  865.         ELSE IF NOT isForward THEN Error(123)
  866.       END;
  867.       IF Symb = Semicolon THEN GetSymbol ELSE Error(14);
  868.       IF Symb IN [ForwardSymb,GemDosSy,BiosSy,XBiosSy,VdiAesSy] THEN BEGIN
  869.         IF isForward THEN Error(161)
  870.         ELSE locc^.IsForwDecl := TRUE;
  871.         IF Symb <> ForwardSymb THEN Anbindung(locc);
  872.         GetSymbol;
  873.         IF Symb = Semicolon THEN GetSymbol ELSE Error(14);
  874.         IF NOT (Symb IN ESets) THEN BEGIN
  875.           Error(6);  Recover(ESets)
  876.         END
  877.       END
  878.       ELSE BEGIN
  879.         locc^.IsForwDecl := FALSE;  Mark(MarkP);
  880.         REPEAT
  881.           Block(ESets,Semicolon,locc);
  882.           IF Symb = Semicolon THEN BEGIN
  883.             GetSymbol;
  884.             IF NOT (Symb IN [BeginSymb,ProcSymb,FuncSymb]) THEN BEGIN
  885.               Error(6);  Recover(ESets)
  886.             END
  887.           END
  888.           ELSE Error(14)
  889.         UNTIL (Symb IN [BeginSymb,ProcSymb,FuncSymb]) OR Eof(Source);
  890.         Release(MarkP);
  891.       END;
  892.       Bst := oldBSt;  DispTop := oldDispIndex;  LocStk := SavLocStk;
  893.     END; (* ProcDeclaration *)
  894.