|
|
@@ -0,0 +1,58 @@
|
|
|
+# Generics — closing summary (2026-10-16)
|
|
|
+
|
|
|
+Branch **`resolve-check`**, tree clean. Suite **214/214**; fixpoint
|
|
|
+**OK (3,710,201 bytes)**; corpus **372 OK / 0 crash**.
|
|
|
+
|
|
|
+## Supported today
|
|
|
+
|
|
|
+ISO 10514-2 **refinement generics**, instantiated by re-parsing the
|
|
|
+generic source with a substitution scope, driven by the session driver.
|
|
|
+
|
|
|
+| Feature | Syntax | Notes |
|
|
|
+| --- | --- | --- |
|
|
|
+| Type parameters | `MODULE Box (T : TYPE)` | `Box(INTEGER)` |
|
|
|
+| Value parameters | `MODULE Buf (size : CARDINAL)` | `Buf(10)`; template binds a placeholder |
|
|
|
+| Procedure parameters | `MODULE Sort (E : TYPE; Compare : PROCEDURE(a,b : E) : INTEGER)` | actual is `Mod.Proc` |
|
|
|
+| Constraints | `MODULE OrdBox (T : TYPE (ORDINAL))` | `ORDINAL`, `INTEGER`, `REAL`, `POINTER`, `SCALAR` |
|
|
|
+| Multiple parameters | `MODULE Pair (T : TYPE; U : TYPE)` | both bound |
|
|
|
+| Nested generics | `MODULE WrapB = Wrap(IntBox.Box)` | an instance's exported type as an actual |
|
|
|
+| Def + impl | `DEFINITION`/`IMPLEMENTATION MODULE X = G(...)` | both required; template not emitted |
|
|
|
+
|
|
|
+Constraints and actual-kind are checked at instantiation (`233` on
|
|
|
+mismatch). Suite: `GenericProg`, `PairProg`, `BufProg`, `g_badbuf`,
|
|
|
+`SortProg`, `OrdProg`, `g_realbox`, `GWrapProg`.
|
|
|
+
|
|
|
+## Mechanism (recap)
|
|
|
+
|
|
|
+- Driver records each generic's def/impl file; on a refinement re-opens
|
|
|
+ it, sets the instantiation context, re-parses and lowers the unit.
|
|
|
+- Formals bind via `SymTab.EnterTypeParamBound` (types),
|
|
|
+ `SetSymVal` on a `CONST` (values), or `SymTab.AliasProc` +
|
|
|
+ `Lower.AliasProc` (procedures; `ProcBaseByUid` fixes mangling after
|
|
|
+ the instance scope is popped).
|
|
|
+- Qualified actuals (`Mod.Name`) are classified as proc or type, which
|
|
|
+ is how both procedure parameters and nested generics reach a name
|
|
|
+ without an import.
|
|
|
+
|
|
|
+## Deliberately not done
|
|
|
+
|
|
|
+- **Instance dedup** — not needed: each refinement declares its own
|
|
|
+ module (`BoxA = OrdBox(INTEGER)`, `BoxB = OrdBox(INTEGER)` coexist
|
|
|
+ cleanly; verified). The only "same instance twice" case is a
|
|
|
+ refinement's DEFINITION and IMPLEMENTATION, which must instantiate
|
|
|
+ the generic's def and impl respectively.
|
|
|
+- **`GENERIC CLASS`** — needs a **design decision**, not extension: the
|
|
|
+ current machinery instantiates *modules* by re-parsing a source file.
|
|
|
+ A generic *class* has no natural refinement form yet (a class is a
|
|
|
+ type declared inside a module; instantiating it would re-parse its
|
|
|
+ enclosing module, or require a `TYPE C = GClass(args)` type-refinement
|
|
|
+ affordance). Until that syntax is chosen, this stays open.
|
|
|
+
|
|
|
+## Résumé
|
|
|
+
|
|
|
+```sh
|
|
|
+cd .../m2compiler-V3/compiler
|
|
|
+./M2 tests/g_ordbox.def tests/g_ordbox.mod tests/g_intbox.def \
|
|
|
+ tests/g_intbox.mod tests/g_wrap.def tests/g_wrap.mod \
|
|
|
+ tests/g_wrapb.def tests/g_wrapb.mod tests/g_wrapprog.mod # GWrapProg -> 42
|
|
|
+```
|