handoff-2026-10-19-next.md 4.0 KB

Next session — plan

Branch state (2026-10-19): work is on master, tree clean.

Baseline: suite 241/241, fixpoint OK (3,853,285 bytes), corpus 411/612, 0 crashes.

Policy: follow Modula-2, not gm2 degradation — declaration before use (only a POINTER's base may forward-reference). In docs/gaps/, the decl-order and gm2-ext classes are not targets except where gm2 compatibility was explicitly chosen (gap22, gap09).


P0 — generics: two instantiations of one generic ✅ DONE

Fixed on 2026-10-19. The bug was not EnterTypeParamBound (each instance re-binds T correctly). It was in Lowering: after EndUnit, Lower re-emitted each unit in globScope, so Lower.MaterializeGlobals copied the unit's types into globScope; a generic instance leaked its NodeRec there, and the second instance's POINTER TO NodeRec picked it up via ForwardType (a forward pointer base made it visible; direct records did not). See docs/analysis_gaps.md §10 for the full trail.

  • SymTab.EnterLowerScope/LeaveLowerScope + Lower re-emits each unit in its own module scope (also around the ExitCode probe in Lower.EndSession).
  • Lower.ReenterImports re-materialises a nested module's FROM-imports in the enclosing scope (the nested scope is popped before lowering).
  • Regression: compiler/tests/g_twice{,i,c,p} (GTwiceProg, 42).

Follow-up: showcase24 can now use two instantiations of one generic (simplify it, or add a demo) — optional.

P1 — quick corpus wins ✅ DONE

Chosen with the user despite the gm2-ext class (compatibility mode).

  • gap22 __FILE__/__LINE__ — done (v3-file-line): scanner allows a leading _, both names are reserved literals folded to the file-name string / line-number integer. +3 corpus.
  • gap09 scalar → ARRAY OF BYTE — done (v3-bytebuf): a parse-time marker on ARRAY OF BYTE open formals, accepted for scalar/pointer/string actuals; a scalar is wrapped in a stack descriptor [count=SIZE(actual)][copy]. +3 corpus. See the caveats in docs/gaps/README.md (writes reach the copy; string HIGH is one less than gm2; BYTE is still 32-bit).

P2 — structural

  • gap12 variant records: empty arms, ELSE, untagged inner CASE (5 files).
  • gap11 bare procedure value as a statement.
  • gap10 VAR-param type leniency (decide whether to adopt gm2's same-size rule — non-standard).
  • gap13 remainder: de-reserve the standard builtins (ORD, CHR, VAL, …) — contextual-keyword parser refactor (ORDL is done).
  • gap18 set-typed CASE labels.

P3 — conformance remainder (architectural)

Forward references to module-level variables/procedures from a procedure body still work (the two-phase parse defers bodies). Strict declaration-before-use would require order-aware body checking; high risk, touches self-hosting. The declaration part is already strict.

P4 — latent correctness

The size-sensitive V3 miscompile is still unroot-caused. Note: the 2026-10-19 Lowering change moved code around, so re-check whether the old symptom ("removing ASTDUMP breaks the fixpoint") still reproduces before bisecting. Dedicated session; a real correctness landmine.

P5 — housekeeping

  • Consolidate docs/summary_*.md (see docs/INDEX.md).
  • (Merge of resolve-check → master: done.)

Gates for every step

compiler/build.sh → compiler/run_tests.sh (must stay 100%) → bootstrap/fixpoint.sh (byte-identical) → tools/v3-corpus/corpus.sh (record OK/CRASH + note) → update docs/gaps/ + STATUS/README → commit with a v3-* tag.

Resume

cd .../m2compiler-V3
git checkout master
cd compiler && ./build.sh && ./run_tests.sh   # 241/241
cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh
tools/v3-corpus/corpus.sh                     # 411 OK, 0 crash

Recommendation: P1 (two bounded wins) next, then reserve a separate session for P4.