Procházet zdrojové kódy

docs: revise the resolve/check plan after starting it

Findings from scaffolding (branch resolve-check):
- the AST is not a typed IR: NkArray/NkRecord/NkPointer/NkEnum/
  NkTypeIdent/NkProcType are never built; constructed types live only
  in SymTab.  So the original step 2 (walk the type AST) had nothing to
  walk; type-constructor checks stay parse-time and are not a
  prerequisite.
- the forward mechanism is narrow: Design's fallback fires only inside
  a procedure and assumes a module-level variable declared later; it
  creates a placeholder symbol and FwdVarFlush patches it at module end.
  Confirmed empirically.

Revised order: scaffold (done) -> expressions/designators ->
statements/calls -> delete FwdVar -> cleanup.
Eric Streit před 2 dny
rodič
revize
83603ca671
1 změnil soubory, kde provedl 45 přidání a 8 odebrání
  1. 45 8
      docs/plan-resolve-check.md

+ 45 - 8
docs/plan-resolve-check.md

@@ -104,19 +104,23 @@ Branch `resolve-check` off `v3-generics-inc2`.
 1. **Scaffold**: add `proc Resolve(n: AST.Node)` (and helpers) in a new
    `Check.def`/`Check.mod`; call it from the driver between `Parse` and
    `Lower.LowerUnitNow`, gated by a flag.  It starts as a no-op.
-2. **Types**: move type-constructor checks (`Type`/`Array`/`Record`/
-   `Set`/`Pointer`) into `Check`, deleting them from the actions.  One
-   constructor kind per commit.
-3. **Expressions**: move `Expr`-family typing; store `AST.SetTy`;
-   make `Lower` read `AST.Ty`.
-4. **Statements & calls**: move assignment/control-flow/arity checks.
-5. **Forward rebind**: with names now bound late, delete the `Design`
+   **(done — `compiler/src/Check.*`, gate `-noresolve`, `50df067`.)**
+2. **Expressions & designators**: move the `Expr`-family typing and
+   `Design` name binding into `Check`; store the resolved symbol and
+   type on the AST node (new `AST` field); make `Lower` read them.
+   Forward references in a proc body (see §11) are *bound* here, not
+   patched.
+3. **Statements & calls**: move assignment/control-flow/arity checks.
+4. **Forward rebind**: with names now bound late, delete the `Design`
    forward branch, `FwdVarRef`/`FwdVarName`/`FwdVarType`/
    `FwdVarResolve`, `IsFwdVar` and its guards, the grammar's
    `FwdVarNote`/`FwdVarFlush`, and the `@` marker.
-6. **Cleanup**: try `-resolve`/legacy byte-compare over the suite to
+5. **Cleanup**: try `-resolve`/legacy byte-compare over the suite to
    prove equivalence, then remove the flag and the old path.
 
+(Step numbering changed 2026-10-15 — see §11.  Type-constructor checks
+are **not** a prerequisite and stay parse-time.)
+
 ## 7. Verification gates
 
 - **Fixpoint** `./bootstrap/fixpoint.sh` — byte-identical stage2/stage3.
@@ -152,3 +156,36 @@ and in `Expr`.
 
 Branch `resolve-check` off `v3-generics-inc2` (`ba9d042`).  Baseline:
 suite 190/190, fixpoint OK (3,472,663 bytes).  Start with §6 step 1.
+
+## 11. Revision 2026-10-15 — findings from starting the work
+
+Measured while scaffolding (branch `resolve-check`):
+
+- **The AST is not a typed IR.**  The parser never builds
+  `NkArray`/`NkRecord`/`NkPointer`/`NkEnum`/`NkTypeIdent`/`NkProcType`
+  (0 sites in `M2.atg` *and* `Lower.mod`); only `NkSubrange` and (one)
+  `NkSet` appear.  Constructed types live **only in SymTab** (resolved
+  `TypeIndex`), and `Lower` reads them from there.  So the original §6
+  step 2 ("walk the type AST") had no data to walk and would have
+  needed the parser extended to build a type AST first — a large
+  prerequisite that duplicates SymTab for no two-phase benefit.
+- **The forward mechanism is narrow.**  `Design`'s fallback fires only
+  inside a procedure (`SymTab.InProc()`), only for a name not found,
+  and assumes a **module-level variable declared later**.  It creates a
+  placeholder symbol (`FwdVarRef`, `ClPtr`-shaped) plus an `@`-marker
+  node, and `FwdVarFlush` (module end) patches the placeholder to the
+  real symbol/type before `Lower` runs.  Empirically:
+  `PROCEDURE P; BEGIN x := 7 END P; VAR x: INTEGER;` compiles, while a
+  never-declared `y` is 201.
+- **Consequence.**  Removing `FwdVar*` requires binding *after* the
+  unit's declarations are all parsed — i.e. the expression/statement
+  walk (new §6 steps 2–3) — and **not** the type-constructor checks,
+  which can stay parse-time indefinitely.  The AST *does* carry
+  expression structure (`NkDesignator`/`NkSelector`/`NkBinExpr`/
+  `NkIdent`/literals), and every type the walk needs is available in
+  SymTab, so a walk keyed on the AST + SymTab is the tractable target.
+- **What step 2 must add to `AST`**: a per-node resolved `TypeIndex`
+  (exists — `AST.SetTy`/`AST.Ty`) and, for an identifier/designator
+  base, its resolved symbol (needs a new field, or reuse the existing
+  node-id slot) so `Lower` can stop re-deriving.
+