127/127 tests green (120 + 5 run + 2 rejection; v_bad_var repurposed),
mc64 boot + example green, Showcase still 157.
Accept a[i], p^ and record fields as VAR actuals (error 233 since
step 4), using the dormant scaffolding (ActIsVarNext, per-actual frame
slots). Keep every old suite green with zero behavior change outside
VAR-want position.
MGen: ActFrame.addrs[] (per-actual stashed address temp, -1 when
unused); StashAddr (DUP + temp-store at the Fact tail, where the
address is complete but not yet loaded — uniform for [], ^ and
. tails); ClrStash (invalidates on any value-combining action);
ActValue takes the stashed address for VAR formals (address already
on top for whole array/record actuals, else drop value + reload stash).M2c.atg: Fact tail stashes when tailed + ActIsVarNext() + head is
Var/Param/VarPar/Field + head is not a module + final type is not
CHAR/BOOLEAN; ClrStash() at every combining site (Rel/AddOp/MulOp
actions, unary neg, NOT, literals, HIGH, call results, set elements).run_tests.sh: step-8 sections added.5 run: v_idx 35 (a[2], a[4]), v_deref 105 (p^.val),
v_field 1031 (r.b.v), v_rec 16 (whole r.b to VAR record formal),
v_row 21 (matrix rows to VAR open-array formal). 3 rejections, each
exactly one error: v_bad_var 233 (repurposed: P(a[i]+1) — operators
defeat the stash), v_bad_byte 233 (CHAR elements are byte-packed, no
valid slot address), v_bad_with 233 (WITH-field actuals).
Bonus finding: row-to-VAR-open works, free of charge.
P(a[i]+1) first compiled (stash from a[i])
because nothing invalidated the address when +1 followed. Every
value-combining action now calls ClrStash(); direction of error is
safe (a missed site would only cause a loud 233, and the audit covered
all Fact alternatives, all operator loops, NOT, HIGH, call
results and set elements; parens stay transparent).WITH-field VAR actuals (233), CHAR/BOOLEAN elements or fields as
VAR actuals (233, byte-packing), module vars as VAR actuals (233),
type exports, DEFINITION/IMPLEMENTATION split, module BEGIN bodies.