Procházet zdrojové kódy

docs: expression types stored; forward tolerance is a tested feature

Records the findings from step 4a: Lower constructs types while emitting
(no dedup), so a type is constructed once and cached on the AST node the
parser already builds; AST.Ty defaults to -1 so Lower can read it with a
fallback.  The forward tolerance is a tested feature (t_fwdvar.mod,
Showcase22, incl. array-index selectors) - an experiment to remove it
failed those tests, so FwdVar* can only go with genuine late binding.
The missing split piece is a designator resolver (Check runs it after
resolving forwards and stores the type on the node).
Eric Streit před 2 dny
rodič
revize
06efe9a55e
1 změnil soubory, kde provedl 26 přidání a 0 odebrání
  1. 26 0
      docs/plan-resolve-check.md

+ 26 - 0
docs/plan-resolve-check.md

@@ -225,4 +225,30 @@ Measured while scaffolding (branch `resolve-check`):
   statement checks moved out of the actions, i.e. the walk, still
   blocked on `Lower`'s type/emit split.
 
+- **2026-10-15 (`5703b27`, step 4a)** — expression types are now stored
+  on the AST (`SetTy` at the Expr/SimExpr/Term/Fact levels).  Findings
+  that shape the split:
+  - `Lower.LowerExprFull` **constructs** types while emitting
+    (`NewStr`/`NewUStr`/`NewSet`/`NewSubR`) and those do **not** dedup
+    (`NewDesc` always allocates).  A type must therefore be constructed
+    exactly once and cached on the node; the parser *already* computes
+    (and for literals constructs) the same type at parse time — now
+    stored — so `Lower` can read `AST.Ty(n)` instead of reconstructing,
+    which also removes a duplicate construction per string/set literal.
+  - `AST.Ty` defaults to `-1` (= `InvalidType`), so "unset/unknown" is
+    distinguishable from a real index; `Lower` can read it with a
+    fallback while the split is in progress.
+  - the forward **tolerance is a tested feature**: `tests/t_fwdvar.mod`
+    (and `Showcase22`) rely on a procedure body referencing a
+    module-level variable declared later — including through an
+    **array-index selector** (`label[0] := "o"`).  An experiment that
+    replaced the tolerance with an immediate 201 failed exactly those
+    two tests.  So `FwdVar*` can only go once `Design`'s binding is
+    genuinely late, and the walk must keep forward refs *with selectors*.
+  - **the missing piece of the split** is a designator *resolver*: the
+    type half of `LowerDesign` (~line 690), which `Check` would run
+    after resolving forward references and store on the node
+    (`AST.SetTy`) for `Lower` to read.  Designator nodes are the only
+    expressions whose parse-time type is `-1` (forward/undefined).
+