MGen.def 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. DEFINITION MODULE MGen;
  2. (* MC64 image emitter for the M2c scalar subset (see M2c.atg).
  3. Buffers a single-module MC64 image and writes "<Module>.MC4"
  4. (current directory) at EndModule. The image satisfies the
  5. reference loader (Loader2): magic "MC64", descriptor with name,
  6. TOINIT flag, global sizes (one 8-byte slot per variable), two
  7. procedures (0 = user code, 1 = decimal print helper), relative
  8. procedure-table cells, and the checksum rule.
  9. Lowered: scalar globals (INTEGER/CARDINAL/CHAR/BOOLEAN/enums as
  10. 32-bit ops on slots, REAL as binary64), CONST initializers that
  11. are plain literals (emitted as startup stores), full scalar
  12. expressions on the stack machine, IF/CASE/WHILE/REPEAT/LOOP+EXIT/
  13. FOR via E0/E1 jumps with fixups. Everything else is reported by
  14. the parser (error 230); this module only needs structurally
  15. valid placeholders for those cases.
  16. Test convention (no I/O in the language): if the source declares
  17. VAR ExitCode : INTEGER; (int family, VAR kind)
  18. the epilogue prints its value as decimal + CRLF through the
  19. embedded print procedure; otherwise the program just ends.
  20. Step 3 adds procedures: user procedures take table entries 1..N
  21. (0 = module body), run with ENTER frames, and are called via
  22. ED (global), EC (directly nested) or EE (display walk). *)
  23. TYPE
  24. LitStr = ARRAY [0 .. 63] OF CHAR;
  25. (* Literal text: "42", "-5", "0FFH", "3.14", "'a'", "TRUE". ""
  26. means "not a plain literal". *)
  27. PROCEDURE OpenModule (name: ARRAY OF CHAR);
  28. (* Resets all state; reserves slots 0..3 for the print helper. *)
  29. PROCEDURE DeclVar (name: ARRAY OF CHAR);
  30. (* Assigns the next global slot to name (any type; one slot). *)
  31. PROCEDURE DeclConst (name: ARRAY OF CHAR; lit: LitStr; t: INTEGER);
  32. (* Assigns a slot and buffers a startup initializer from the literal
  33. text (t is a SymTab.TypeIndex). Empty lit buffers a 0. *)
  34. PROCEDURE DeclConstInt (name: ARRAY OF CHAR; v: INTEGER);
  35. (* Assigns a slot with an INTEGER startup value (enum literals). *)
  36. PROCEDURE BeginBody;
  37. (* Flushes buffered CONST initializers as startup stores. *)
  38. PROCEDURE EndModule;
  39. (* Emits the epilogue, the print procedure, the procedure table,
  40. the descriptor, the checksum, and writes the .MC4 file. *)
  41. PROCEDURE LoadVar (name: ARRAY OF CHAR);
  42. (* Pushes the global (placeholder push-0 if unknown). *)
  43. PROCEDURE StoreVar (name: ARRAY OF CHAR);
  44. (* Pops into the global (dropped if unknown). *)
  45. PROCEDURE PushVar (name: ARRAY OF CHAR);
  46. (* Pushes a variable's value, frame-aware: globals via the global
  47. table, same-frame locals/params direct, outer frames via the
  48. display, VAR params indirect. Placeholder push-0 if unknown. *)
  49. PROCEDURE LoadTemp (t: INTEGER);
  50. PROCEDURE StoreTemp (t: INTEGER);
  51. (* Direct slot access for compiler temporaries. *)
  52. PROCEDURE TempGlobal (): INTEGER;
  53. (* Allocates a fresh hidden global slot, returns its index. *)
  54. PROCEDURE PushInt (v: INTEGER);
  55. (* Small encodings for 0..15; negatives via 0,mag,sub. *)
  56. PROCEDURE PushBits (b: LONGCARD);
  57. (* 8E + 8 bytes: CARDINAL values and REAL bit patterns. *)
  58. PROCEDURE ParseInt (s: ARRAY OF CHAR; VAR v: INTEGER): BOOLEAN;
  59. (* Decimal, H-suffixed hex, optional leading '-'. *)
  60. PROCEDURE ParseCard (s: ARRAY OF CHAR; VAR v: CARDINAL): BOOLEAN;
  61. (* Decimal or H-suffixed hex (for literals past MAXINT). *)
  62. PROCEDURE ParseReal (s: ARRAY OF CHAR; VAR b: LONGCARD): BOOLEAN;
  63. (* Decimal with optional fraction/exponent/sign to IEEE bits. *)
  64. PROCEDURE CharOrd (s: ARRAY OF CHAR): INTEGER;
  65. (* ORD of a 1-character literal such as 'a'. *)
  66. PROCEDURE NegFold (a: ARRAY OF CHAR; VAR q: LitStr);
  67. (* Folds a unary minus into literal text ("5" -> "-5"). *)
  68. PROCEDURE IsLit (s: ARRAY OF CHAR): BOOLEAN;
  69. (* TRUE for non-empty literal text. *)
  70. (* ---- stack operators (one opcode each, see mc64-spec.md §11) ---- *)
  71. PROCEDURE Add;
  72. PROCEDURE Sub;
  73. PROCEDURE MulU;
  74. PROCEDURE DivU;
  75. PROCEDURE ModU;
  76. PROCEDURE MulI;
  77. PROCEDURE DivI;
  78. PROCEDURE ModI (t: INTEGER);
  79. (* Signed a MOD b with truncation semantics via temp slot t:
  80. a - (a DIV b) * b. Caller passes TempGlobal(). *)
  81. PROCEDURE RealAdd;
  82. PROCEDURE RealSub;
  83. PROCEDURE RealMul;
  84. PROCEDURE RealDiv;
  85. PROCEDURE And;
  86. PROCEDURE Or;
  87. PROCEDURE Not;
  88. PROCEDURE Power2;
  89. (* Push (1 << pop) for set element masks. *)
  90. PROCEDURE FieldMask;
  91. (* (1<<hi)-(1<<lo) for set ranges. *)
  92. PROCEDURE BitIn;
  93. (* Push (pop in bitset(pop)). *)
  94. PROCEDURE Eq;
  95. PROCEDURE Neq;
  96. PROCEDURE ULt;
  97. PROCEDURE ULe;
  98. PROCEDURE UGt;
  99. PROCEDURE UGe;
  100. PROCEDURE ILt;
  101. PROCEDURE ILe;
  102. PROCEDURE IGt;
  103. PROCEDURE IGe;
  104. PROCEDURE RealEq;
  105. PROCEDURE RealNe;
  106. PROCEDURE RealLt;
  107. PROCEDURE RealLe;
  108. PROCEDURE RealGt;
  109. PROCEDURE RealGe;
  110. PROCEDURE NegInt;
  111. PROCEDURE NegReal;
  112. PROCEDURE IntToReal;
  113. (* BD int_to_long + BE long_to_real. *)
  114. PROCEDURE Dup;
  115. PROCEDURE Drop;
  116. (* ---- frames, addresses, indirect access (see §5-§6) ---- *)
  117. PROCEDURE LoadLocal (sl: INTEGER);
  118. PROCEDURE StoreLocal (sl: INTEGER);
  119. (* 2C/3C direct frame access (locals negative, params >= 3).
  120. Same-frame VAR-param slots hold addresses: read them with
  121. LoadLocal, then LoadIndir0. *)
  122. PROCEDURE LoadIndir0;
  123. PROCEDURE StoreIndir0;
  124. (* 60H/70H slot-0 indirect (through VAR-param addresses). *)
  125. PROCEDURE FrameAddr (sl: INTEGER; np: CARDINAL);
  126. (* Pushes (display-frame(np) + slot*8) as a byte address. *)
  127. PROCEDURE LoadIndir;
  128. PROCEDURE StoreIndir;
  129. (* 41H/51H through a computed address. *)
  130. PROCEDURE LocalAddr (sl: INTEGER);
  131. (* 80H address of a same-frame slot. *)
  132. PROCEDURE GlobalAddr (name: ARRAY OF CHAR);
  133. (* 81H address of a global (push-0 if unknown). *)
  134. PROCEDURE PushAddr (name: ARRAY OF CHAR);
  135. (* Pushes a VAR-actual address: slot addresses for plain variables,
  136. slot contents for VAR params; display-aware. Push-0 if unknown. *)
  137. PROCEDURE StoreSetup (name: ARRAY OF CHAR);
  138. (* Emits an early store address (VAR-param or outer-frame targets)
  139. before the value expression; nothing for direct targets. *)
  140. PROCEDURE StoreFinish (name: ARRAY OF CHAR);
  141. (* Emits the store for a storable variable (global, param, local,
  142. VAR-param, outer frame). *)
  143. (* ---- procedures (see §5.2) ---- *)
  144. PROCEDURE ProcEntry (num: INTEGER; nLoc: CARDINAL);
  145. (* Records the procedure address and emits ENTER for nLoc locals. *)
  146. PROCEDURE CallProc (num: INTEGER);
  147. (* ED: call a global procedure (OFP = NIL). *)
  148. PROCEDURE CallNested (num: INTEGER);
  149. (* EC: call a directly nested procedure (OFP = FP). *)
  150. PROCEDURE CallDisplay (num: INTEGER; np: CARDINAL);
  151. (* 11H np display walk, then EE call with that frame. *)
  152. PROCEDURE Leave (nPar: CARDINAL; func: BOOLEAN);
  153. (* 84H (proper) or 85H (function) procedure leave. *)
  154. (* ---- actual parameters (nested-call-safe frame stack) ---- *)
  155. PROCEDURE ActBegin (pn: ARRAY OF CHAR);
  156. (* Opens an actual-parameter frame for a call to pn. *)
  157. PROCEDURE ActValue (t: INTEGER; v: BOOLEAN;
  158. vn: ARRAY OF CHAR): INTEGER;
  159. (* Checks one actual against its formal (0 = ok): VAR formals need
  160. a plain variable of identical type (address pushed), value
  161. formals need assignment compatibility (INTEGER widens to REAL).
  162. Always consumes the value (temp store). 1 means error 233. *)
  163. PROCEDURE ActEnd (pn: ARRAY OF CHAR; sfx, inExpr: BOOLEAN): INTEGER;
  164. (* Verifies arity and callee kind, reloads actuals reversed and
  165. emits the depth-correct call (0 = ok, 1 = error 233). *)
  166. (* ---- control flow (E0/E1 with fixups) ---- *)
  167. PROCEDURE NewLabel (): INTEGER;
  168. PROCEDURE DefLabel (id: INTEGER);
  169. PROCEDURE Jmp (id: INTEGER);
  170. PROCEDURE Jz (id: INTEGER);
  171. (* Jump if false (pops the condition). *)
  172. PROCEDURE PushLoop (exit: INTEGER);
  173. PROCEDURE PopLoop;
  174. PROCEDURE TopLoop (VAR exit: INTEGER): BOOLEAN;
  175. (* Innermost LOOP exit label; FALSE outside any LOOP. *)
  176. PROCEDURE NoSupEnter;
  177. PROCEDURE NoSupExit;
  178. PROCEDURE CopyName (s: ARRAY OF CHAR; VAR d: ARRAY OF CHAR);
  179. (* Copies zero-terminated strings between any char arrays. *)
  180. PROCEDURE NoEmitEnter;
  181. PROCEDURE NoEmitExit;
  182. (* Suppresses code emission (not literal capture) in declarative
  183. contexts such as CONST initializers and subrange bounds. *)
  184. PROCEDURE NoSup (): BOOLEAN;
  185. (* Guard depth for unsupported constructs: while > 0 the grammar
  186. suppresses follow-on 230 errors to avoid cascades. *)
  187. END MGen.