summary_step2.md 2.6 KB

Step 2 — Scalars + MC64 backend (tag: step2)

Commit eee1504 — "step2: scalars + MC64 backend — SymTab, MGen emitter, 25/25 tests green; fix bit_in operand order" (88 files, +4980/−132).

Goal

Full scalar subset of Modula-2 compiling to runnable MC64 images: CONST/TYPE/VAR, complete expression hierarchy, all structured statements, static type checking, exact error codes.

What was built

  • m2c/SymTab.def/.mod — symbol table + type checker, ported from the proven Test1 design: scopes, aliases/subranges/enums/arrays/ records/sets/pointers descriptors, InvalidType cascade suppression; codes 200/201/202, 210–224; plus PendCount/ PendName for VAR-list emission.
  • m2c/MGen.def/.mod — MC64 image emitter: one 8-byte slot per global, literal CONSTs as startup stores, stack-machine expressions (A6/A7/A8/B8/A9/AA/B9, signed B2–B5 compares, D5–D9 reals, E6/E8/B6 logic), E0/E1 jumps with fixups, LOOP/EXIT stack, CASE as compare-chains, FOR with hidden temp global, SETs via power2/build_field_mask/bit_in/A0, embedded decimal-print helper. Test convention: a global VAR ExitCode : INTEGER is printed as decimal + CRLF.
  • m2c/M2c.atg — full scalar grammar (~900 lines): type checking identical to the reference rules; backend lowers scalars + sets, everything else parses but gets error 230.
  • m2c/run_tests.sh — extended: expect_run compiles, runs the .MC4 (name derived from the MODULE line, not ls -t) under mcint, and compares the printed value.

Tests — 25/25

14 run tests (7, 15, 42, 20, 103, 55, 55, 7, 85, 31, 97, 1, 74, sets 15) + 6 rejections (one 210, rest 230-only, no cascades) + 4 phase-0 + 1 silent-minimal. All negatives produce exactly one error each.

Bugs found and fixed

  1. Image writer skipped the 64-byte file header (shifted image).
  2. ParseCard used 10H/16H (hex 16/22!) for decimal bases — multi-digit literals wrong, single digits accidentally right.
  3. ParseReal overlaid 8 bytes of gm2's 80-bit-extended LONGREAL — switched to 8-byte REAL like the VM's own Stack.mod.
  4. bit_in (0E7H) operands swapped in mc64/Interpreter.mod vs both the spec prose and the original Turbo MCode (op := Pop(); Push(Pop() IN BITSET(op))) — fixed (2 lines), MC64 suite re-verified 24/24.
  5. Runner used same-second ls -t ties + non-portable $'\r' stripping — deterministic names + tr -d '\r'.

Known limits (in M2c.atg header)

Truncating DIV/MOD, signed compares for CARDINAL, eager AND/OR, literal-only CONST/BY, REAL as binary64, no procedures yet.