(*==============================================*) (* 6.8.1986 *) (* INCLUDE-FILE "P.STATEMENT.P" *) (*==============================================*) PROCEDURE STATEMENT; VAR AD1,AD2,I,X:INTEGER; ART :TART; LOOP :VARDESCRIPTOR; PROCEDURE BOOLEXP; VAR T:INTEGER; BEGIN T:=EXPRESSION; TYPTEST(T,BOOL,148) END; (* BOOLEXP *) PROCEDURE INSPECT; (* SETZT WITHIND FUER 'POSITION'. BEI NACH- *) (* FOLGENDER SUCHE NACH NAMEN WIRD ZUERST DIE *) (* SELEKTORLISTE DES INDIZIERTEN RECORDS *) (* DURCHSUCHT. WITHADR WIRD DURCH DX BESTIMMT *) VAR WITHI2,TYP2,WITH2:INTEGER; I,X :INTEGER; BEGIN WITH2:=WITHADR; WITHI2:=WITHIND; X:=DX; REPEAT GETSYM; IF SYM<>IDENT THEN ERROR(2); I:=POSITION(ID); IF (WITHIND<>0) AND (TABART[I]<>SELECT) THEN ERROR(152); VARIABLE(I,ZU); WITHIND:=ZU.VTYP; IF TABART[WITHIND]<>VERBTYP THEN BEGIN WITHIND:=0; ERROR(140) END; (* ABSOLUTE ADRESSE DES RECORDS AUF DEM *) (* STACK. (ZUGRIFF IN VARIABLE) *) GENF(ZU); WITHADR:=DX; DX:=DX+2; UNTIL SYM<>KOMMA; TEST(134 (* DO *),54); STATEMENT; REPEAT (* ADRESSE LOESCHEN, WIHIND:=ALTER WERT *) GEN(POPSYM); DX:=DX-2 UNTIL DX=X; WITHIND:=WITHI2; WITHADR:=WITH2; END; (* INSPECT *) PROCEDURE SEQUENZ (ENDSYM:INTEGER); (* ANWEISUNGSFOLGE DER FOLGENDEN FORM LESEN: *) (* SYM STATEMENT [;STATEMENT] ENDSYM *) (* ERLAUBE FEHLENDE ';'. VERLASSE SCHLEIFE, *) (* FALLS OFFENSICHTLICH ENDZEICHEN FEHLT *) VAR READY: BOOLEAN; BEGIN GETSYM; STATEMENT; READY:=FALSE; REPEAT CASE SYM OF SEMI: BEGIN GETSYM; STATEMENT END; IDENT,130,143,162,155,139,131,INTNUM,142: (* ANFANGSSYMBOLE FUER STATEMENTS: *) (* BEGIN,IF,WHILE,REPEAT,FOR,CASE,GOTO *) (* LABEL UND BEZEICHNER. *) BEGIN ERROR(14); STATEMENT END; 137,160:(* END, UNTIL *) BEGIN IF SYM<>ENDSYM THEN ERROR(175); GETSYM; READY:= TRUE; END; 145,132,159,161,141,152: (* STOPSYMBOLE AUSSERHALB DES ANW.TEILS *) (* LABEL, CONST, TYPE, VAR, FUNCTION, *) (* PROCEDURE *) BEGIN ERROR(175); READY:=TRUE END; ELSE (* CASE *) BEGIN GETSYM; ERROR(175) END END; (* CASE *) UNTIL READY; END; (* SEQUENZ *) PROCEDURE FALL; VAR I,LSYM,Z,TYP:INTEGER; TAB: ARRAY[0..MXCASE] OF INTEGER; (* KELLERSPEICHER, TABELLENZEIGER IST Z *) PROCEDURE PUSH(X:INTEGER); BEGIN IF Z>MXCASE THEN ERROR(400) ELSE BEGIN TAB[Z]:=X; Z:=Z+1 END END; (* PUSH *) BEGIN (* FALL *) Z:=0; GETSYM; TYP:=EXPRESSION; IF ISLONG(TYP) THEN ERROR(144); DX:=DX+2; TEST(149 (*OF*) ,8); LSYM:=SEMI; WHILE (SYM<>137) AND (SYM<>136) DO (* BIS 'ELSE' ODER 'END' *) IF SYM=SEMI THEN BEGIN LSYM:=SEMI; GETSYM END ELSE BEGIN IF LSYM<>SEMI THEN ERROR(14); GEN(JMCSYM); AD1:=PC; FRE; I:=0; REPEAT (* KONSTANTEN AUF DEN STACK *) CHECKCONST(TYP,147); PUSH(NUM); I:=I+1; LSYM:=SYM; GETSYM UNTIL LSYM<>KOMMA; GEN(I); (* # LABELS *) REPEAT Z:=Z-1; I:=I-1; GENA(TAB[Z]) UNTIL I=0; IF LSYM<>DPKT THEN ERROR(5); STATEMENT; GEN(JMPSYM); PUSH(PC); FRE; FIXUP(AD1,PC); LSYM:=STERN END; IF SYM=136 (*'ELSE'*) THEN REPEAT GETSYM; STATEMENT UNTIL SYM<>SEMI ELSE BEGIN GEN(ERRSYM); GEN(CASERR) END; TEST(137 (* END *) ,13); WHILE Z>0 DO BEGIN Z:=Z-1; FIXUP(TAB[Z],PC) END; GEN(POPSYM); DX:=DX-2; END; (* FALL *) BEGIN (* STATEMENT *) IF SYM=INTNUM THEN (* LABELDEFINITION *) BEGIN I:=LBLI2; WHILE (ILBL[I].VAL) DO I:=I+1; IF I0 THEN ERROR(165) ELSE BEGIN LEV:=-LEV; (* DEKLARATION VERVOLLSTAENDIGEN: *) FIXUP(ADDU(ADR,1),DX-2);(* LFD. OFFSET*) FIXUP(ADDU(ADR,4),PC); (* ZIELADRESSE*) END END ELSE ERROR(167); GETSYM; TEST(DPKT,5) END; (* LABEL *) CASE SYM OF IDENT:BEGIN I:=POSITION(ID); IF I<0 THEN ART:=VARBLE ELSE ART:=TABART[I]; CASE ART OF VARBLE,FKT,SELECT: BEGIN IF ART=FKT THEN BEGIN (* ZUWEISUNG MOEGLICH? *) ART:=VARBLE; IF I<>BLK THEN ERROR(103); I:= I+TABA2[I]+1; (* ERGEBNISVAR*) END; ZUW1(I); TEST(170,51); (* ':=' *) ZUW2(EXPRESSION); END; PROZ: BEGIN GETSYM; I:=CALL(I) (* I IST DUMMY *) END ELSE (* CASE *) BEGIN ERROR(103); GETSYM END END (* CASE *) END; (* IDENT *) 130: (* BEGIN *) SEQUENZ(137); (* END *) 143: (* IF *) BEGIN GETSYM;BOOLEXP; TEST(157,52); GEN(JNCSYM); AD1:=PC; FRE; STATEMENT; IF SYM=136 (* ELSE *) THEN BEGIN GETSYM; GEN(JMPSYM); AD2:=PC; FRE; FIXUP(AD1,PC); STATEMENT; AD1:=AD2 END; FIXUP(AD1,PC) END; 162: (* WHILE *) BEGIN GETSYM; AD1:=PC; BOOLEXP; TEST(134 (* DO *),54); GEN(JNCSYM); AD2:=PC; FRE; STATEMENT; GEN(JMPSYM); GENA(AD1); FIXUP(AD2,PC) END; 155: (* REPEAT *) BEGIN AD1:=PC; SEQUENZ(160); (* UNTIL *) BOOLEXP; GEN(JNCSYM); GENA(AD1) END; 139: (* FOR *) BEGIN GETSYM; IF SYM=IDENT THEN I:=POSITION(ID) ELSE I:=-1; VARIABLE(I,LOOP); IF LOOP.ACCESS<>BASEOFFSET THEN ERROR(155); IF ISLONG(LOOP.VTYP) THEN ERROR(143); TEST(170,51); (* BEREICHSTESTS NUR BEI DEN GRENZEN: *) X:=EXPRESSION; TYPTEST(X,LOOP.VTYP,144); IF (SYM<>158) AND (SYM<>135) (* I=RICHTUNG: TO = 1 / DOWNTO = 0 *) THEN BEGIN I:=1; ERROR(55) END ELSE BEGIN I:=ORD(SYM=158); GETSYM END; X:=EXPRESSION; TYPTEST(X,LOOP.VTYP,144); TEST(134 (* DO *), 54); DX:= DX+4; AD1:=PC; GEN(FOR1SYM); AD2:=PC; FRE; GEN(I); IF MEMLEN(LOOP.VTYP)=1 THEN GENLS(SBSYM,LOOP) ELSE GENLS(SSYM ,LOOP); STATEMENT; GEN(FOR2SYM); GENA(AD1); GEN(I); FIXUP(AD2,PC); DX:= DX-4; END; 131: (* CASE *) FALL; 163: (* WITH *) INSPECT; 142: (* GOTO *) BEGIN GETSYM; IF SYM<>INTNUM THEN ERROR(106) ELSE BEGIN I:=0; WHILE (ILBL[I].VAL) DO I:=I+1; IF I