# Session summary — 2026-10-16 (c): generics increment 3 Branch **`resolve-check`**, tree clean. Suite **213/213**; fixpoint **OK (3,706,134 bytes)**; corpus **372 OK / 0 crash**. Tags: `v3-generics-value-params`, `v3-generics-inc3`, `v3-generics-proc-params`, `v3-generics-constraints`. ## What inc3 added ISO 10514-2 refinement generics now accept **value** and **procedure** parameters, an **explicit constraint model**, and **actual-kind constraints**. ### 1. Value (constant) parameters ```modula2 GENERIC DEFINITION MODULE Buf (size : CARDINAL); TYPE T = ARRAY [0..size] OF CHAR; END Buf. DEFINITION MODULE Buf10 = Buf(10); END Buf10. ``` `GenericFormal` collects its names, then takes `: TYPE` (type formal) or `: TypeIdent` (value formal). `Actual` accepts an integer, `charConst`, or an identifier. Refinement actuals carry a **kind** (0 type / 1 value / 2 proc) and a **value text** (`refKind`/`refVal`, `instKind`/`instVal` + accessors). A value formal binds to a `CONST` with the actual value at instantiation; in the **abstract template** it is a `CONST` placeholder (`"0"`) — templates are never lowered, so only instances matter. Verified with two instances of different sizes. ### 2. Actual-kind constraints At instantiation the actual's kind must match the formal: a type formal needs a type actual, a value formal a value actual, else `233` (`g_badbuf`). ### 3. Procedure parameters ```modula2 GENERIC DEFINITION MODULE Sort (Element : TYPE; Compare : PROCEDURE(a, b : Element) : INTEGER); PROCEDURE Smaller(x, y : Element) : Element; END Sort. DEFINITION/IMPLEMENTATION MODULE IntSort = Sort(INTEGER, Cmp.IntCompare); ``` The formal's type is an inline `ProcType`; the actual is a **qualified** procedure name (the refinement parses actuals before any import, so qualification is the only way to reach a proc without one). In the template the formal is a proc-typed callable (the body checks, via an indirect call there); at instantiation it is aliased to the actual: - `SymTab.AliasProc(formal, mod, actual)` — clones the actual's `SymNode` under the formal's name (keeps `uid`/`mod`/`sym`). - `Lower.AliasProc(...)` — a **scope-neutral proc-table entry**, because `Lower` resolves call targets from its own table, not `SymTab` (the first attempt emitted `call $Compare`, an unresolved symbol). - `SymTab.ProcBaseByUid` + a uid→base map, so `QbeGen.Mangled` recovers the base name after the instance scope has been popped. Refinement forms also accept `{ Import }` now. Verified end-to-end (`Smaller(7,3)` through `IntSort`, `IntCompare` in a separate module, returns 3). ## 4. Constraint model A type formal may carry an explicit constraint: ```modula2 GENERIC DEFINITION MODULE OrdBox (T : TYPE (ORDINAL)); TYPE Box = ARRAY [0..3] OF T; END OrdBox. DEFINITION MODULE IntBox = OrdBox(INTEGER); (* ok *) DEFINITION MODULE RealBox = OrdBox(REAL); (* rejected: 233 *) ``` `GenericFormal`'s `TYPE` branch takes an optional `( name )`; `ConsCode` maps `ORDINAL`/`INTEGER`/`REAL` → 0/1/2/3 and `ConsOk` tests the actual (`ORDINAL` → `SymTab.IsOrdinal`; `INTEGER` → `ClInt`; `REAL` → `ClReal`). The constraint is read from the formal's source on **both** passes (template and re-parse), so no extra state is needed. Verified: `OrdBox(INTEGER)` compiles and runs (`b[0]+b[3]` → 42); `OrdBox(REAL)` is rejected. ## Verification - Suite **213/213** (`BufProg`, `g_badbuf`, `SortProg`, `OrdProg`, `g_realbox`); forward tests, two-phase gates, and exit-code gates all green. - Fixpoint **OK** (3,706,134 bytes). - Corpus unchanged: **372 OK, 0 crash** (generics are not in the corpus). ## Remaining in the generics thread - `GENERIC CLASS`; instance dedup; nested generics as actuals; further constraint names (`POINTER`, `SCALAR`). ## Resume ```sh cd .../m2compiler-V3/compiler ./M2 tests/g_cmp.def tests/g_cmp.mod tests/g_sort.def tests/g_sort.mod \ tests/g_isort.def tests/g_isort.mod tests/g_sortprog.mod # SortProg -> 3 ./M2 tests/g_buf.def tests/g_buf.mod tests/g_buf10.def \ tests/g_buf10.mod tests/g_bufprog.mod # BufProg -> 42 ./M2 tests/g_ordbox.def tests/g_ordbox.mod tests/g_intbox.def \ tests/g_intbox.mod tests/g_ordprog.mod # OrdProg -> 42 ```