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 | 254/254 |
fixpoint (bootstrap/fixpoint.sh) |
OK (3,882,337 B) | OK (3,930,173 B) |
corpus (tools/v3-corpus/corpus.sh) |
467/612 | 499/612, 0 crashes |
Reproduce:
cd compiler && ./build.sh && ./run_tests.sh # 254/254
cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh
tools/v3-corpus/corpus.sh # 499 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 | PACKEDSET, exceptions/UNIQUE, __FUNCTION__, PROC as a result type; sized SYSTEM types fixed below |
conforming clusters: arrays, subranges, ordinal FOR, empty string, libc prototypes, SYSTEM sized types |
32 | 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.
Three tagged states, each green on all gates:
| commit | tag | scope |
|---|---|---|
aa4f49b |
v3-corpus-triage |
multi-index arrays, typed subranges, ordinal FOR (+12) |
f87bcc9 |
v3-empty-string |
ISO empty string as CHAR (+6) |
c02fd41 |
v3-libc-prototypes |
typed libc prototypes, printf varargs (+6) |
libc, but most stop earlier on
declaration order, exceptions or sized types. Only 6 were blocked by
the missing prototypes.printf decision was a policy choice, not a technical one: the
permissive external already made statement calls work. Option 3
(function + allow discarding the result only for foreign C varargs)
keeps t_bad_funstmt and unlocks all 59 printf files.docs/gaps/README.md is still the place to record why a case is
rejected; the new entries state the fix and the remaining carve-out.SYSTEM — SymTab + grammarThe hard-coded SYSTEM module was not registered, so
SYSTEM.CARDINAL8 (qualified type access) was undeclared even though
FROM SYSTEM IMPORT CARDINAL8 worked. InitSystemModule now registers
a pseudo-module with its own scope and copies every predef type and
constant into it; TypeIdent's QualType and DesignTail's
MaterializeAlias then resolve SYSTEM.X normally. FROM SYSTEM
IMPORT stays permissive (its names are global predefs or keywords).
Added the ISO/gm2 names: WORD8/16/32/64, BITSET8/16/32,
REAL32/64/128, COMPLEX32/64/128, CSIZE_T/CSSIZE_T/COFF_T,
and BITSPERLOC/LOCSPERWORD/LOCSPERBYTE. V3 keeps its 32-bit
word model, so the narrow integer/word names share INTEGER/
CARDINAL and COMPLEX* is a REAL placeholder. Corpus +8:
compsize, int8field, returnrecord, printsize, testgeneric,
testgeneric2/3/4. Regression t_system.
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.PROC as a result type (testrecursive.def,
typeonly.def, procconv, procconv2); parser-level.SysClock — the stdlib stub lacks DateTime,
CanGetClock, GetClock, SetClock (testclock, testclock2).PACKEDSET, ISO exceptions/UNIQUE, __FUNCTION__ — each
one or two files; larger or gm2-flavoured.STATUS.md "what remains" is the live list.