summary_session-2026-10-22.md 5.1 KB

Session 2026-10-22 — corpus triage: three conforming clusters

Branch master. Continues summary_session-2026-10-19.md; the only plan source was its "Remaining" list (corpus LANG triage).

Numbers

gate session start end
suite (compiler/run_tests.sh) 249/249 252/252
fixpoint (bootstrap/fixpoint.sh) OK (3,882,337 B) OK (3,906,044 B)
corpus (tools/v3-corpus/corpus.sh) 467/612 485/612, 0 crashes

Reproduce:

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

Triage method

The 118 LANG entries were compiled one at a time (a single-file version of corpus.sh), and each first diagnostic was read against its source line. They fall into these buckets:

bucket count verdict
imports libc but uses a libc function as a value (printf/malloc) ~48 libc prototypes missing; V3's permissive FROM libc IMPORT has no result type, so expression use is invalid call
declaration order (type/const/var used before its declaration) ~25 correctly rejected (docs/gaps/); not a target
gm2 extensions (ASM, '' NUL char, 666B, absolute VAR [addr]) ~7 not a target unless chosen
ISO features actually missing ~20 sized SYSTEM types (WORD32/BITSET32/qualified SYSTEM.CARDINAL8), PACKEDSET, exceptions/UNIQUE, __FUNCTION__, PROC as a result type
conforming clusters: arrays, subranges, ordinal FOR, empty string 18 fixed this session

What landed

PIM/ISO multi-index arrays — compiler/src/M2.atg

ARRAY [0..1], [0..2] OF T is the standard spelling (17 corpus files use it; none use V3's single-bracket comma list). ArrayType now parses one bracket group per dimension ({ "," "[" ... "]" }) and appends every group's bounds before the element type; nesting stays inside-out, so the layout matches ARRAY [0..1] OF ARRAY [0..2] OF T. The old ARRAY [0..1, 0..2] OF form still works. Corpus +6: arraybool, assignment2, foo, recordarray2, tinyarray4/5. Regression t_multidim.

Subranges keep their ordinal base — SymTab, grammar

A subrange was always FSub with no base descriptor, so ClassOf returned ClInt for ['A'..'Z'] and [red..blue]: assigning a CHAR/enum literal (or comparing with one) failed. SymTab.NewSubB stores the base when both bounds have the same type; ClassOf, SubBounds, SetSpan/BaseSpanOk and the set-span check now follow it. Assignable/EqCheck/OrdCheck accept a base value against a subrange of the same CHAR/BOOLEAN/enum base (two different enums stay incompatible). Corpus +3: subrange16, subrange17, enum3. Regression t_subrange. Assignment range checks remain (future) — V3 is already lenient for the integer family.

FOR over ordinals + typed MIN/MAX of sets — grammar

FOR accepted only the integer family. It now accepts any ordinal control variable (bounds must be assignment-compatible with it), which covers enums and CHAR. MIN/MAX of a SET now yields the set's base type instead of INTEGER, so FOR i := MIN(S) TO MAX(S) binds (the bound was previously INTEGER against an enum i). Corpus +3: forloop2, smallset4, minmax.

ISO empty string literal — SymTab + grammar + Lower

ISO makes the empty string literal ("" / '') length 0 and compatible with CHAR, where its value is the terminator. V3 typed it as an ordinary string, so ch := "", ch = "", CASE ch OF "", FOR ch := "" TO …, a CHAR formal actual, and RETURN "" either failed (incompatible assignment/comparison, invalid Fact) or stored a descriptor address.

SymTab.NewEmptyStr marks the literal's type (tlo = -2); it is still ClStr, so ARRAY OF CHAR contexts keep working (s := "", s = "", t_strempty). Assignable/EqCheck accept it against CHAR, and Lower substitutes the value 0 when the context is a character (assignment, relation, CASE label, FOR bound, value actual, RETURN). Corpus +6: arraychar, arraychar2, arraychar3, nulcharcase, nulcharvar, forloopnulchar. Regression t_emptychar.

Remaining (for a next session)

  1. libc.def — the single biggest corpus bucket (~48 files). A minimal definition module (exit, printf, malloc, write, …) needs the grammar to prefer it over the permissive FROM libc IMPORT path, plus a varargs marker for printf. This is library work with a real payoff.
  2. ISO SYSTEM sized types — WORD32/WORD16/WORD8 and BITSET8/16/32/64 are missing, and qualified SYSTEM.CARDINAL8 does not resolve (predefs live in the global scope, not a SYSTEM module). ~8 files.
  3. PACKEDSET, ISO exceptions/UNIQUE, __FUNCTION__ — each one or two files; larger or gm2-flavoured.
  4. Runtime subrange range checks — the remaining conformance difference from this session's subrange work.
  5. STATUS.md "what remains" is the live list.