Просмотр исходного кода

docs: next-session handoff (P0 generics bug, corpus wins, gates)

Record the state (239/239, fixpoint 3,812,771, corpus 405/612), the
policy (follow Modula-2; decl-order/gm2-ext are not targets), and a
prioritised plan:
- P0 generics: two instantiations of one generic share the formal
  binding (likely SymTab.EnterTypeParamBound returning early when the
  formal is already visible) -- a real bug;
- P1 gap22 (__FILE__/__LINE__), gap09 (scalar -> ARRAY OF BYTE), set span;
- P2 variant arms, bare proc value, VAR-param leniency, standard builtins
  as identifiers (gap13 remainder), set CASE labels;
- P3 forward module variables/procedures (two-phase) -- architectural;
- P4 the size-sensitive miscompile; P5 housekeeping.

Indexed from docs/INDEX.md.
Eric Streit 7 часов назад
Родитель
Сommit
3b75399fda
2 измененных файлов с 109 добавлено и 0 удалено
  1. 2 0
      docs/INDEX.md
  2. 107 0
      docs/handoff-2026-10-18-next.md

+ 2 - 0
docs/INDEX.md

@@ -6,6 +6,8 @@ bisecting *why* a decision was made, not for reading end-to-end).
 
 ## Start here
 
+- **`handoff-2026-10-18-next.md`** — next-session plan (P0 generics bug,
+  corpus wins, structural gaps, gates).
 - **`STATUS.md`** — current state, architecture, what remains.
 - **`plan.md`** — the phased plan (Blaise-adapted).
 - **`features.md`** — the feature list.

+ 107 - 0
docs/handoff-2026-10-18-next.md

@@ -0,0 +1,107 @@
+# Next session — handoff (2026-10-18)
+
+State: branch **`resolve-check`**, tree clean.  Suite **239/239**,
+fixpoint **OK (3,812,771 bytes)**, corpus **405/612, 0 crashes**.
+Tags include `v3-enum-import`, `v3-ordl`, `v3-showcase24`,
+`v3-convert`, `v3-set-word`, `v3-strict-decl-order`, `v3-m2-conformance`,
+`v3-gap-examples`.
+
+## Policy (decided)
+
+Follow **Modula-2**, not gm2 degradation: declaration before use (only a
+`POINTER`'s base may forward-reference).  `docs/gaps/` classifies every
+remaining case; **`decl-order` and `gm2-ext` are not targets** (gm2
+accepts non-conforming code; V3 correctly rejects it).  The corpus is
+gm2's testsuite, so its number mixes both; the **`undeclared identifier`
+bucket (44) is now inflated by the decl-order files** — don't chase it
+blindly.
+
+The corpus harness now resolves **transitive** imports (2026-10-18); that
+is the measurement method from here.
+
+## P0 — generics: two instantiations of one generic (a real bug)
+
+`analysis_gaps.md` §10: instantiating one generic twice with arguments
+from different families fails on the second instantiation
+(`GStack(INTEGER)` + `GStack(CHAR)` → `incompatible assignment` at
+`n^.val := v`); `INTEGER`+`CARDINAL` passes only because the wrong
+binding still type-checks.  Each type argument alone works.
+
+**Likely culprit:** `SymTab.EnterTypeParamBound` (SymTab.mod ~line 675):
+
+```mod
+IF Lookup(name) AND (SymKind(name) = KindType) THEN RETURN TRUE END;
+```
+
+During an instantiation re-parse the formal is already visible, so it
+returns **without rebinding** to the new actual — the first
+instantiation's binding sticks.
+
+*First steps:* reproduce with a five-file session (`GBox(T)` generic
+def/mod + two instantiations + a program); check how the driver
+establishes the scope for each re-parse (`InstBegin`/`Reenter`, compiler
+frame); make the formal binding per-instantiation (fresh alias), then
+add a regression test (two instantiations, distinct scalar families) and
+re-run fixpoint (generics are used in the compiler's own generics
+tests, not its source).
+
+## P1 — quick, bounded corpus wins
+
+- **`gap22` `__FILE__`/`__LINE__`** (`packed`): gm2 predefined
+  constants; `__`/`_` are not legal identifier chars in V3.  Either add
+  the two pseudo-constants or leave as `gm2-ext` (+1 file).
+- **`gap09` scalar actual into `ARRAY OF BYTE`** (gm2's untyped byte
+  buffer; `aochar`, `arrayofbyte`, `bytearray`): accept a scalar/
+  `ADDRESS` actual for an `ARRAY OF BYTE`/`VAR ARRAY OF BYTE` formal by
+  passing its address (+ ~3 files).
+- **`gap16`/`gap17` set span**: raise the cap / handle `SET OF CARDINAL`
+  (low value).
+
+## P2 — structural (parser / semantics)
+
+- **`gap12` variant records**: empty variant arms, `ELSE`, untagged
+  inner `CASE` (`varient2/3/8`, `tsize`/`2`).
+- **`gap11` bare procedure value as a statement** (`tinyproc2/4`).
+- **`gap10` `VAR` actual type leniency** (gm2 same-size rule;
+  `testparam2/3`) — decide whether to adopt it (non-standard).
+- **`gap13` remainder**: the *standard* built-ins (`ORD`, `CHR`, `VAL`,
+  `MOD`, …) are still Coco/R keyword tokens; de-reserving them needs
+  contextual-keyword parsing (predeclared identifiers).  `ORDL` (the
+  corpus case) is done.
+- **`gap18` set-typed `CASE` labels** (`bitset5`).
+
+## 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; decide
+whether to pursue (high risk, touches self-hosting).  The declaration
+part itself is already strict.
+
+## P4 — latent correctness
+
+The **size-sensitive V3 miscompile** (historical "removing `ASTDUMP`
+breaks the fixpoint") is still unroot-caused.  Worth a dedicated
+bisection session: it is a correctness landmine, unlike the remaining
+language gaps.
+
+## P5 — housekeeping
+
+- Consolidate `docs/summary_*.md` (see `docs/INDEX.md`).
+- Decide merge/push of `resolve-check` (no pushes so far).
+
+## Gates for every step
+
+`./build.sh`, `./run_tests.sh` (must stay 100%), `bootstrap/fixpoint.sh`
+(**byte-identical**), `corpusx.sh` (record OK/CRASH + note), update
+`docs/gaps/` + `STATUS`/`README`, commit with a `v3-*` tag.
+
+## Resume
+
+```sh
+cd .../m2compiler-V3
+git checkout resolve-check
+cd compiler && ./build.sh && ./run_tests.sh   # 239/239
+cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh
+M2FLAGS="" ./.scratch/corpusx.sh              # 405 OK, 0 crash
+```