Suite 50/50 (21 run — incl. 3 trap-aborts — + 29 reject). LL(1)-clean (only the known-benign TypeBlock warning).
Sets are memory addresses (globals or alloc8 temps), never
scalars — uniform with arrays. No header (size is static);
W words of bitmask, bit v-lo. Unrolled straight-line word code
everywhere (counts static, deterministic).
M2.atg)SetType: SET OF bool/char/bounded-subrange (span ≤ 256);
enums wait for ordinals, INTEGER is unbounded → 230.SetLit/SetElem in Fact: literals are SET OF [0..255]
(8 words); elements int/char/bool, folded values checked
0..255 statically (222), computed values trap via SetBit;
ranges always lower via SetRange (literals validated, inverted
runtime ranges are naturally empty, like FOR 5 TO 1).+ - * / branch to union/difference/intersection/symdiff when
both sides are sets (result spans max, typed exactly so
downstream word counts match allocations); IN added to Rel
(mismatch → 222); set =/# via word-wise CmpSet; CASE
labels reject sets (arrays/strings already 213 themselves).Assign copies sets (CopySet with dst/span word counts).QbeGen, all probed first)DeclSet, NewSetTemp (alloc8, 8-rounded), SetZero,
SetBit/SetRange (span traps), SetBinOp (overlap via op,
larger-side extras copied or zeroed), CmpSet (min words +
zero-check extras), CopySet (min-word memcpy, zero-fill,
trap when src extras beyond dst are nonzero — narrowing
{100} into SET OF [0..7] aborts instead of silently
dropping bits), InSet (bit test + span trap).
Probe facts reused: alloc8, shr/shl, strict width checking
(a mixed-width mul in the probe failed loudly — hence
WidenIndex everywhere).
SubBounds/SetBase/SetWords/SetBaseLo/SetCount; SetBasesOk
accepts any two suitable bases (masks compare over min words);
InCheck accepts small int/char/bool against suitable sets.
Static 222s stay for what is known bad (out-of-span literals,
non-sets in IN); the runtime trap catches the rest.
t_set → 131 (all four ops, IN, =/#, empty, var index),
t_setchar → 77 (word-3 bits), t_setrange → 55 (ranges, var
element, empty compare); t_bad_setelem/t_bad_in → 222,
t_bad_setbase → 230; t_trap_setspan → abort (rc=134).
Deferred: enum bases (ordinals), string =/+, multi-word
performance (unrolled is fine for now), CHAR-bound subtleties.