summary_string-variant-nested.md 4.2 KB

Session summary — 2026-09-30 (b): constructors, corpus gaps, String/variant/nested

Suite 169/169; self-hosting fixpoint OK (image 2,754,353 bytes). master, tree clean except the user's uncommitted compiler/toto.mod.

This session closed the aggregate-constructor work and then knocked out nine corpus-driven gaps.

Steps, tags and headline commits

Step Tag Commit What
Constructor gaps v3-ctor-gaps 5a74f41 set fields, string fold, index-type arrays, MIN/MAX
Gaps 1–5 v3-gaps-1-5 619bff9 libc, enum/char sets, sized types, set builtins, forward types
This step v3-string-variant-nested 6882d63 String, variant assignment, nested modules, ADDRESS↔pointer
Summary v3-string-variant-nested-summary (this commit) session save

(Showcase20, v3-showcase20 / b0494da, opened the session.)

1. Constructor gaps (v3-ctor-gaps)

  • Set fields in record constructors (R{7, S{1,3,5}}); the global braceCls dispatch flag is saved/restored around a nested set constructor.
  • Constant string concatenation in constructor elements — arraytype {Hello + " " + World}: CONST string values, QbeGen.StrFold folds + on constants, and a string element expands into consecutive CHAR elements.
  • Index-type arrays ARRAY <ordinalType> OF T; enum values usable as array indices.
  • MIN/MAX over ordinal types, arrays and sets.

2. Gaps 1–5 (v3-gaps-1-5)

  1. FROM libc intrinsic — printf/exit/… import as permissive external C procedures (varargs, no result); string/CHAR-array actuals pass as descriptor+8 (SymTab.DeclareCProc/Varargs, QbeGen.CArg).
  2. SET OF enum and SET OF <char-range> (+ enum/BOOLEAN subranges); set span limit 256 → 65536.
  3. MIN/MAX for REAL/LONGREAL/LONGINT and gm2 sized names (LONGCARD, SHORTREAL, INTEGER8/16/32/64, CARDINAL8/…).
  4. INCL/EXCL statements and SHIFT/ROTATE expressions (QbeGen.SetClearBit/SetShift, bit-by-bit over a runtime amount).
  5. Module-level forward type references — a global may name a type declared further down; emission is deferred (FlushPend).

3. String / variant / nested / ADDRESS (v3-string-variant-nested)

  • Opaque/forward/undeclared aliases are pointer-like — ClassOf returns ClPtr for an unresolved alias, so Design/DeclVar/ ResClass/AssOrCall treat them as pointers. This is what gm2's opaque String needs: String is not built-in, it is an opaque type imported from a definition module (DynamicStrings, or a local opaque); an undeclared type name is an error, as in gm2.
  • Variant-record assignment — CopyRecord is a flat byte blit of TypeSize(t) (records are flat blobs; the only correct choice for overlapping variant fields); variant records are emitted as one zeroed blob. Previously q := r compiled but corrupted data.
  • Nested local MODULE — verified EXPORT lists, procedures, nested-nested modules and init bodies (already largely working).
  • ADDRESS ↔ pointer assignment — the ADDRESS checks now precede the pointer-subclass test in SymTab.Assignable (p := ADR(x)).

Corpus (with $V3_LIBS)

milestone testsuite stdlib
start of session 283 115
v3-ctor-gaps 301 115
v3-gaps-1-5 376 124
v3-string-variant-nested 395 131
after conformant String cleanup 392 127

CRASH 0 throughout. Remaining testsuite taxonomy: undeclared identifier 65, not supported yet 34, invalid call 27, incompatible assignment 12.

Tests (169, was 159)

New: t_ctor7 (set field + string fold), t_minmax, t_minmax2, t_libc, t_setops, t_fwdtype, t_variant2, t_string, t_addrptr, t_nestedmod.

Resume

cd .../m2compiler-V3
./bootstrap/fixpoint.sh                       # FIXPOINT OK
cd compiler && ./build.sh && ./run_tests.sh   # 169/169

Remaining (see docs/analysis_gaps.md)

GOTO/labels, result suffixes, generics, coroutines, multiple inheritance (deliberate), full forward variables, and the gm2-only library modules.