Sfoglia il codice sorgente

generics: option C strengthened - generic class with value-param-sized field

Suite GStkProg: a generic class whose array field is sized by a value
parameter and whose element is the type parameter, instantiated via a
generic module (GStk(INTEGER,4)); HIGH(a)=4, rc 42. Documents the
pattern's small print (class in a TYPE block; CLASS IMPLEMENTATION
needs a trailing ';'; class-impl BEGIN cannot assign fields).

Suite 216/216; fixpoint OK.
Eric Streit 18 ore fa
parent
commit
6b148fbf31

+ 2 - 0
compiler/run_tests.sh

@@ -294,6 +294,8 @@ expect_run_files GWrapProg 42 \
   g_wrap.def g_wrap.mod g_wrapb.def g_wrapb.mod g_wrapprog.mod
 expect_run_files GCBoxProg 42 \
   g_gcbox.def g_gcbox.mod g_gcint.def g_gcint.mod g_gcprog.mod
+expect_run_files GStkProg 42 \
+  g_gstk.def g_gstk.mod g_gstki.def g_gstki.mod g_gstkp.mod
 expect_run_files WrapProg 42 \
   ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
   ../stdlib/iochan.def ../stdlib/iochan.mod \

+ 8 - 0
compiler/tests/g_gstk.def

@@ -0,0 +1,8 @@
+GENERIC DEFINITION MODULE GStk (T : TYPE; cap : CARDINAL);
+TYPE
+  CLASS Stk;
+    a : ARRAY [0..cap] OF T;
+    PROCEDURE Capacity() : INTEGER;
+    PROCEDURE Put(x : T);
+  END Stk;
+END GStk.

+ 8 - 0
compiler/tests/g_gstk.mod

@@ -0,0 +1,8 @@
+GENERIC IMPLEMENTATION MODULE GStk;
+CLASS IMPLEMENTATION Stk;
+  PROCEDURE Capacity() : INTEGER;
+  BEGIN RETURN HIGH(a) END Capacity;
+  PROCEDURE Put(x : T);
+  BEGIN a[0] := x END Put;
+END Stk;
+END GStk.

+ 2 - 0
compiler/tests/g_gstki.def

@@ -0,0 +1,2 @@
+DEFINITION MODULE GIntStk = GStk(INTEGER, 4);
+END GIntStk.

+ 2 - 0
compiler/tests/g_gstki.mod

@@ -0,0 +1,2 @@
+IMPLEMENTATION MODULE GIntStk = GStk(INTEGER, 4);
+END GIntStk.

+ 4 - 0
compiler/tests/g_gstkp.mod

@@ -0,0 +1,4 @@
+MODULE GStkProg;
+IMPORT GIntStk;
+VAR s : GIntStk.Stk; ExitCode : INTEGER;
+BEGIN s.Put(9); ExitCode := s.Capacity() + 38 END GStkProg.

+ 21 - 10
docs/summary_generics-closed-2026-10-16.md

@@ -61,17 +61,28 @@ mismatch).  Suite: `GenericProg`, `PairProg`, `BufProg`, `g_badbuf`,
   ```
 
   So **no standalone `GENERIC CLASS` syntax is required** for the
-  capability.  Standalone syntax would only matter if a class must be
-  instantiated *without* a whole generic module; the principled form
-  for that is a **type refinement** (`TYPE IntStack = Stack(INTEGER);`),
-  which mirrors `MODULE X = G(args)` at type level but needs the
-  class's `CLASS IMPLEMENTATION` block re-parsed/renamed per instance —
-  a design of its own.  Recommendation: keep the generic-module pattern.
+  capability.  It also composes with the increment-3 features: suite
+  `GStkProg` instantiates a class whose **array field is sized by a
+  value parameter** and whose element is the type parameter:
 
-  Minor asymmetry noted: a class is accepted as a top-level item in an
-  IMPLEMENTATION/program `DeclSeq` but not in a DEFINITION unit's item
-  list (only inside a `TYPE` block) — harmless, but a tidy-up
-  candidate.
+  ```modula2
+  GENERIC DEFINITION MODULE GStk (T : TYPE; cap : CARDINAL);
+  TYPE
+    CLASS Stk;
+      a : ARRAY [0..cap] OF T;
+      PROCEDURE Capacity() : INTEGER;
+    END Stk;
+  END GStk.
+  (* class impl: *)  PROCEDURE Capacity() : INTEGER; BEGIN RETURN HIGH(a) END Capacity;
+  DEFINITION/IMPLEMENTATION MODULE GIntStk = GStk(INTEGER, 4);   (* HIGH(a)=4 *)
+  ```
+
+  Small print for the pattern: a class must be declared **inside a
+  `TYPE` block** (a bare `CLASS` item is not accepted in a DEFINITION
+  unit's item list); the `CLASS IMPLEMENTATION` block is a `DeclSeq`
+  item, so it needs a **trailing `;`**; and a class impl's `BEGIN`
+  initialiser cannot assign a *field* (only module globals) — so
+  field state must be set by a method, as above.
 
 ## Résumé