# Session summary — 2026-10-16 (c): generics increment 3 Branch **`resolve-check`**, tree clean. Suite **211/211**; fixpoint **OK (3,702,885 bytes)**; corpus **372 OK / 0 crash**. Tags: `v3-generics-value-params`, `v3-generics-inc3`, `v3-generics-proc-params`. ## What inc3 added ISO 10514-2 refinement generics now accept **value** and **procedure** parameters, plus **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). ## Verification - Suite **211/211** (`BufProg`, `g_badbuf`, `SortProg`); forward tests, two-phase gates, and exit-code gates all green. - Fixpoint **OK** (3,702,885 bytes). - Corpus unchanged: **372 OK, 0 crash** (generics are not in the corpus). ## Remaining in the generics thread - A **richer constraint model** (e.g. "`T` must be ordinal") — next. - `GENERIC CLASS`; instance dedup; nested generics as actuals. ## 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 ```