|
|
@@ -0,0 +1,91 @@
|
|
|
+# Session summary — 2026-10-08 (b): generics increment 2
|
|
|
+
|
|
|
+Tag `v3-generics-inc2`, branch `generics-inc2` (off `generics-inc1`).
|
|
|
+Suite **190/190**; fixpoint **OK** (**3,472,663 bytes**).
|
|
|
+
|
|
|
+Increment 2 of ISO 10514-2 generics: a refinement now **instantiates**
|
|
|
+the generic by re-parsing its source with the type formals bound to the
|
|
|
+actuals — the design sketched in `docs/analysis_generics.md`.
|
|
|
+
|
|
|
+## 1. What the syntax does now
|
|
|
+
|
|
|
+```modula2
|
|
|
+GENERIC DEFINITION MODULE Ident (T : TYPE); (* the template *)
|
|
|
+PROCEDURE Id(x : T) : T;
|
|
|
+END Ident.
|
|
|
+
|
|
|
+DEFINITION MODULE IntId = Ident(INTEGER); (* a refinement *)
|
|
|
+END IntId.
|
|
|
+```
|
|
|
+
|
|
|
+`IntId` is now a real module: its `Id` takes/returns `INTEGER`. A
|
|
|
+program `FROM IntId IMPORT Id; … Id(42)` compiles and returns 42.
|
|
|
+
|
|
|
+## 2. How it works
|
|
|
+
|
|
|
+Increment 1 left: grammar recognition of the four generic module
|
|
|
+categories, formals entered as unresolved aliases (`EnterTypeParam`),
|
|
|
+and refinements recorded (`refInst`/`refGen`/`refActual`).
|
|
|
+
|
|
|
+Increment 2 adds the instantiation pass:
|
|
|
+
|
|
|
+- **Grammar** (`M2.atg`): an instantiation context
|
|
|
+ `instActive`/`instName`/`instActual[]`/`instFk`, with accessors
|
|
|
+ (`InstBegin`/`InstAddActual`/`InstEnd`/`InInst`) and unit/refinement
|
|
|
+ queries (`UnitNameGet`/`UnitIsGeneric`/`UnitIsDefModule`,
|
|
|
+ `RefineSeen`/`RefineIsDef`/`RefineInst`/`RefineGen`/`RefineActual*`),
|
|
|
+ exported via `parser.frm`. When `instActive`, `DefUnit`/`ImplUnit`
|
|
|
+ rename the module to `instName`, `GenericFormal` binds each formal to
|
|
|
+ the matching actual (`EnterTypeParamBound`), and the `END` name is
|
|
|
+ overridden.
|
|
|
+- **SymTab**: `EnterTypeParamBound` (a formal alias whose target is the
|
|
|
+ actual) and `Reenter` (re-enter an already-registered module scope —
|
|
|
+ the refinement registered `X` before the re-parse).
|
|
|
+- **Driver** (`compiler.frm`): records each generic def/impl *file*
|
|
|
+ (module name → path) when parsed and does **not** emit the abstract
|
|
|
+ template; on a refinement it re-opens the generic's file, sets the
|
|
|
+ instantiation context, re-parses, and lowers the resulting unit.
|
|
|
+
|
|
|
+## 3. Self-hosting constraints hit (and fixed)
|
|
|
+
|
|
|
+The self-hosted compiler is stricter than gm2; three fixes were needed:
|
|
|
+
|
|
|
+- helper procedures must be declared **before** their callers
|
|
|
+ (`CopyNm`) — moved the accessor block below it;
|
|
|
+- an **array element** may not be passed to a `VAR ARRAY OF CHAR`
|
|
|
+ formal, and an **open array** may not be assigned to a fixed array —
|
|
|
+ the registry copies element-by-element and looks up by index;
|
|
|
+- gm2 rejects an **anonymous fixed-size array** as a formal parameter
|
|
|
+ type — named types `GName`/`GPath` were introduced.
|
|
|
+
|
|
|
+## 4. Test
|
|
|
+
|
|
|
+`g_ident.def/.mod` (the generic `Ident(T)`), `g_intid.def/.mod`
|
|
|
+(`IntId = Ident(INTEGER)`) and `g_prog.mod` (`Id(42)`).
|
|
|
+`run_tests.sh`: `expect_run_files GenericProg 42 …` → PASS.
|
|
|
+
|
|
|
+## 5. Scope / remaining
|
|
|
+
|
|
|
+- Multiple formals and multiple actuals are threaded but only a single
|
|
|
+ `T` is exercised; `const`/procedure parameters and constraints are
|
|
|
+ increment 3.
|
|
|
+- Instance **dedup** is not implemented (each refinement re-instantiates).
|
|
|
+- `GENERIC CLASS`, and generics with a program module, are untouched.
|
|
|
+- The refinement file must appear **after** the generic's file in the
|
|
|
+ session (the registry is populated as files are parsed), and the
|
|
|
+ generic's def must precede its impl.
|
|
|
+
|
|
|
+## Resume
|
|
|
+
|
|
|
+```sh
|
|
|
+cd .../m2compiler-V3
|
|
|
+./bootstrap/fixpoint.sh # FIXPOINT OK
|
|
|
+cd compiler && ./build.sh && ./run_tests.sh # 190/190
|
|
|
+```
|
|
|
+
|
|
|
+## Files
|
|
|
+
|
|
|
+`compiler/src/M2.atg`, `compiler/src/parser.frm`,
|
|
|
+`compiler/src/SymTab.def`/`.mod`, `compiler/src/compiler.frm`,
|
|
|
+`compiler/tests/g_ident.*`, `g_intid.*`, `g_prog.mod`,
|
|
|
+`compiler/run_tests.sh`, this doc.
|