handoff-2026-10-23-next.md 8.1 KB

Next session — plan (from 2026-10-23)

Branch: master. Feature state: v3-exceptions + v3-ptrchain + v3-function-exception + v3-finally + open-array M1/M2/M3/M4. Gates: suite 295/295, fixpoint OK (3,480,366 bytes), corpus 518/612, 0 crashes.

Read first: docs/STATUS.md, docs/features.md, docs/gaps/README.md, docs/summary_session-2026-10-23-exceptions.md.

Policy reminder

V3 follows PIM/ISO Modula-2, not gm2 leniencies. Declaration before use is required for data; only a POINTER's base may forward-reference. gm2 compatibility is accepted only where documented in docs/gaps/.

1. PACKEDSET — done (spans ≤ 32 bits)

Implemented 2026-10-23: 1/2/4-byte storage, SIZE/ORD, INCL/EXCL/ IN, assignment, set operations, packed arrays/records/parameters. Wider packed sets are a loud 230 implementation limit. Regression t_packedset.

The corpus files onebyte, onebyte2, onebyte3 still do not compile, but the blocker is earlier: they use the module variable r inside assert before its declaration (declaration order, rejected by policy). With r moved before the procedure they compile and run. Do not relax declaration order for this corpus case.

2. ISO exceptions — done (v3-exceptions)

A dedicated feature session, not a small fix. The design is in docs/design-exceptions.md (grammar/AST, handler stack, sigsetjmp/ siglongjmp codegen, EXCEPTIONS/M2EXCEPTION, trap mapping, tests).

M1 parser/AST — done (2026-10-23). EXCEPT/RETRY are reserved words; bodies carry NkExcept/NkRetry; RETRY outside a handler is error 237.

M2 runtime/codegen — done (2026-10-23). Handler stack + saved state, m2_exc_push/leave/retry/raise, sigsetjmp dispatch, EmitRet pops, m2_exc_init in main, SYSTEM.THROW, and basic SIGSEGV/SIGFPE mapping. Positive tests: t_except_parse, t_except_throw, t_except_retry, t_except_return, t_except_nested, t_except_module, t_except_signal; negative t_retry_bad (237).

M3 libraries — done (2026-10-23). SysExceptions, EXCEPTIONS and M2EXCEPTION are implemented in runtime/syslib/SysExceptions.* and stdlib/{exceptions,m2exception}.*. t_except_lib covers RAISE, CurrentNumber, GetMessage, IsCurrentSource, IsExceptionalExecution, wrong-source exException, and M2Exception after SYSTEM.THROW.

M4 language traps — done (2026-10-23). TrapCode, CheckIndex vs CheckRange, CASE caseSelectException, and unhandled-exception abort (rc 134). Tests: t_except_trap, t_except_case, t_except_unhandled.

M5 finalization — done (2026-10-23). Session summary summary_session-2026-10-23-exceptions.md; feature tag v3-exceptions at 02b3763, session-end tag at the docs commit. Optional follow-ups: coroutine/protection exceptions.

Corpus reality: lazyunique now compiles and runs (rc=0, unique output 0, 2, 1) after the pointer-chain follow-up; the corpus count stays 512 because it was already compile-OK. Regression t_ptrchain covers the self-referential record layout and p^.next^.value path. except2/4/5/7/8/9 still fail declaration order because ip is declared after the procedures, like onebyte*; keep moved-ip copies as semantic tests but do not count them in the corpus until the policy changes.

3. Multi-dimensional open arrays — design ready

See docs/design-open-arrays.md. Chosen ABI: per-level view descriptors over one contiguous flat backing block, with payload SIZE/ADR semantics for multi/open arrays. Full scope: fixed/open 2-D and 3-D, VAR, subarray views, row → 1-D, 2-D → ARRAY OF BYTE, records/constructors.

M1 — type/ABI helpers — done (2026-10-23). ArrayRank, IsMultiArray, ArrayLeafBytes, ArrayStride, ArrayPayloadSize; MaxDefer 512 and the session SSA buffer 8 MiB.

M2 — fixed multi storage — done (2026-10-23). Static and local rank-2/3 arrays now use one contiguous payload plus a chain of 40-byte views {count, elemBytes, stride, base, next}. ViewIndex yields subviews or final element addresses; pointer-to-multi indexing and NEW/local initialization work. Whole-array copies handle new views and old nested static constructors (CopyOldNestedToView). A temporary copy-in/copy-back adapter maps rank-1 row views to the legacy 1-D descriptor for fixed/open formals; this was required by the compiler's own files[n]/symSet[...] uses and is not the final M3 ABI. Multi-dimensional record fields still use the legacy nested layout; t_nestarr is unchanged. Regression t_multidim_local was added. Suite 284/284, fixpoint OK, corpus 512/612, 0 crashes.

Corpus: unbounded, unbounded2/3/4/6/8, array9, adrunbounded3. Do not just accept the files; the ABI and ADR(m) = ADR(m[0]) checks must be real. unbounded5 remains a declaration-order case. Next is M3 — open view descriptors — done (2026-10-23). Nested open-array formals parse; fixed/open rank-2/3 arrays and rank-2/3 subviews are passed as ArrayView pointers; open multi formals index through count/stride/base/next; HIGH/LEN read the view count; VAR and value open multi calls share the view (no payload copy). Row → 1-D and ARRAY OF BYTE conversions still use the legacy descriptor adapter, now with copy-back for VAR and free after the call; migrating the 1-D descriptor itself is M4. Tests: t_open2d*, t_open3d*, t_open_row_to_1d, t_open_flatten_byte; corpus 518/612.

M4 — array builtins — done (2026-10-23). SIZE/TSIZE use payload bytes for fixed/open/multi arrays; ADR returns the view base for multi views/rows and the payload base for 1-D open descriptors, while fixed 1-D arrays keep their descriptor address. External 1-D compatibility descriptors now include the CHAR/UCHAR terminator. Tests: t_open2d_size, t_open2d_adr, t_open1d_size_adr; unbounded3 runs with 60/12/2/2. Suite 295/295, fixpoint 3,480,366 bytes, corpus 518/612. Remaining: pointer-based 1-D view migration (row ADR identity through an internal 1-D call) and M5 records/constructors.

4. Runtime range checks — done, follow-ups

Lower.CheckSub covers assignment, value actuals, RETURN and INC/DEC; the FOR final increment is exempt. Possible follow-ups:

  • LONGINT/CARDINAL subranges (currently skipped);
  • FOR control variables (decide whether to range-check the initial bound only, as now);
  • trap tests for CHAR/enum subranges (currently integer).

5. Library folders / separate compilation — deferred plans

  • docs/plan-separate-compilation.md — stable symbols, per-unit objects, init order, linker; and the appendix on dialect folders.
  • Library-folder layout (lib/pim, lib/iso, lib/m2r10, shared runtime/syslib) is a low-risk build change, to do after the compiler language work; no need to mix dialects in one session.

6. Corpus leftovers (classify first)

ptrarray3 (open-array actual), unbounded7 (2-D actual for ARRAY OF BYTE), adraddress (ADDRESS/pointer compare), proc / shift3 / shift4 (decl-order), constprocedure/constvec3/ conststrarray (mostly ordered decls). Park gm2 extensions, wide sets (settest1/3) and CHAR.mod as before.

Gates for every step

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

Update STATUS.md, features.md, gaps/, the comparison table and a session summary; commit with a v3-* tag. Do not push without asking.

Resume

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

Recommendation: take the multi-dimensional open-array ABI decision, or start the separate-compilation/library-folder work. FINALLY/module termination is now implemented. Library folders and separate compilation remain deferred (docs/plan-separate-compilation.md).