Branch resolve-check. Suite 225/225; fixpoint OK
(3,823,438 bytes); corpus 387/612 compile-OK, 0 crashes.
Tag: v3-set-constants.
Landed set constants — the first of the two features recorded in
docs/analysis_gaps.md §9 — from the previous corpus sweep.
CONST Digits = CharSet{"0".."9"}; (* char range *)
Signs = CharSet{'+', '-'};
NumCh = Signs + Digits; (* union of two set constants *)
Warm = CS{Red, Blue}; (* enum base *)
Corpus 382 → 387 (+5 files: setconst, setconst2, and 3 more),
0 crashes. New suite tests t_setconst (run, exit 42) and
t_bad_setconst (reject, 230).
A set literal is emitted as a runtime temp (NewSetTemp/SetZero/
SetBit), so a set CONST had no static value; accepting the
declaration produced a 230 rather than a miscompile (see the previous
sweep's finding). Sets are also addresses of memory words, so the
constant must be a real data symbol.
The fix computes the bit mask at parse time — where the element
values are known and validated — and has Lower re-emit it as a pooled
static descriptor:
Lower.SetConstMaskOf (exported) folds a set expression to
(mask, words, lo): set literals (NkSetLit/NkBraceLit), char /
integer / named-CONST elements, a..b ranges, and +/-/*//
over two foldable set operands (union / difference / intersection /
symdiff), plus + - * DIV MOD on element ordinals.ConstDecl (grammar) calls it for ClSet; on success it records the
mask (Lower.NoteSetMask) and lets the constant be an aggregate; on
failure it stays a clear 230.Lower.LowerDecls looks the mask up by name and calls the new
QbeGen.PoolSet, which registers data $setN = { w mask0, ... } and
returns its address. FlushSets emits the pool in EndModule.Design and Lower's LowerDesign now treat a
ClSet KindConst as an aggregate: its value is the descriptor
address (so c1 := Digits, c IN Digits work).Bound: masks are folded up to 16 words (512 bits); a wider SET
CONST stays a 230 (MaxCFoldW). The corpus set constants are
≤ 8 words.
setconst3.mod still fails: its VAR mem: ARRAY [0..CARDINAL(
addressLines)] names a CONST declared after the VAR (a forward
CONST reference), which is a separate gap. Its SET CONST itself now
parses.CONST (CAP(VAL(CHAR,65)), MIN/MAX of
sets) — still the second recorded feature; fold builtins over
immediates.compiler/src/Lower.{def,mod} (evaluator + PoolSet call),
compiler/src/QbeGen.{def,mod} (PoolSet/FlushSets/pool state),
compiler/src/M2.atg (ConstDecl, Design),
compiler/tests/t_setconst.mod, compiler/tests/t_bad_setconst.mod,
compiler/run_tests.sh.
cd .../m2compiler-V3
git checkout resolve-check
cd compiler && ./build.sh && ./run_tests.sh # 225/225
cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh
M2FLAGS="" ./.scratch/corpusx.sh # 387 OK, 0 crash