Generator.mod 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. IMPLEMENTATION MODULE Generator;
  2. FROM InOut IMPORT Write, WriteString,
  3. WriteOct, WriteCard, WriteHex,
  4. WriteInt, WriteLn;
  5. FROM Interpreter IMPORT INSTR, Command;
  6. FROM Storage IMPORT ALLOCATE;
  7. FROM Scanner IMPORT STRING, printCode;
  8. TYPE refPointer = POINTER TO instr;
  9. TYPE instr = RECORD
  10. addr : CARDINAL;
  11. next : refPointer;
  12. END;
  13. TYPE label = RECORD
  14. num : CARDINAL;
  15. addr : CARDINAL;
  16. refs : refPointer
  17. END;
  18. TYPE Label = POINTER TO label;
  19. VAR LNum : CARDINAL; (* number of next label *)
  20. VAR currAddr : CARDINAL; (* current code store index *)
  21. VAR mnem : ARRAY [ MSP .. OUTc], [0..3] OF CHAR;
  22. PROCEDURE GetNewLabel() : Label;
  23. VAR tmp : Label;
  24. BEGIN
  25. NEW(tmp);
  26. tmp^.num := LNum; INC(LNum);
  27. tmp^.addr := 0;
  28. tmp^.refs := NIL;
  29. RETURN tmp
  30. END GetNewLabel;
  31. PROCEDURE Gen(fct: Command; lev, val: CARDINAL);
  32. BEGIN
  33. IF currAddr >= maxadr THEN
  34. WriteString("*** code store overflow ***"); WriteLn;
  35. HALT
  36. END;
  37. CodeStore[currAddr].cmd := fct;
  38. CodeStore[currAddr].lev := lev;
  39. CodeStore[currAddr].val := val;
  40. IF printCode THEN
  41. WriteHex(currAddr, 4);WriteString(": ");
  42. WriteString(mnem[fct]);
  43. IF fct < RET THEN
  44. Write(" ");
  45. IF (fct = LDA) OR (fct = CALL) THEN
  46. WriteCard(lev, 1); Write(",");
  47. END;
  48. IF (fct = JMP) OR (fct = JMPC) OR (fct = CALL) THEN
  49. Write('$'); WriteHex(val, 4)
  50. ELSE
  51. WriteInt(INTEGER(val), 1)
  52. END
  53. END;
  54. WriteLn;
  55. END;
  56. INC(currAddr)
  57. END Gen;
  58. PROCEDURE GenL(fct : Command; lev : CARDINAL; lab : Label);
  59. VAR refPtr : refPointer;
  60. BEGIN
  61. IF currAddr >= maxadr THEN
  62. WriteString("*** code store overflow ***"); WriteLn;
  63. HALT
  64. END;
  65. CodeStore[currAddr].cmd := fct;
  66. CodeStore[currAddr].lev := lev;
  67. CodeStore[currAddr].val := lab^.addr;
  68. IF printCode THEN
  69. WriteHex(currAddr, 4); WriteString(": ");
  70. WriteString(mnem[fct]);
  71. IF fct < RET THEN
  72. Write(" ");
  73. IF (fct = LDA) OR (fct = CALL) THEN
  74. WriteCard(lev, 1); Write(",");
  75. END;
  76. Write('L'); WriteHex(lab^.num, 4);
  77. END;
  78. WriteLn;
  79. END;
  80. IF lab^.refs = NIL THEN
  81. NEW(lab^.refs);
  82. refPtr := lab^.refs
  83. ELSE
  84. refPtr := lab^.refs;
  85. WHILE refPtr^.next # NIL DO refPtr := refPtr^.next END;
  86. NEW(refPtr^.next);
  87. refPtr := refPtr^.next
  88. END;
  89. refPtr^.addr := currAddr;
  90. refPtr^.next := NIL;
  91. INC(currAddr)
  92. END GenL;
  93. PROCEDURE GenS(fct : Command; len : CARDINAL; str : STRING);
  94. VAR i, j : CARDINAL;
  95. c : CHAR;
  96. BEGIN
  97. IF currAddr >= maxadr THEN
  98. WriteString("*** code store overflow ***"); WriteLn;
  99. HALT
  100. END;
  101. CodeStore[currAddr].cmd := fct;
  102. CodeStore[currAddr].lev := 0;
  103. CodeStore[currAddr].val := len;
  104. IF printCode THEN
  105. WriteHex(currAddr, 4); WriteString(": ");
  106. WriteString(mnem[fct]);
  107. WriteString(" '");
  108. END;
  109. INC(currAddr); j := 0; DEC(len);
  110. FOR i := len TO 0 BY -1 DO
  111. CodeStore[currAddr].sval[j] := str^[i];
  112. INC(j);
  113. IF j = 6 THEN
  114. INC(currAddr); j := 0
  115. END
  116. END;
  117. IF printCode THEN
  118. FOR i := 0 TO len DO
  119. c := str^[i];
  120. IF (c >= ' ') AND (c <= "~") THEN
  121. Write(c);
  122. ELSE
  123. Write("\"); WriteOct(ORD(c), 3)
  124. END
  125. END;
  126. Write("'"); WriteLn;
  127. END;
  128. IF j # 0 THEN
  129. INC(currAddr)
  130. END
  131. END GenS;
  132. PROCEDURE Gens(fct: Command);
  133. BEGIN
  134. Gen(fct, 0, 0)
  135. END Gens;
  136. PROCEDURE fixup(x: CARDINAL);
  137. BEGIN
  138. CodeStore[x].val := currAddr;
  139. END fixup;
  140. PROCEDURE SetLabel(lab : Label);
  141. VAR nref : refPointer;
  142. BEGIN
  143. IF printCode THEN
  144. WriteHex(currAddr, 4);
  145. WriteString(": L"); WriteHex(lab^.num, 4); Write(":"); WriteLn
  146. END;
  147. nref := lab^.refs;
  148. WHILE nref # NIL DO
  149. fixup(nref^.addr);
  150. nref := nref^.next
  151. END;
  152. lab^.addr := currAddr
  153. END SetLabel;
  154. PROCEDURE InitGenerator;
  155. BEGIN
  156. currAddr := 0;
  157. LNum := 1;
  158. END InitGenerator;
  159. PROCEDURE Initmnem;
  160. BEGIN
  161. mnem[MSP ] := "MSP "; mnem[LDA ] := "LDA "; mnem[LD ] := "LD ";
  162. mnem[ST ] := "ST "; mnem[LDI ] := "LDI "; mnem[LDIs] := "LDIs";
  163. mnem[JMP ] := "JMP "; mnem[JMPC] := "JMPC"; mnem[CALL] := "CALL";
  164. mnem[RET ] := "RET "; mnem[MV ] := "MV "; mnem[NEGi] := "NEGi";
  165. mnem[ODDi] := "ODDi"; mnem[ADDi] := "ADDi"; mnem[SUBi] := "SUBi";
  166. mnem[MULi] := "MULi"; mnem[DIVi] := "DIVi"; mnem[EQ ] := "EQ ";
  167. mnem[NE ] := "NE "; mnem[LT ] := "LT "; mnem[GE ] := "GE ";
  168. mnem[GT ] := "GT "; mnem[LE ] := "LE "; mnem[ANDb] := "ANDb";
  169. mnem[ORb ] := "ORb "; mnem[NOTb] := "NOTb"; mnem[INi ] := "INi ";
  170. mnem[OUTi] := "OUTi"; mnem[OUTc] := "OUTc";
  171. END Initmnem;
  172. BEGIN
  173. Initmnem;
  174. END Generator.