|
|
@@ -0,0 +1,59 @@
|
|
|
+# 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 `CONST`s 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, `SET`s 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.
|