Branch master. Continues summary_session-2026-10-19.md; the
only plan source was its "Remaining" list (corpus LANG triage).
| gate | session start | end |
|---|---|---|
suite (compiler/run_tests.sh) |
249/249 | 253/253 |
fixpoint (bootstrap/fixpoint.sh) |
OK (3,882,337 B) | OK (3,919,695 B) |
corpus (tools/v3-corpus/corpus.sh) |
467/612 | 491/612, 0 crashes |
Reproduce:
cd compiler && ./build.sh && ./run_tests.sh # 253/253
cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh
tools/v3-corpus/corpus.sh # 491 OK, 0 crash
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 were missing; fixed below (the rest fail later for other reasons) |
| 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, libc prototypes |
24 | fixed this session |
compiler/src/M2.atgARRAY [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.
SymTab, grammarA 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 — grammarFOR 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.
SymTab + grammar + LowerISO 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.
libc prototypes — SymTab + Lower + grammarFROM libc IMPORT P used to declare every name as a permissive
no-result varargs external, so printf/malloc/write in an
expression were invalid call. The known C functions now get real
signatures from a built-in table (DeclareCProc/CProto):
printf/snprintf are varargs functions with an ARRAY OF CHAR
format, the rest have typed formals/results (exit none, write/
read/open/close/lseek, malloc, memcpy/memset/strncpy,
system/getenv, atof/strtod). Lower.NoteCProc copies the
signature into its proc table.
Discarding the result of a call in statement position is now allowed
only for foreign C varargs (printf/snprintf) — the documented
compatibility carve-out. An ordinary Modula-2 function used as a
statement is still 233 (t_bad_funstmt). Corpus +6:
procedure2, tinyparam, tinyparam2, sizes, variant9,
varient (except5 now stops on ISO exceptions). Regression
t_libc2.
libc.def — the built-in prototype table covers the
common functions; a definition module (or DEFINITION MODULE FOR
"C") would let users extend it. Not needed for the corpus now.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.PACKEDSET, ISO exceptions/UNIQUE, __FUNCTION__ — each
one or two files; larger or gm2-flavoured.STATUS.md "what remains" is the live list.