Branch ast-stage-c. Tag v3-lower7-flip.
This session did three things: (1) flipped the emitter so Lower is
the only active emitter, (2) deleted the inline emit from the
statement and declaration productions, and (3) started the value/emit
decoupling so expression emit could go too — in the process it found
and fixed a real latent bug in the VAR-actual note ring.
Everything is verified with compiler/run_tests.sh (204/204) and
bootstrap/fixpoint.sh (FIXPOINT OK) after every step.
857c221)The driver (compiler/src/compiler.frm) now always runs the per-unit
Lower emit: BeginSession/BeginUnit/LowerUnitNow/EndSession.
The grammar's inline emit is still present but runs suppressed
(SetNoEmit) and is discarded. -lower is now test-only — it does not
change what is emitted, only names the image <mod>L.ssa for the
byte-compare harness.
This was a no-op flip because Lower had already been verified
byte-identical to the legacy inline emit on every single-file test and
every session.
FIXPOINT OK, 3,553,701 bytes.
| commit | production group |
|---|---|
e5830b2 |
builtin statements (EXIT, INCL/EXCL, INC/DEC, NEW, DISPOSE) |
ce37247 |
control flow (IF/WHILE/REPEAT/LOOP/FOR/CASE), RETURN, HALT |
acc4e91 |
declarations/lifecycle (DeclVar/DeclConst, module/impl/nested/class BeginInit/EndInit/BeginBody/EndModule, FlushPend, FwdPatch) |
Not mechanical: many QbeGen.* calls are semantic queries or parser
state, not emit (TopLoop/PushLoop/PopLoop, TopWith/PushWith,
IsImm/Fold2/NormInt, LocFull, ConstInt, …) and must stay.
7de78bb)Removing the grammar's QbeGen.DeclVar exposed a latent mis-resolution:
Strings.Replace's src VAR actual became $Strings_nl, so Showcase11
no longer linked.
Root cause: QbeGen.AddrOfVal scans the whole 256-entry nVal/nAddr
VAR-actual note ring, and RestoreSession restored nn but never
cleared the ring. The grammar's suppressed parse-time NoteAddr
entries survived into Lower; their keys are temps that restart per
function, so a stale entry could false-match. Removing DeclVar (fewer
AllocLocal/NewTemp calls) shifted those keys and exposed it.
Fix: RestoreSession clears the ring. Lower re-notes its own VAR
actuals, so an empty ring is correct. The fix is output-neutral on
Showcase11 and corrected some latent resolutions in the compiler's own
image.
| commit | removed |
|---|---|
d730e80 |
LowerSession, LowerUnit, the whole Can* family, SetLower/lowerRequested |
e269828 |
QbeGen's CloseModule, FwdPatch, FwdElemPatch, Remark |
241c2c9 |
SymTab's CurModule/CurUnit/ProcDepth/ParamName/ModDefined/ModImplemented/Qual*/NestArray/NewSub/SetElemCheck/SetFor/UnaryCheck/FwdVarKind, QbeGen.StrLen |
b0ef2bf |
AST.TxtLen, AST.SetKind (AST.AddChild stays: t_ast.mod uses it) |
A scan over src/, tests/, runtime/, stdlib/, tools/ now reports
no unreferenced procs in AST/SymTab/QbeGen/Lower.
Still needed until the inline emit is gone:
SaveSession/RestoreSession/SetNoEmit, and
MaterializeGlobals/MaterializeReplace (live, from LowerOneUnit).
The expression value is also the front-end's constant value (Expr's q
feeds SymTab.SetSymVal/Lower.NoteConstVal and IsImm/ConstInt), so
it cannot simply be dropped. The decoupling marks runtime results with a
non-constant sentinel "@" (IsImm/ConstInt reject it), keeps
constant folding (NegFold/Fold2/StrFold) and every check.
| commit | production |
|---|---|
6001af6 |
SimExpr (unary -, OR, UString/CHAR concat, set binops, arithmetic) |
5fb26e7 |
Term (AND, set intersection, * / DIV MOD) |
4f2afa0 |
Expr relation (=,#,<,<=,>,>=,IN) |
d469c78 |
Fact's always-runtime branches (ResultComp ElemLoad, zero-arg calls, ADR, SHIFT/ROTATE, open-array HIGH/LEN, CHR8 range check) |
Constant-producing builtins (fixed-array HIGH/LEN, SIZE/TSIZE,
MAX/MIN, ORD/CHR/VAL, …) keep their folding paths.
Design → Fact → ArgList → ActParam plus the NoteAddr/
AddrOfVal chain must move as one unit: Fact records
NoteAddr(q, qd)/AddrOf(qn, qa) and ActParam recovers the VAR-actual
address with AddrOfVal(qe, qa), and the note key is the actual's
emitted value. Verified: dropping ArgList's CallBegin alone (fewer
NewTemps) shifts the keys and breaks calls (75 suite failures). To
finish: Design emits nothing (literal for a constant, "@" otherwise),
Fact drops the notes, ActParam replaces AddrOfVal with an
AST-kind addressability check and drops CallArg, then ArgList drops
CallBegin/CallEnd; afterwards NoteAddr/AddrOfVal/AddrOf in
QbeGen are dead.
Then: retire the -lower test flag and the now-degenerate byte-compare
tests, and delete SaveSession/RestoreSession/SetNoEmit.
| step | bytes |
|---|---|
| flip | 3,553,701 |
| statements + declarations + bug fix | 3,538,557 |
| dead-code sweep | 3,420,733 |
| value/emit decoupling (expr layer) | 3,406,951 |
The functional goal — Lower is the only emitter — is met. The rest
is architecture/cleanliness.