home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1993-11-04 | 17.1 KB | 629 lines |
- (******************************
- * Programm von Dieter Seidel *
- * Eingegeben am 14.11.1991 *
- * Nach einer langen Pause *
- * fertiggestellt am 23.07.92 *
- ******************************)
-
-
- IMPLEMENTATION MODULE QuadInterpreter;
-
- FROM InOut IMPORT ReadCard, WriteCard, WriteLn, Write, WriteString;
- FROM LongInOut IMPORT WriteLongCard;
- FROM JaNein IMPORT JaNein;
- FROM QuadLese IMPORT MaxZeile, QuadZeile, arrQuad, arrList;
- FROM QuadDrucke IMPORT DruckeQuadrupel;
- FROM QuadBerechneQuad IMPORT BerechneQuad;
-
- CONST Max = 100; (* Die Variablen X[0]..X[99] sind für while-Programme *)
- (* gedacht, während X[100] für Konstanten in den *)
- (* while-Programmen sind. *)
- MaxVar = 4;
-
- VAR X : ARRAY [0..Max] OF CARDINAL;
- AnzAnweisungen : LONGCARD;
-
-
- PROCEDURE DruckeVariable(VAR X : ARRAY OF CARDINAL);
- VAR i, Anzahl : CARDINAL;
- BEGIN
- Anzahl:=0;
- FOR i:=0 TO 99 DO (* Bis Max, aber X[Max] steht für die Zahl null. *)
- IF X[i] # 0 THEN
- WriteString(" X[");WriteCard(i,2);WriteString("] : ");
- WriteCard(X[i],5);
- INC(Anzahl);
- IF Anzahl = MaxVar THEN
- WriteLn;
- Anzahl:=0;
- ELSE
- WriteString(" : ");
- END;
- END;
- END;
- IF Anzahl # 0 THEN
- WriteLn;
- END;
- END DruckeVariable;
-
-
- PROCEDURE HoleVariable( QuadListe : arrQuad;
- Zaehler : CARDINAL;
- VAR VarEins, VarZwei : CARDINAL);
- VAR i : CARDINAL;
- BEGIN
- i:=2;
- VarEins:=0;
- VarZwei:=0;
- WHILE (QuadListe[Zaehler].Befehl[i] >= "0") AND
- (QuadListe[Zaehler].Befehl[i] <= "9") AND (i <= MaxZeile) DO
- VarEins:=VarEins * 10;
- VarEins:=VarEins + ORD(QuadListe[Zaehler].Befehl[i]) - ORD("0");
- INC(i);
- END;
- IF VarEins > 99 THEN
- WriteLn;
- WriteString("Zu grosser Variablen-Index!!! ");
- DruckeQuadrupel(QuadListe[Zaehler]);
- WriteLn;
- HALT;
- END;
- WHILE NOT((QuadListe[Zaehler].Befehl[i] >= "0") AND
- (QuadListe[Zaehler].Befehl[i] <= "9")) AND
- (QuadListe[Zaehler].Befehl[i] # "X") AND
- (i <= MaxZeile) DO
- INC(i);
- END;
- IF i > MaxZeile THEN
- WriteLn;
- WriteString("Vermisse die zweite Anweisung!!!");
- DruckeQuadrupel(QuadListe[Zaehler]);
- WriteLn;
- HALT;
- END;
- IF (QuadListe[Zaehler].Befehl[i] >= "0") AND
- (QuadListe[Zaehler].Befehl[i] <= "9") THEN
- X[Max]:=0;
- WHILE (QuadListe[Zaehler].Befehl[i] >= "0") AND
- (QuadListe[Zaehler].Befehl[i] <= "9") AND (i <= MaxZeile) DO
- X[Max]:=10*X[Max];
- X[Max]:=X[Max] + ORD(QuadListe[Zaehler].Befehl[i]) - ORD("0");
- INC(i);
- END;
- VarZwei:=Max;
- ELSE
- INC(i);
- IF i > MaxZeile THEN
- WriteLn;
- WriteString("Vermisse die zweite Anweisung!!!");
- DruckeQuadrupel(QuadListe[Zaehler]);
- WriteLn;
- HALT;
- END;
- WHILE (QuadListe[Zaehler].Befehl[i] >= "0") AND
- (QuadListe[Zaehler].Befehl[i] <= "9") AND (i <= MaxZeile) DO
- VarZwei:=VarZwei * 10;
- VarZwei:=VarZwei + ORD(QuadListe[Zaehler].Befehl[i]) - ORD("0");
- INC(i);
- END;
- IF VarZwei > 99 THEN
- WriteLn;
- WriteString("Zu grosser Variablen-Index!!! ");
- DruckeQuadrupel(QuadListe[Zaehler]);
- WriteLn;
- HALT;
- END;
- END;
- END HoleVariable;
-
-
- PROCEDURE succ(Zeile : QuadZeile) : BOOLEAN;
- VAR i : CARDINAL;
- BEGIN
- FOR i:=1 TO MaxZeile DO
- IF Zeile.Befehl[i] = "s" THEN
- RETURN TRUE;
- END;
- END;
- RETURN FALSE;
- END succ;
-
-
- PROCEDURE pred(Zeile : QuadZeile) : BOOLEAN;
- VAR i : CARDINAL;
- BEGIN
- FOR i:=1 TO MaxZeile DO
- IF Zeile.Befehl[i] = "p" THEN
- RETURN TRUE;
- END;
- END;
- RETURN FALSE;
- END pred;
-
-
- PROCEDURE schleife(Zeile : QuadZeile) : BOOLEAN;
- VAR i : CARDINAL;
- BEGIN
- FOR i:=1 TO MaxZeile DO
- IF Zeile.Befehl[i] = "#" THEN
- RETURN TRUE;
- END;
- END;
- RETURN FALSE;
- END schleife;
-
-
- PROCEDURE UnterprogrammNr(Zeile : QuadZeile) : CARDINAL;
- VAR i,
- Nummer : CARDINAL;
- BEGIN
- Nummer:=0;
- i:=2;
- WHILE (Zeile.Befehl[i] >= "0") AND
- (Zeile.Befehl[i] <= "9") AND (i <= MaxZeile) DO
- Nummer:=Nummer * 10;
- Nummer:=Nummer + ORD(Zeile.Befehl[i]) - ORD("0");
- INC(i);
- END;
- RETURN Nummer;
- END UnterprogrammNr;
-
-
- PROCEDURE BerUnterPrg(PrgNummer, Tiefe : CARDINAL;
- QuadLst : arrQuad;
- ZeigeUnterPrg : BOOLEAN);
- VAR i,
- VarEins,
- VarZwei,
- Anzahl,
- Zaehler : CARDINAL; (* Zeigt auf die auszufuehrende Quadrupelzeile *)
- QuadLst2 : arrQuad;
- BefehlsLst : arrList;
- Korrekt : BOOLEAN;
- Y : ARRAY [0..Max] OF CARDINAL;
- BEGIN
- FOR i:=0 TO 9 DO
- Y[i]:=X[i];
- END;
- FOR i:=10 TO Max DO
- Y[i]:=0;
- END;
- Zaehler:=1;
- Anzahl:=1;
-
- WHILE QuadLst[Zaehler].Zeile # 0 DO
- Korrekt:=FALSE;
-
- IF ZeigeUnterPrg THEN
- IF PrgNummer = 1 THEN
- WriteString("Add");
- END;
- IF PrgNummer = 2 THEN
- WriteString("Sub");
- END;
- IF PrgNummer = 3 THEN
- WriteString("Mul");
- END;
- IF PrgNummer = 4 THEN
- WriteString("DIV");
- END;
- IF PrgNummer = 5 THEN
- WriteString("MOD");
- END;
- WriteCard(Tiefe,1);
- WriteString(" : ");
- WriteCard(Anzahl,3);
- WriteString(" Quad : ");
- DruckeQuadrupel(QuadLst[Zaehler]);
- END;
-
- IF QuadLst[Zaehler].Befehl[1] = "U" THEN
- VarEins:=UnterprogrammNr(QuadLst[Zaehler]);
- IF VarEins = 1 THEN
- IF ZeigeUnterPrg THEN
- WriteString(" U1 ---> Addition : X1:=X1+X2");WriteLn;
- END;
- BefehlsLst:="bX10:X2;wX10#0dbX10:p(X10);X1:s(X1)ee";
- BerechneQuad(BefehlsLst,QuadLst2);
- FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
- BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
- FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
- END;
-
- IF VarEins = 2 THEN
- IF ZeigeUnterPrg THEN
- WriteString(" U2 ---> Subtraktion : X1:=X1-X2");WriteLn;
- END;
- BefehlsLst:="bX10:X2;wX10#0dbX10:p(X10);X1:p(X1)ee";
- BerechneQuad(BefehlsLst,QuadLst2);
- FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
- BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
- FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
- END;
-
- IF VarEins = 3 THEN
- IF ZeigeUnterPrg THEN
- WriteString(" U3 ---> Multiplikation : X1:=X1*X2");WriteLn;
- END;
- BefehlsLst:="bX10:p(X1);X1:X2;wX10#0dbU1;X10:p(X10);ee";
- BerechneQuad(BefehlsLst,QuadLst2);
- FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
- BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
- FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
- END;
-
- IF VarEins = 4 THEN
- IF ZeigeUnterPrg THEN
- WriteString(" U4 ---> Division : X1:=X1 DIV X2");WriteLn;
- END;
- BefehlsLst:="bX10:0;X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12;wX11#0dbU2;X10:s(X10);X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12eX1:X10e";
- BerechneQuad(BefehlsLst,QuadLst);
-
- (*Drucke(BefehlsLst,QuadLst);WriteLn;*)
-
- FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
- BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
- FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
- END;
-
- IF VarEins = 5 THEN
- IF ZeigeUnterPrg THEN
- WriteString(" U5 ---> Modular : X1:=X1 MOD X2");WriteLn;
- END;
- BefehlsLst:="bX10:0;X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12;wX11#0dbU2;X10:s(X10);X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12ee";
- BerechneQuad(BefehlsLst,QuadLst);
- FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
- BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
- FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
- END;
-
- Zaehler:=QuadLst[Zaehler].IFzeile;
- Korrekt:=TRUE;
- ELSE
- HoleVariable(QuadLst,Zaehler,VarEins,VarZwei);
- Y[Max]:=X[Max];
- END;
-
- IF NOT(Korrekt) AND succ(QuadLst[Zaehler]) THEN
- IF Y[VarZwei] # 65535 THEN
- Y[VarEins]:=Y[VarZwei]+1;
- ELSE
- Y[VarEins]:=65535;
- END;
- Korrekt:=TRUE;
- Zaehler:=QuadLst[Zaehler].IFzeile;
- IF ZeigeUnterPrg THEN
- WriteString(" succ(X");
- WriteCard(VarZwei,1);
- WriteString(") ---> X");
- WriteCard(VarEins,1);
- WriteString(" = ");
- WriteCard(Y[VarEins],1);WriteLn;
- END;
- END;
-
- IF NOT(Korrekt) AND pred(QuadLst[Zaehler]) THEN
- IF Y[VarZwei] # 0 THEN
- Y[VarEins]:=Y[VarZwei]-1;
- ELSE
- Y[VarEins]:=0;
- END;
- Korrekt:=TRUE;
- Zaehler:=QuadLst[Zaehler].IFzeile;
- IF ZeigeUnterPrg THEN
- WriteString(" pred(X");
- WriteCard(VarZwei,1);
- WriteString(") ---> X");
- WriteCard(VarEins,1);
- WriteString(" = ");
- WriteCard(Y[VarEins],1);WriteLn;
- END;
- END;
-
- IF NOT(Korrekt) AND schleife(QuadLst[Zaehler]) THEN
- IF Y[VarEins] # Y[VarZwei] THEN
- Zaehler:=QuadLst[Zaehler].IFzeile;
- IF ZeigeUnterPrg THEN
- WriteString(" while X");
- WriteCard(VarEins,1);
- WriteString(" # ");
- IF VarZwei = Max THEN
- WriteCard(Y[Max],1);
- ELSE
- Write("X");
- WriteCard(VarZwei,1);
- END;
- WriteString(" ---> TRUE");
- WriteLn;
- END;
- ELSE
- Zaehler:=QuadLst[Zaehler].ELSEzeile;
- IF ZeigeUnterPrg THEN
- WriteString(" while X");
- WriteCard(VarEins,1);
- WriteString(" # ");
- IF VarZwei = Max THEN
- WriteCard(Y[Max],1);
- ELSE
- Write("X");
- WriteCard(VarZwei,1);
- END;
- WriteString(" ---> FALSE");
- WriteLn;
- END;
- END;
- Korrekt:=TRUE;
- END;
-
- IF NOT(Korrekt) THEN
- Y[VarEins]:=Y[VarZwei];
- Korrekt:=TRUE;
- Zaehler:=QuadLst[Zaehler].IFzeile;
- IF ZeigeUnterPrg THEN
- WriteString(" X");
- WriteCard(VarEins,1);
- WriteString(":=");
- IF VarZwei = Max THEN
- WriteCard(Y[Max],1);
- ELSE
- Write("X");
- WriteCard(VarZwei,1);
- END;
- WriteString(" ---> X");
- WriteCard(VarEins,1);
- WriteString(" = ");
- WriteCard(Y[VarEins],1);
- WriteLn;
- END;
- END;
-
- INC(Anzahl);
- INC(AnzAnweisungen);
- END;
- FOR i:=0 TO 9 DO
- X[i]:=Y[i];
- END;
- END BerUnterPrg;
-
-
- PROCEDURE Unterprogramm(ZeigeBefehl, ZeigeUnterPrg : BOOLEAN;
- Nummer : CARDINAL);
- VAR QuadLst : arrQuad;
- BefehlsLst : arrList;
- BEGIN
- IF Nummer = 1 THEN
- IF ZeigeBefehl THEN
- WriteString(" U1 ---> Addition : X1:=X1+X2");WriteLn;
- END;
- BefehlsLst:="bX10:X2;wX10#0dbX10:p(X10);X1:s(X1)ee";
- BerechneQuad(BefehlsLst,QuadLst);
- BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
- END;
-
- IF Nummer = 2 THEN
- IF ZeigeBefehl THEN
- WriteString(" U2 ---> Subtraktion : X1:=X1-X2");WriteLn;
- END;
- BefehlsLst:="bX10:X2;wX10#0dbX10:p(X10);X1:p(X1)ee";
- BerechneQuad(BefehlsLst,QuadLst);
- BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
- END;
-
- IF Nummer = 3 THEN
- IF ZeigeBefehl THEN
- WriteString(" U3 ---> Multiplikation : X1:=X1*X2");WriteLn;
- END;
- BefehlsLst:="bX10:p(X1);X1:X2;wX10#0dbU1;X10:p(X10);ee";
- BerechneQuad(BefehlsLst,QuadLst);
- BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
- END;
-
- IF Nummer = 4 THEN
- IF ZeigeBefehl THEN
- WriteString(" U4 ---> Division : X1:=X1 DIV X2");WriteLn;
- END;
- BefehlsLst:="bX10:0;X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12;wX11#0dbU2;X10:s(X10);X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12eX1:X10e";
- BerechneQuad(BefehlsLst,QuadLst);
-
- (*Drucke(BefehlsLst,QuadLst);WriteLn;*)
-
- BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
- END;
-
- IF Nummer = 5 THEN
- IF ZeigeBefehl THEN
- WriteString(" U5 ---> Modular : X1:=X1 MOD X2");WriteLn;
- END;
- BefehlsLst:="bX10:0;X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12;wX11#0dbU2;X10:s(X10);X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12ee";
- BerechneQuad(BefehlsLst,QuadLst);
- BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
- END;
-
- IF (Nummer < 1) AND (Nummer > 5) THEN
- WriteString(" U");WriteCard(Nummer,1);
- WriteString(" existiert nicht!!!");
- WriteLn;
- END;
-
- END Unterprogramm;
-
-
- PROCEDURE Interpreter(QuadListe : arrQuad);
- VAR i,
- VarEins,
- VarZwei,
- Anw, (* Bisher ausgefuehrte Anweisungen. *)
- AnwMax, (* Maximal auszufuehrende Anweisungen *)
- Zaehler : CARDINAL; (* Zeigt auf die auszufuehrende Quadrupelzeile *)
- ZeigeBefehl,
- ZeigeUnterPrg,
- ZeigeVariable,
- Korrekt : BOOLEAN;
-
-
- BEGIN
- FOR i:=0 TO Max DO;
- X[i]:=0;
- END;
- WriteLn;
- WriteString("Soll dieses while-Programm ausgefuehrt werden ? ");
- IF JaNein() THEN
- Zaehler:=1;
- WriteString("Wieviele Anweisungen sollen maximal ausgefuehrt werden : ");
- ReadCard(AnwMax);
- IF AnwMax >= 65534 THEN AnwMax:=65534 END;
- WriteCard(AnwMax,1);WriteLn;
- WriteString("Soll jede einzelne Anweisung gedruckt werden ? ");
- ZeigeBefehl:=JaNein();
- IF ZeigeBefehl THEN
- WriteString("Sollen dann auch die Variablen # 0 gedruckt werden ? ");
- ZeigeVariable:=JaNein();
- WriteString("Sollen die Anweisungen der Unterprogramme gezeigt ");
- WriteString("werden ? ");
- ZeigeUnterPrg:=JaNein();
- ELSE
- ZeigeVariable:=FALSE;
- END;
-
- Anw:=1;
- AnzAnweisungen:=0;
- WHILE Anw <= AnwMax DO
- Korrekt:=FALSE;
-
- IF QuadListe[Zaehler].Zeile = 0 THEN
- WriteLn;
- WriteString("Ende der Quadrupelliste --> Ende des Programms.");
- WriteLn;
- Korrekt:=TRUE;
- Anw:=AnwMax + 1;
- ELSE
-
- IF ZeigeBefehl THEN
- WriteString("Main : ");WriteCard(Anw,3);
- WriteString(" Quad : ");
- DruckeQuadrupel(QuadListe[Zaehler]);
- END;
-
- IF QuadListe[Zaehler].Befehl[1] = "U" THEN
- Unterprogramm(ZeigeBefehl,ZeigeUnterPrg,
- UnterprogrammNr(QuadListe[Zaehler]));
- Zaehler:=QuadListe[Zaehler].IFzeile;
- Korrekt:=TRUE;
- ELSE
- HoleVariable(QuadListe,Zaehler,VarEins,VarZwei);
- END;
-
- IF NOT(Korrekt) AND succ(QuadListe[Zaehler]) THEN
- IF X[VarZwei] # 65535 THEN
- X[VarEins]:=X[VarZwei]+1;
- ELSE
- X[VarEins]:=65535;
- END;
- Korrekt:=TRUE;
- Zaehler:=QuadListe[Zaehler].IFzeile;
- IF ZeigeBefehl THEN
- WriteString(" succ(X");
- WriteCard(VarZwei,1);
- WriteString(") ---> X");
- WriteCard(VarEins,1);
- WriteString(" = ");
- WriteCard(X[VarEins],1);WriteLn;
- END;
- END;
-
- IF NOT(Korrekt) AND pred(QuadListe[Zaehler]) THEN
- IF X[VarZwei] # 0 THEN
- X[VarEins]:=X[VarZwei]-1;
- ELSE
- X[VarEins]:=0;
- END;
- Korrekt:=TRUE;
- Zaehler:=QuadListe[Zaehler].IFzeile;
- IF ZeigeBefehl THEN
- WriteString(" pred(X");
- WriteCard(VarZwei,1);
- WriteString(") ---> X");
- WriteCard(VarEins,1);
- WriteString(" = ");
- WriteCard(X[VarEins],1);WriteLn;
- END;
- END;
-
- IF NOT(Korrekt) AND schleife(QuadListe[Zaehler]) THEN
- IF X[VarEins] # X[VarZwei] THEN
- Zaehler:=QuadListe[Zaehler].IFzeile;
- IF ZeigeBefehl THEN
- WriteString(" while X");
- WriteCard(VarEins,1);
- WriteString(" # ");
- IF VarZwei = Max THEN
- WriteCard(X[Max],1);
- ELSE
- Write("X");
- WriteCard(VarZwei,1);
- END;
- WriteString(" ---> TRUE");
- WriteLn;
- END;
- ELSE
- Zaehler:=QuadListe[Zaehler].ELSEzeile;
- IF ZeigeBefehl THEN
- WriteString(" while X");
- WriteCard(VarEins,1);
- WriteString(" # ");
- IF VarZwei = Max THEN
- WriteCard(X[Max],1);
- ELSE
- Write("X");
- WriteCard(VarZwei,1);
- END;
- WriteString(" ---> FALSE");
- WriteLn;
- END;
- END;
- Korrekt:=TRUE;
- END;
-
- IF NOT(Korrekt) THEN
- X[VarEins]:=X[VarZwei];
- Korrekt:=TRUE;
- Zaehler:=QuadListe[Zaehler].IFzeile;
- IF ZeigeBefehl THEN
- WriteString(" X");
- WriteCard(VarEins,1);
- WriteString(":=");
- IF VarZwei = Max THEN
- WriteCard(X[Max],1);
- ELSE
- Write("X");
- WriteCard(VarZwei,1);
- END;
- WriteString(" ---> X");
- WriteCard(VarEins,1);
- WriteString(" = ");
- WriteCard(X[VarEins],1);
- WriteLn;
- END;
- END;
-
- IF ZeigeVariable THEN
- DruckeVariable(X);
- WriteLn;
- END;
-
- INC(AnzAnweisungen);
- INC(Anw);
- END;
- END;
-
- WriteLn;WriteLn;
- WriteString("Es wurden ");WriteLongCard(AnzAnweisungen,1);
- WriteString(" Anweisungen ausgefuehrt.");WriteLn;
- WriteString("Ergebnis : ");WriteLn;
- DruckeVariable(X);
- END;
- END Interpreter;
-
-
- END QuadInterpreter.
-