|
|
@@ -111,9 +111,13 @@ Done:
|
|
|
1. Builtin statements (`EXIT`, `INCL/EXCL`, `INC/DEC`, `NEW`, `DISPOSE`).
|
|
|
2. Control flow (`IF`/`WHILE`/`REPEAT`/`LOOP`/`FOR`/`CASE`), `RETURN`,
|
|
|
`HALT`.
|
|
|
+3. Declarations/lifecycle: `DeclVar`/`DeclConst`, the module/impl/
|
|
|
+ nested/class `BeginInit`/`EndInit`/`BeginBody`/`EndModule`,
|
|
|
+ `FlushPend`, `FwdPatch`. (This exposed and fixed a real bug — see
|
|
|
+ below.)
|
|
|
|
|
|
Still to do:
|
|
|
-3. **Expressions / `Fact` / `Term` / `SimExpr` / `Expr`: BLOCKED.**
|
|
|
+4. **Expressions / `Fact` / `Term` / `SimExpr` / `Expr`: BLOCKED.**
|
|
|
Their `QbeGen` calls are not (only) inline emit — they are the
|
|
|
front-end **constant evaluator**. `Expr`'s `q` is handed to
|
|
|
`SymTab.SetSymVal` and `Lower.NoteConstVal` for a CONST, and
|
|
|
@@ -125,33 +129,37 @@ Still to do:
|
|
|
constants itself from the AST (a real change, not cleanup), then
|
|
|
dropping the grammar's value layer. Designators are entangled the
|
|
|
same way (`qn`/`NoteAddr` feed VAR-actual addresses).
|
|
|
-4. **Calls, declarations, proc headings, imports, classes: BLOCKED
|
|
|
- too, by fused validation.** The `QbeGen` emit functions double as
|
|
|
- semantic checks and the grammar depends on their result:
|
|
|
- `QbeGen.CallArg` (`IF NOT … THEN SemError(233)`), `AddrOfVal`
|
|
|
- (VAR-actual address + 233), `FuncParam` (`IF NOT …` on a heading).
|
|
|
- Removing the calls would remove error detection, so this needs the
|
|
|
- checks reimplemented in `SymTab`/the grammar first — again a real
|
|
|
- change, not cleanup. Only the genuinely pure emitters
|
|
|
- (`Jmp`/`EmitLabel`/`NewLabel`/`SetBit`/`NewHeap`/`DeclVar`/… when
|
|
|
- not used as a check) can be dropped.
|
|
|
-5. Retire the `-lower` test flag and the now-degenerate byte-compare
|
|
|
+5. **Calls, proc headings, imports, classes: BLOCKED too, by fused
|
|
|
+ validation.** The `QbeGen` emit functions double as semantic
|
|
|
+ checks and the grammar depends on their result: `QbeGen.CallArg`
|
|
|
+ (`IF NOT … THEN SemError(233)`), `AddrOfVal` (VAR-actual address +
|
|
|
+ 233), `FuncParam` (`IF NOT …` on a heading). Removing the calls
|
|
|
+ would remove error detection, so this needs the checks
|
|
|
+ reimplemented in `SymTab`/the grammar first — again a real change,
|
|
|
+ not cleanup.
|
|
|
+6. Retire the `-lower` test flag and the now-degenerate byte-compare
|
|
|
tests in `run_tests.sh`.
|
|
|
-6. Remove the dead scaffolding: `LowerSession`, `MaterializeGlobals`,
|
|
|
+7. Remove the dead scaffolding: `LowerSession`, `MaterializeGlobals`,
|
|
|
`SaveSession`/`RestoreSession` and the `SetNoEmit` machinery (once
|
|
|
nothing emits inline), plus the dead `SetLower`/`lowerRequested`.
|
|
|
|
|
|
Note: full deletion to zero is gated on moving constant folding into
|
|
|
-`Lower` (item 3). Until then the expression/value layer stays.
|
|
|
-
|
|
|
-Attempted and reverted (2026-10-08): deleting the grammar's
|
|
|
-`QbeGen.DeclVar` (in `VarDecl`) is **not** safe. It makes `Lower`
|
|
|
-resolve one local to a global (`Showcase11`: the `src` VAR actual in
|
|
|
-`Strings.Replace` becomes `$Strings_nl`), reproducibly, even though
|
|
|
-`Lower.mod` and the AST are unchanged — another instance of the
|
|
|
-layout-sensitive latent bug class this project has hit before.
|
|
|
-`QbeGen.DeclConst` removal alone is fine; `DeclVar` stays until that
|
|
|
-bug is understood.
|
|
|
+`Lower` (item 4). Until then the expression/value layer stays.
|
|
|
+
|
|
|
+### Fixed (2026-10-08): the note ring leaked the grammar's notes into Lower
|
|
|
+
|
|
|
+Removing `QbeGen.DeclVar` from `VarDecl` had made `Lower` resolve one
|
|
|
+VAR actual to the wrong symbol (`Showcase11`: `Strings.Replace`'s `src`
|
|
|
+became `$Strings_nl`). Root cause: `QbeGen.AddrOfVal` scans the whole
|
|
|
+256-entry `nVal`/`nAddr` VAR-actual note ring, and `RestoreSession`
|
|
|
+restored `nn` but never cleared the ring — so 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
|
|
|
+`Lower`'s own key. Removing `DeclVar` (fewer `AllocLocal`/`NewTemp`
|
|
|
+calls) shifted those keys and exposed it. `RestoreSession` now clears
|
|
|
+the ring; `Lower` re-notes its own VAR actuals, so an empty ring is
|
|
|
+correct. The fix is output-neutral on `Showcase11` and corrects some
|
|
|
+latent resolutions in the compiler's own image (fixpoint size moved).
|
|
|
|
|
|
|
|
|
## Are we near completion?
|