summary_step3.1.md 3.1 KB

V3 step 3.1 — arrays: bounded/open, strings, whole assign (done 2026-09-20)

First of four phased composite substeps (arrays → records → sets → pointers). Suite 42/42 (16 run — incl. 2 trap-aborts — + 26 reject), LL(1)-clean (only the known-benign TypeBlock warning).

Type syntax (M2.atg)

  • Type gains allowOpen and ArrayType: "ARRAY" "OF" Type (open formal; 230 elsewhere incl. named open aliases) and "ARRAY" "[" bounds "]" "OF" Type (multi-index sugar nests inside-out via NestArray). Bounds are folded int/char literals (ConstInt, inverted → 230); bare-type indices wait for enum ordinals; VarDecl takes full Type<FALSE> (anonymous arrays in VAR); formals take Type<TRUE>; composite function results are 230 (V2 parity).
  • Coco/R V1.53 cannot parse dotted types (SymTab.BoundsArr) in attribute declarations (generates garbage), so bounds accumulate SymTab-side (BoundBegin/BoundAdd/NestArray, max 8).
  • Design grows index suffixes ([i, j] descends nested levels; 217/218) plus an sfx out-flag; Fact loads indexed elements (ElemLoad) and lowers string literals to descriptors (1-char stays CHAR, '' works); Assign copies whole arrays (CopyArray) or stores elements (ElemStore, with ConvIR for r[i] := 3); array/string = is 213 (strict Wirth; done in EqCheck, so CASE labels agree).

Layout (locked rule, now real)

DeclArr emits data $a = { l n, … } with CHAR→b, int/bool/enum→w, REAL→d, nested/pointer→l, all zero; nested levels are separate $a_i objects linked by address (probes proved l $sym in data, copy $sym addressing, loadub, blit-class ops). Indexes widen to LONGCARD (extsw), check lo..hi (static, or 0..count-1 for open via OpenHi), trap via call $abort() + hlt (rc=134; interim until runtime/syslib/Trap).

Backend lessons (all probed, not guessed)

  • QBE blit needs a constant length → whole copies use call $memcpy(l dst, l src, l n) (runtime length, uniform for fixed/open/nested; nested recurses through a runtime loop).
  • QBE call needs per-argument classes (call $f(l a, …)); bare $abort() is fine.
  • Single-letter %p temporaries mislink — always %tN (already the convention; now recorded).
  • String data must be top-level: literals buffer during the body and flush at EndModule (a data line mid-function is a QBE syntax error — found the hard way).

SymTab (additive)

Bounded/open descriptors (NewArrayB/OpenArray, alo/ahi), IsOpenArray/ArrayLo/Hi/Len/Depth, ConstInt reuse; Assignable tightened (array↔array by SameType, string→1-D-CHAR-array only); EqCheck rejects array/string =.

Tests

t_array → 108 (named + anonymous arrays, nested m[i,j], whole + nested copies, strings, char compare); t_bad_index (218), t_bad_bounds (inverted → 230), t_openformal/t_bad_open (open rules); new expect_trap harness (rc=134): index breach and "abcd"-into-3 count mismatch.

Deferred: HIGH/LEN (need calls, step 4), string =/+, string CONSTs, enum/char-subrange bounds as index types, CHAR-bound subtleties, open-formal reads (parse-only now).