# Next session — plan (from 2026-10-22 stop point) **Branch:** `master` (tree clean at the stop point). **Feature state:** `v3-smallfix`. **Gates:** suite **259/259**, fixpoint **OK (4,028,447 bytes)**, corpus **511/612, 0 crashes**. Read first: `docs/STATUS.md` (live state), `docs/features.md`, `docs/gaps/README.md` (policy + reproducers), and `docs/summary_session-2026-10-22.md` (what the last session did). ## Policy reminder V3 follows **PIM/ISO Modula-2**, not gm2's leniencies. Declaration before use is required for data; the only forward type reference is a `POINTER`'s base. gm2 compatibility is accepted only where explicitly chosen and documented (`docs/gaps/README.md`). The corpus is gm2's testsuite, so `LANG` includes deliberate rejections; classify before fixing. ## 1. `PACKEDSET` — 3 corpus files (`onebyte`, `onebyte2`, `onebyte3`) ISO 10514-1 has `PACKEDSET OF `; XDS states that the standard does not mandate a representation and treats sets/packedsets the same. Options: - **Minimal:** parse `PACKEDSET` as `SET` (the XDS interpretation) and document that the representation is not bit-packed. This compiles the three files but `onebyte*` may test `SIZE`/bit layout — inspect first. - **Faithful:** add a packed representation (1/2/4-byte masks), which means new set ops at byte granularity in `QbeGen` and type sizing. Suggested decision: inspect `onebyte*`; if they only use set operations (not `SIZE`-sensitive), map to `SET` and document. Add a regression. ## 2. ISO exceptions — 7 corpus files (`except2/4/5/7/8/9`, `lazyunique`) This is a **feature**, not a parser tweak: - `EXCEPT` / `RETRY` after a normal statement sequence (procedures and module bodies); - `EXCEPTIONS` (AllocateSource/RAISE/CurrentNumber/GetMessage/ IsCurrentSource/IsExceptionalExecution) and `M2EXCEPTION`; - runtime support (handler stack / `setjmp`-`longjmp` or equivalent); - `lazyunique` also needs ISO `UNIQUE` module support. Design a minimal handler model first (one active handler per procedure, exception state per coroutine, re-raise on unhandled), then implement. Budget a dedicated session; do not start it as a "small fix". ## 3. Multi-dimensional open arrays — 8 corpus files `unbounded`, `unbounded2/3/4/6/8`, `array9`, `adrunbounded3`. **Do not just accept them**: V3 represents each array level as its own descriptor, while gm2 passes a flat block with strides. The corpus files check `ADR(m) = ADR(m[0]) = ADR(m[0][0])` and flat `SIZE` values, so compiling them would silently miscompile. Next step is an **ABI decision**: - keep the nested-descriptor model and add a flat/strided open-array descriptor for multi-dimensional formals (real work), or - document the limitation and leave this bucket parked. `unbounded5` is different: a type declared after its use (decl-order gap), not this feature. ## 4. Runtime subrange range checks — conformance V3 accepts base-typed values into CHAR/enum subranges (2026-10-22) but emits no runtime range check, and is already lenient for the integer family. Add `QbeGen.CheckRange` on assignment / parameter binding / `RETURN` where the destination is a subrange, with an `abort` trap; add trap tests (like `t_trap_index`). This is the main remaining conformance difference from the subrange work. ## 5. Optional / larger - **ISO 10514-3 OO** vs the Clarion-form `CLASS`. Large; only if OO conformance becomes a goal. - **A real `stdlib/libc.def`** instead of the built-in prototype table. Not needed for the corpus; useful for user code (`DEFINITION MODULE FOR "C"`, varargs, `SYSTEM.CSIZE_T`). - **Small corpus leftovers** (classify first): `ptrarray3` (open-array actual), `unbounded7` (2-D actual for `ARRAY OF BYTE`), `adraddress` (ADDRESS/pointer compare), `proc` (decl-order), `shift3/4` (decl-order), `constprocedure`/`constvec3`/`conststrarray` (mostly ordered decls). ## Known non-targets / parked - gm2 extensions: `ASM`, address arithmetic, absolute `VAR [addr]`, `666B`/`012H` literals, `SHORTREAL` as 32-bit, char arithmetic, set ordering (`largeset5`), module named `CHAR`. - decl-order cases (gaps 01–06, 19–21) — V3 rejects them by policy. - wide sets (`settest1/3`): implementation limit (span > 65536). - `CHAR.mod`: a module named `CHAR` collides with the pervasive type. ## Gates for every step ```sh cd compiler && ./build.sh && ./run_tests.sh # must stay 100% cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh tools/v3-corpus/corpus.sh # record OK/CRASH ``` Then update `docs/STATUS.md`, `docs/features.md`, `docs/gaps/` and the comparison table, and commit with a `v3-*` tag. Do not push without asking; tags are immutable per feature. ## Resume ```sh cd .../m2compiler-V3 git checkout master cd compiler && ./build.sh && ./run_tests.sh # 259/259 cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh tools/v3-corpus/corpus.sh # 511 OK, 0 crash ``` **Recommendation:** start with `PACKEDSET` (after inspecting `onebyte*`), then the subrange range checks; reserve a whole session for ISO exceptions, and make an explicit ABI decision before touching multi-dimensional open arrays.