(*==============================================*) (* 12.9.1986 *) (* INCLUDE-FILE "P.EXPRESSION.P" *) (*==============================================*) (* DIE FOLGENDEN FUNKTIONEN KOMPILIEREN EINEN *) (* (TEIL-)AUSDRUCK UND LIEFERN EINEN TYPINDEX *) (* ALS FUNKTIONSERGEBNIS. *) FUNCTION EXPRESSION; VAR T1,T2,OPSYM,KOMP1:INTEGER; PROCEDURE DYADIC (VAR TYP1:INTEGER;TYP2:INTEGER); (* OBJEKT MIT TYP2 IST DAS OBERSTE STACKELEMENT*) (* OBJEKT MIT TYP1 IST DAS ZWEITE STACKELEMENT*) (* ANGLEICH INTEGER<->REAL BEI BEDARF. *) (* TYP1 BEIM AUFRUF INTEGER/REAL. BEI RUECK- *) (* KEHR GLEICH DEM ERGEBNISTYP (INTEGER / REAL)*) BEGIN IF (TYP1=REALS) OR (TYP2=REALS) THEN BEGIN TYPTEST(TYP2,REALS,129); IF TYP1<>REALS THEN BEGIN TYPTEST(TYP1,INT,129); (* FUER FEHLERMELD.*) GEN(FLOSYM); TYP1:=REALS END END ELSE TYPTEST (TYP2,TYP1,129) END; (* DYADIC *) PROCEDURE TESTSETS (KOMP1,T2:INTEGER); (* VERKNUEPFUNG DER MENGE 'SET OF KOMP1' MIT *) (* T2 TYP DER ERGEBNISMENGE IN TABA2[SETT] *) BEGIN IF T2<>SETT THEN ERROR(129) ELSE BEGIN EXPAND(TABA2[SETT]); EXPAND(KOMP1); IF KOMP1<>TABA2[SETT] THEN BEGIN (* AUSNAHME: LEERE MENGE *) IF TABA2[SETT]<0 THEN TABA2[SETT]:=KOMP1 ELSE IF KOMP1>=0 THEN ERROR(129) END END END;(* TESTSETS *) PROCEDURE TESTELEM (VAR ET:INTEGER); (* PRUEFE ET AUF KORREKTEN TYP FUER MENGEN- *) (* AUFBAU. EVTL. LAUFZEITTEST KOMPILIEREN, *) (* DAHER MUSS OBJEKT AUF DEM STACK LIEGEN! *) BEGIN IF ISLONG(ET) THEN ERROR(136); EXPAND(ET); IF TSTFLG THEN BEGIN GEN(TSTSYM); GENA(0); GENA(SETSIZE) END; END; (* TESTELEM *) FUNCTION SMPLEXP:INTEGER; VAR T1,T2,OPSYM,KOMP1:INTEGER; FUNCTION TERM:INTEGER; VAR T1,T2,OPSYM,KOMP1:INTEGER; FUNCTION FACTOR:INTEGER; VAR I,J:INTEGER; ART:TART; V :VARDESCRIPTOR; PROCEDURE GENSET; (* INNERHALB EINES FAKTORS WURDE '[' GELESEN *) (* AUFBAU EINER KOMPLETTEN MENGE AUF DEM *) (* STACK. TYPBESCHREIBUNG IN TAB..[SETT] *) VAR EMPTY :BOOLEAN; X,SETTYP:INTEGER; BEGIN EMPTY:=TRUE; GETSYM; IF SYM<>EKLZU THEN REPEAT IF NOT EMPTY THEN GETSYM; X:=EXPRESSION; TESTELEM(X); IF EMPTY THEN SETTYP:=X ELSE TYPTEST(X,SETTYP,137); IF SYM=174 (*..*) THEN BEGIN GETSYM; X:=EXPRESSION; TESTELEM(X); TYPTEST(X,SETTYP,137); GEN(GS2SYM) END ELSE GEN(GS1SYM); IF NOT EMPTY THEN GEN(UNISYM); EMPTY:=FALSE UNTIL SYM<>KOMMA ELSE BEGIN SETTYP:=-1; GEN(NULSYM) END; TEST(EKLZU,12); TABA2[SETT]:=SETTYP END; (* GENSET *) BEGIN (* FACTOR *) CASE SYM OF IDENT:BEGIN I:=POSITION(ID); IF I<0 THEN ART:=VARBLE ELSE ART:=TABART[I]; CASE ART OF VARBLE,SELECT: BEGIN VARIABLE(I,V); I:=V.VTYP; IF INTEST(I,FELDTYP,SEQTYP) THEN BEGIN GENF(V); (* ADRESSE HOLEN *) IF TABART[I]=MENGE THEN BEGIN (* MENGEN SOFORT LADEN *) GEN(LSASYM); TABA1[SETT]:=TABA1[I]; TABA2[SETT]:=TABA2[I]; I:=SETT END END ELSE (*STDTYP,AUFZHL,AUSSCH,ZEIGTYP*) CASE MEMLEN(I) OF 2: GENLS(LSYM ,V); 1: GENLS(LBSYM,V); 5: GENLS(LRSYM,V); END; (* CASE *) FACTOR:=I; END; (* VARIABLE *) FKT: BEGIN GETSYM; FACTOR:=CALL(I) END; PROZ: BEGIN ERROR(103); GETSYM; FACTOR:=CALL(I); END; KONST: BEGIN I:=UNSCONST(TRUE); IF SYM=EKLAUF THEN BEGIN IF TABART[I]<>STRTYP THEN ERROR(138); GETSYM; J:= EXPRESSION; TYPTEST(J,INT,139); IF TSTFLG THEN BEGIN GEN(TSTSYM); GENA(0); GENA(TABA1[I]-1) END; GEN(ADUSYM); GEN(LBSYM+3); FACTOR:=CHART; TEST(EKLZU,12); END ELSE FACTOR:=I; END ELSE BEGIN (* TYPBINDUNG *) GETSYM; FACTOR:=I; TEST(KLAUF,9); I:= EXPRESSION; TEST(KLZU,4); END END;(*CASE*) END; KLAUF:BEGIN GETSYM; FACTOR:=EXPRESSION;TEST(KLZU,4) END; 148: BEGIN (* NOT *) GETSYM; I:=FACTOR; IF I=BOOL THEN GEN(INVSYM) ELSE BEGIN TYPTEST(I,INT,502); GEN(NOTSYM) END; FACTOR:=I END; EKLAUF:BEGIN GENSET; FACTOR:=SETT END; ELSE (* CASE *) FACTOR:=UNSCONST(TRUE) END (* CASE *) END; (* FACTOR *) BEGIN (* TERM *) T1:=FACTOR; WHILE(SYM=STERN) OR (SYM=133) OR (SYM=QUER) OR(SYM=146) OR (SYM=128) DO BEGIN OPSYM:=SYM; GETSYM; CASE OPSYM OF 128: (* AND *) BEGIN IF T1<>BOOL THEN TYPTEST(T1,INT,502); T2:=FACTOR; IF T2<>BOOL THEN TYPTEST(T2,INT,502); IF T1<>T2 THEN ERROR(129); GENOP(OPSYM) END; 133,146: (* DIV,MOD *) BEGIN TYPTEST(T1,INT,500); T2:=FACTOR; TYPTEST(T2,INT,500); GENOP(OPSYM) END; QUER: (* / *) BEGIN TYPTEST(T1,REALS,134); T2:=FACTOR; TYPTEST(T2,REALS,134); GENROP(3) END; STERN: BEGIN IF T1=SETT THEN BEGIN KOMP1:=TABA2[SETT]; T2:=FACTOR; TESTSETS(KOMP1,T2); GEN(ISCSYM) END ELSE BEGIN IF T1<>REALS THEN TYPTEST(T1,INT,134); T2:=FACTOR; DYADIC(T1,T2); IF T1=REALS THEN GENROP(2) ELSE GENOP(OPSYM) END END END (* CASE *) END; (* WHILE *) TERM:=T1 END;(* TERM *) BEGIN (* SMPLEXP *) IF (SYM=PLUS) OR (SYM=MINUS) THEN BEGIN OPSYM:=SYM; GETSYM; T1:=TERM; IF T1=REALS THEN BEGIN IF OPSYM=MINUS THEN GENROP(5) END ELSE BEGIN TYPTEST(T1,INT,105); IF OPSYM=MINUS THEN GEN(CHSSYM) END END ELSE T1:= TERM; WHILE (SYM=PLUS) OR (SYM=MINUS) OR (SYM=150) DO BEGIN OPSYM:=SYM; GETSYM; IF OPSYM=150 (* OR *) THEN BEGIN IF T1<>BOOL THEN TYPTEST(T1,INT,502); T2:=TERM; IF T2<>BOOL THEN TYPTEST(T2,INT,502); IF T1<>T2 THEN ERROR(129); GENOP(OPSYM) END ELSE BEGIN (* + ODER - *) IF T1=SETT THEN BEGIN KOMP1:=TABA2[SETT]; T2:=TERM; TESTSETS(KOMP1,T2); IF OPSYM=PLUS THEN GEN(UNISYM) ELSE GEN(DIFSYM) END ELSE BEGIN EXPAND(T1); IF (T1=REALS) OR (T1=INT) THEN BEGIN (* SUMME / DIFFERENZ *) T2:=TERM; DYADIC(T1,T2); IF T1=REALS THEN GENROP(ORD(OPSYM=MINUS)) ELSE GENOP(OPSYM); END ELSE BEGIN (* STRINGKONKATENATION / FEHLER *) MAKESTRING(T1); T2:=TERM; MAKESTRING(T2); GEN (CCTSYM); T1:=STRNG; TABA1[STRNG]:=0; TABA2[STRNG]:=1; END; END; END; (* + ODER - *) END; (* WHILE *) SMPLEXP:=T1 END; (* SMPLEXP *) FUNCTION MASKE(OPSYM:INTEGER): INTEGER; (* BILDE 3-BIT MASKE FUER VERGLEICHSOPERATOREN *) BEGIN CASE OPSYM OF KLEINER : MASKE:=1; GLEICH : MASKE:=2; 171 : MASKE:=3; (*<=*) GROESSER : MASKE:=4; 172 : MASKE:=5; (*<>*) 173 : MASKE:=6; (*>=*) END; (* CASE *) END; (* MASKE *) BEGIN (* EXPRESSION *) T1:=SMPLEXP; CASE SYM OF GLEICH,172,171,173,GROESSER,KLEINER: BEGIN OPSYM:=SYM; GETSYM; EXPAND(T1); CASE TABART[T1] OF STDTYP,AUFZHL: BEGIN T2:=SMPLEXP; DYADIC(T1,T2); IF T1=REALS THEN BEGIN GEN(CMPSYM); GEN(MASKE(OPSYM)); END ELSE GENOP(OPSYM) END; ZEIGTYP: BEGIN T2:=SMPLEXP; IF (OPSYM<>GLEICH) AND (OPSYM<>172) THEN ERROR(131); IF TABART[T2]<>ZEIGTYP THEN BEGIN ERROR(129); T2:=T1 END; T1:=TABA2[T1]; T2:=TABA2[T2]; IF (T1<>T2) AND (T1>0) AND (T2>0) THEN ERROR(129); (* NIL BEACHTEN! *) GENOP(OPSYM); END; FELDTYP, STRTYP: BEGIN MAKESTRING(T1); T2:=SMPLEXP; MAKESTRING(T2); GEN(STRCMPSYM); GEN(MASKE(OPSYM)); END; MENGE: BEGIN KOMP1:=TABA2[T1]; T2:=SMPLEXP; TESTSETS(KOMP1,T2); CASE OPSYM OF GLEICH:GEN(SEQSYM); 172:BEGIN GEN(SEQSYM); GEN(INVSYM) END; 173:GEN(SGESYM); 171:GEN(SLESYM) ELSE ERROR(132) END;(* CASE *) END ELSE ERROR(134) END; (* CASE *) EXPRESSION:=BOOL END; (* VERGLEICHSOPERATOR *) 144: (* IN *) BEGIN TESTELEM(T1); GETSYM; T2:=SMPLEXP; IF T2<>SETT THEN ERROR(130); T2:=TABA2[SETT]; EXPAND(T2); TYPTEST(T1,T2,134); GEN(INNSYM); EXPRESSION:=BOOL END ELSE (* CASE *) EXPRESSION:=T1 END; (* CASE *) END; (* EXPRESSION *)