| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- IMPLEMENTATION MODULE Generator;
- FROM InOut IMPORT Write, WriteString,
- WriteOct, WriteCard, WriteHex,
- WriteInt, WriteLn;
- FROM Interpreter IMPORT INSTR, Command;
- FROM Storage IMPORT ALLOCATE;
- FROM Scanner IMPORT STRING, printCode;
- TYPE refPointer = POINTER TO instr;
- TYPE instr = RECORD
- addr : CARDINAL;
- next : refPointer;
- END;
- TYPE label = RECORD
- num : CARDINAL;
- addr : CARDINAL;
- refs : refPointer
- END;
- TYPE Label = POINTER TO label;
- VAR LNum : CARDINAL; (* number of next label *)
- VAR currAddr : CARDINAL; (* current code store index *)
- VAR mnem : ARRAY [ MSP .. OUTc], [0..3] OF CHAR;
- PROCEDURE GetNewLabel() : Label;
- VAR tmp : Label;
- BEGIN
- NEW(tmp);
- tmp^.num := LNum; INC(LNum);
- tmp^.addr := 0;
- tmp^.refs := NIL;
- RETURN tmp
- END GetNewLabel;
- PROCEDURE Gen(fct: Command; lev, val: CARDINAL);
- BEGIN
- IF currAddr >= maxadr THEN
- WriteString("*** code store overflow ***"); WriteLn;
- HALT
- END;
- CodeStore[currAddr].cmd := fct;
- CodeStore[currAddr].lev := lev;
- CodeStore[currAddr].val := val;
- IF printCode THEN
- WriteHex(currAddr, 4);WriteString(": ");
- WriteString(mnem[fct]);
- IF fct < RET THEN
- Write(" ");
- IF (fct = LDA) OR (fct = CALL) THEN
- WriteCard(lev, 1); Write(",");
- END;
- IF (fct = JMP) OR (fct = JMPC) OR (fct = CALL) THEN
- Write('$'); WriteHex(val, 4)
- ELSE
- WriteInt(INTEGER(val), 1)
- END
- END;
- WriteLn;
- END;
- INC(currAddr)
- END Gen;
- PROCEDURE GenL(fct : Command; lev : CARDINAL; lab : Label);
- VAR refPtr : refPointer;
- BEGIN
- IF currAddr >= maxadr THEN
- WriteString("*** code store overflow ***"); WriteLn;
- HALT
- END;
- CodeStore[currAddr].cmd := fct;
- CodeStore[currAddr].lev := lev;
- CodeStore[currAddr].val := lab^.addr;
- IF printCode THEN
- WriteHex(currAddr, 4); WriteString(": ");
- WriteString(mnem[fct]);
- IF fct < RET THEN
- Write(" ");
- IF (fct = LDA) OR (fct = CALL) THEN
- WriteCard(lev, 1); Write(",");
- END;
- Write('L'); WriteHex(lab^.num, 4);
- END;
- WriteLn;
- END;
- IF lab^.refs = NIL THEN
- NEW(lab^.refs);
- refPtr := lab^.refs
- ELSE
- refPtr := lab^.refs;
- WHILE refPtr^.next # NIL DO refPtr := refPtr^.next END;
- NEW(refPtr^.next);
- refPtr := refPtr^.next
- END;
- refPtr^.addr := currAddr;
- refPtr^.next := NIL;
- INC(currAddr)
- END GenL;
- PROCEDURE GenS(fct : Command; len : CARDINAL; str : STRING);
- VAR i, j : CARDINAL;
- c : CHAR;
- BEGIN
- IF currAddr >= maxadr THEN
- WriteString("*** code store overflow ***"); WriteLn;
- HALT
- END;
- CodeStore[currAddr].cmd := fct;
- CodeStore[currAddr].lev := 0;
- CodeStore[currAddr].val := len;
- IF printCode THEN
- WriteHex(currAddr, 4); WriteString(": ");
- WriteString(mnem[fct]);
- WriteString(" '");
- END;
- INC(currAddr); j := 0; DEC(len);
- FOR i := len TO 0 BY -1 DO
- CodeStore[currAddr].sval[j] := str^[i];
- INC(j);
- IF j = 6 THEN
- INC(currAddr); j := 0
- END
- END;
- IF printCode THEN
- FOR i := 0 TO len DO
- c := str^[i];
- IF (c >= ' ') AND (c <= "~") THEN
- Write(c);
- ELSE
- Write("\"); WriteOct(ORD(c), 3)
- END
- END;
- Write("'"); WriteLn;
- END;
- IF j # 0 THEN
- INC(currAddr)
- END
- END GenS;
- PROCEDURE Gens(fct: Command);
- BEGIN
- Gen(fct, 0, 0)
- END Gens;
- PROCEDURE fixup(x: CARDINAL);
- BEGIN
- CodeStore[x].val := currAddr;
- END fixup;
- PROCEDURE SetLabel(lab : Label);
- VAR nref : refPointer;
- BEGIN
- IF printCode THEN
- WriteHex(currAddr, 4);
- WriteString(": L"); WriteHex(lab^.num, 4); Write(":"); WriteLn
- END;
- nref := lab^.refs;
- WHILE nref # NIL DO
- fixup(nref^.addr);
- nref := nref^.next
- END;
- lab^.addr := currAddr
- END SetLabel;
- PROCEDURE InitGenerator;
- BEGIN
- currAddr := 0;
- LNum := 1;
- END InitGenerator;
- PROCEDURE Initmnem;
- BEGIN
- mnem[MSP ] := "MSP "; mnem[LDA ] := "LDA "; mnem[LD ] := "LD ";
- mnem[ST ] := "ST "; mnem[LDI ] := "LDI "; mnem[LDIs] := "LDIs";
- mnem[JMP ] := "JMP "; mnem[JMPC] := "JMPC"; mnem[CALL] := "CALL";
- mnem[RET ] := "RET "; mnem[MV ] := "MV "; mnem[NEGi] := "NEGi";
- mnem[ODDi] := "ODDi"; mnem[ADDi] := "ADDi"; mnem[SUBi] := "SUBi";
- mnem[MULi] := "MULi"; mnem[DIVi] := "DIVi"; mnem[EQ ] := "EQ ";
- mnem[NE ] := "NE "; mnem[LT ] := "LT "; mnem[GE ] := "GE ";
- mnem[GT ] := "GT "; mnem[LE ] := "LE "; mnem[ANDb] := "ANDb";
- mnem[ORb ] := "ORb "; mnem[NOTb] := "NOTb"; mnem[INi ] := "INi ";
- mnem[OUTi] := "OUTi"; mnem[OUTc] := "OUTc";
- END Initmnem;
- BEGIN
- Initmnem;
- END Generator.
|