summary_session-2026-10-19.md 5.3 KB

Session 2026-10-19 — summary

Branch master (tree clean). Eleven commits, tagged individually (v3-generics-two-instances … v3-pim-io-libs). Plan source: handoff-2026-10-18-next.md (P0–P5) + handoff-2026-10-19-next.md.

Numbers

gate session start end
suite (compiler/run_tests.sh) 239/239 249/249
fixpoint (bootstrap/fixpoint.sh) OK (3,812,771 B) OK (3,882,337 B)
corpus (tools/v3-corpus/corpus.sh) 405/612 467/612, 0 crashes

Reproduce:

cd compiler && ./build.sh && ./run_tests.sh          # 249/249
cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh
tools/v3-corpus/corpus.sh                            # 467 OK, 0 crash

What landed

P0 — generics double-instantiation (real bug) — dc3b3c8

One generic instantiated twice with different-family type arguments failed on the second. Root cause was Lowering, not the formal binding: after EndUnit, Lower re-emitted each unit in globScope, so MaterializeGlobals copied the unit's types there; a generic instance leaked its NodeRec and the second instance's POINTER TO NodeRec resolved the first instance's record via ForwardType. Fix: SymTab.EnterLowerScope/LeaveLowerScope (re-emit each unit in its own scope), Lower.ReenterImports for nested-module FROM-imports. Regression g_twice* / GTwiceProg.

P1 — two gm2 extensions (user chose compatibility) — a33fc7c, b042be3

  • __FILE__ / __LINE__: scanner allows a leading _; both are reserved literals folded to the file-name string / line-number integer.
  • scalar actual → ARRAY OF BYTE: parse-time marker on the open formal; a scalar is wrapped in a stack descriptor [count=SIZE(actual)][copy] (QbeGen.OpenScalarDesc). Approximate by design (writes hit the copy; BYTE stays 32-bit) — documented in gaps/README.md.

P2 — structural gm2 extensions — 81b488b

gap10 same-size scalar VAR actual; gap11 PIM PROC type + bare proc-value statement; gap12 variant empty arms / ELSE / comma labels / untagged inner CASE / nested variant CASE; gap18 set-typed CASE labels (word-wise CmpSet). Corpus +16.

P3 — strict declaration order in bodies — 10e0951

Deferred bodies are now order-aware for this module's own data (variables/constants/types): SymTab declaration sequence + a window in Lookup; parser state moved so the parser obeys the rule. Forward procedure calls stay allowed (the generated parser relies on it; gm2's bootstrap link rejects FORWARD). Corpus −6 (intended: gm2 decl-order leniencies now correctly rejected).

P4 — the "size-sensitive" miscompile — a50fc6f (docs)

Not size-sensitive, not a codegen bug. ASTDUMP dumped the AST to stdout; built from its own sources that dump contained the driver's literal "Parsed correctly", and the fixpoint gate was grep -q Parsed — so the gate passed while the session reported Incorrect source. Removing the dump unmasked real errors (Lower's forward procedure calls), already fixed in a3ef897. Also corrected the stale note about the record-array-field codegen bug (38e0b54): it is fixed (hybrid ArrBodyItems), covered by t_arrrecfld/t_arrrecbig/t_nestarr.

gap14 + P5 — f53cdad

  • __BUILTIN__ / __ATTRIBUTE__ declaration pragmas parsed and ignored (builtin.def/.mod + 4 importers now compile).
  • docs/INDEX.md rewritten; 45 unreferenced historical files moved to docs/archive/ (all 69 cross-references kept valid).
  • gap13 remainder (standard built-ins as identifiers) documented and deliberately deferred: no corpus exemplar, and it needs a contextual-keyword rewrite of Fact/ArgList (Coco/R is LL(1)); a declaration-site-only measure would silently bind calls to the built-in.

Robustness — 3d58325

Table-limit overflows are now loud (230), not silent drops: the two-phase span table (used to silently drop a body's codegen — regression t_manyproc), the label/GOTO tables, the 32-actual AST buffer, and SymTab.MaxTypes. Corpus unchanged (no corpus file hits a limit).

Library — c7d5cff, d243d25

  • ISO 10514-1 ChanConsts + StreamFile on IOChan; PIM/gm2 NumberIO, RealInOut, FpuIO (new shim m2writefix).
  • Two real compiler bugs surfaced and fixed: cross-unit set CONSTs (emitted under the global name now) and qualified enum literals in set constants (Lower.EvalOrdConst).
  • Harness fidelity: corpus.sh now resolves V3's own shipped libraries by default (V3_LIBS), instead of mislabelling their imports LIB.

Corrections / lessons

  • The "size-sensitive miscompile" and the "still-open record-array-field bug" were both stale notes; both are resolved. Verify old findings before acting on them.
  • A weak success gate (grep -q Parsed) can mask real errors — the gate now greps Parsed correctly and fails on session errors.

Remaining (for a next session)

  1. Corpus LANG bucket — after the library work: undeclared identifier (gm2-only modules M2RTS/Builtins/Processes/… aside), not supported yet, invalid call. Triage the top kinds.
  2. Error recovery / message polish — dropped tokens cascade.
  3. gap13 refactor (optional, no corpus exemplar).
  4. STATUS.md "what remains" is the live list.

Nothing was pushed; origin/master is the previous commit.