Suite 56/56 (23 run — incl. 3 trap-aborts — + 33 reject). LL(1)-clean (only the known-benign TypeBlock warning).
The plan said array headers sit inline in records, but 3.1 shipped
nested separate objects — one type would then have two layouts
(silent corruption on cross-assigns). Locked instead: records are
flat blobs with scalars/sets inline, array fields as 8-byte
pointers to static descriptors, nested records inline, static
declaration-order offsets. Whole-record assignment is deep
(per-field copy, arrays via CopyArray), so no aliasing.
M2.atg)RecordType (+ RecField/RecIdents reusing the field
machinery, so classes share offsets for free); class fields
widened to full Type for the same reason.. suffixes mixing freely with [...]
(r.tags[i], m[i].x); 215 non-record, 216 unknown field.KindField designators resolve through the WITH stacks
(base + static offset, array fields auto-dereferenced like
nested levels); field use outside WITH/methods is still 230.WITH v [, ...] DO (215 on non-records): pushes fields
(inner wins) + bases, pops both exactly; nested and
field-designator (WITH r.org) forms work.Assign accepts field targets and copies records deep
(CopyRecord); whole-class assign is explicit 230; record/set
= is 213 (added to EqCheck); partial composites flow as
addresses in Fact (never scalar-loaded).TypeSize (inline footprint: arrays/pointers 8), lazy
declaration-order FieldOffset (+ rank for declaration-order
enumeration, invalidated on new fields), FieldOwner via a new
scope→record link, FieldCount/FieldName; nominal-cycle depth
guard (223 proper still deferred).
QbeGen)DeclRec (statics pre-pass + flat items; reverse-chain emission
walks declaration order via ranks), FieldAddr, WITH base stack,
CopyRecord (scalars/sets inline, arrays deep, records recurse).
TypeSize counted full array
sizes inside records while layout stores pointers — offsets
went wrong whenever an array field preceded others. TypeSize
is now the inline footprint (arrays 8) everywhere.t_record → 160 (nesting, array fields, deep-copy independence
via post-copy mutation, field-designator WITH), t_with → 114
(multi-designator shadowing, nested WITH); t_bad_field (216),
t_bad_with (215), t_bad_recassign (210). Total 56.
Deferred: variant records (Wirth has none — correctly absent),
WITH-field VAR actuals (needs calls, step 4), class lowering
(vtable/THIS), HIGH/LEN, 223 cycle errors.