Kaynağa Gözat

generics: nested generics as type actuals + more constraint names

- Actual: a qualified actual Mod.Name is classified as a procedure
  (Mod.Proc) or a type (Mod.Type), so an instance's exported type can
  feed another generic: WrapB = Wrap(IntBox.Box). Verified end-to-end
  (suite GWrapProg, rc 42).
- Constraints: add POINTER (ClPtr) and SCALAR (ordinal or real).

Suite 214/214; fixpoint OK; corpus unchanged (372 OK, 0 crash).
Eric Streit 1 gün önce
ebeveyn
işleme
b00def2975

+ 3 - 0
compiler/run_tests.sh

@@ -289,6 +289,9 @@ expect_run_files SortProg 3 \
   g_cmp.def g_cmp.mod g_sort.def g_sort.mod g_isort.def g_isort.mod g_sortprog.mod
 expect_run_files OrdProg 42 \
   g_ordbox.def g_ordbox.mod g_intbox.def g_intbox.mod g_ordprog.mod
+expect_run_files GWrapProg 42 \
+  g_ordbox.def g_ordbox.mod g_intbox.def g_intbox.mod \
+  g_wrap.def g_wrap.mod g_wrapb.def g_wrapb.mod g_wrapprog.mod
 expect_run_files WrapProg 42 \
   ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
   ../stdlib/iochan.def ../stdlib/iochan.mod \

+ 28 - 3
compiler/src/M2.atg

@@ -448,6 +448,8 @@ PROCEDURE ConsCode (nm: ARRAY OF CHAR): INTEGER;
     IF SymTab.Equal(nm, "ORDINAL") THEN RETURN 1
     ELSIF SymTab.Equal(nm, "INTEGER") THEN RETURN 2
     ELSIF SymTab.Equal(nm, "REAL") THEN RETURN 3
+    ELSIF SymTab.Equal(nm, "POINTER") THEN RETURN 4
+    ELSIF SymTab.Equal(nm, "SCALAR") THEN RETURN 5
     END;
     RETURN 0
   END ConsCode;
@@ -459,6 +461,14 @@ PROCEDURE ConsOk (cons: INTEGER; t: SymTab.TypeIndex): BOOLEAN;
     ELSIF cons = 1 THEN RETURN SymTab.IsOrdinal(t)
     ELSIF cons = 2 THEN RETURN SymTab.ClassOf(t) = SymTab.ClInt
     ELSIF cons = 3 THEN RETURN SymTab.ClassOf(t) = SymTab.ClReal
+    ELSIF cons = 4 THEN RETURN SymTab.ClassOf(t) = SymTab.ClPtr
+    ELSIF cons = 5 THEN
+      RETURN (SymTab.ClassOf(t) = SymTab.ClInt)
+          OR (SymTab.ClassOf(t) = SymTab.ClChar)
+          OR (SymTab.ClassOf(t) = SymTab.ClBool)
+          OR (SymTab.ClassOf(t) = SymTab.ClEnum)
+          OR (SymTab.ClassOf(t) = SymTab.ClUChar)
+          OR (SymTab.ClassOf(t) = SymTab.ClReal)
     END;
     RETURN TRUE
   END ConsOk;
@@ -681,6 +691,9 @@ PRODUCTIONS
                                              aKind: INTEGER;
                                              amod: SymTab.Name;
                                              nm2: SymTab.Name;
+                                             qu, qd: CARDINAL;
+                                             qr: SymTab.TypeIndex;
+                                             qe: BOOLEAN;
                                              k: CARDINAL; .)
     =                                   (. isV := FALSE; at := SymTab.InvalidType;
                                            nm[0] := CHR(0); nm2[0] := CHR(0);
@@ -695,9 +708,21 @@ PRODUCTIONS
                                         (. isV := FALSE; at := SymTab.InvalidType;
                                            aKind := 0; amod[0] := CHR(0);
                                            IF nm2[0] # CHR(0) THEN
-                                             (* qualified procedure actual:
-                                                Mod.Proc, no import needed *)
-                                             aKind := 2;
+                                             (* qualified actual Mod.Name:
+                                                a nested instance's type
+                                                (Mod.Type) or a procedure
+                                                (Mod.Proc); no import
+                                                needed *)
+                                             IF SymTab.QualProcInfo(nm, nm2,
+                                                  qu, qd, qr, qe) THEN
+                                               aKind := 2
+                                             ELSE at := SymTab.QualType(nm, nm2);
+                                               IF at # SymTab.InvalidType THEN
+                                                 aKind := 0
+                                               ELSE SemError(201);
+                                                 aKind := 0; at := SymTab.InvalidType
+                                               END
+                                             END;
                                              CopyNm(nm, amod);
                                              CopyNm(nm2, nm)
                                            ELSIF SymTab.Lookup(nm)

Dosya farkı çok büyük olduğundan ihmal edildi
+ 2465 - 2465
compiler/src/M2.lst


+ 4 - 0
compiler/tests/g_wrap.def

@@ -0,0 +1,4 @@
+GENERIC DEFINITION MODULE Wrap (U : TYPE);
+TYPE W = ARRAY [0..1] OF U;
+PROCEDURE Hi() : INTEGER;
+END Wrap.

+ 4 - 0
compiler/tests/g_wrap.mod

@@ -0,0 +1,4 @@
+GENERIC IMPLEMENTATION MODULE Wrap;
+PROCEDURE Hi() : INTEGER;
+BEGIN RETURN HIGH(W) END Hi;
+END Wrap.

+ 2 - 0
compiler/tests/g_wrapb.def

@@ -0,0 +1,2 @@
+DEFINITION MODULE WrapB = Wrap(IntBox.Box);
+END WrapB.

+ 2 - 0
compiler/tests/g_wrapb.mod

@@ -0,0 +1,2 @@
+IMPLEMENTATION MODULE WrapB = Wrap(IntBox.Box);
+END WrapB.

+ 4 - 0
compiler/tests/g_wrapprog.mod

@@ -0,0 +1,4 @@
+MODULE GWrapProg;
+FROM WrapB IMPORT Hi;
+VAR ExitCode : INTEGER;
+BEGIN ExitCode := Hi() + 41 END GWrapProg.

+ 10 - 5
docs/analysis_generics.md

@@ -47,13 +47,18 @@
 >
 > **Done (Increment 3 — 2026-10-16, constraint model):** a type formal
 > may carry an explicit constraint: `T : TYPE (ORDINAL)` (also
-> `INTEGER`, `REAL`).  At instantiation the actual type must satisfy it
-> (`ConsOk`: ORDINAL → `IsOrdinal`, INTEGER → `ClInt`, REAL →
-> `ClReal`), else `233`.  Verified: `OrdBox(INTEGER)` compiles and runs;
+> `INTEGER`, `REAL`, `POINTER`, `SCALAR`).  At instantiation the actual
+> type must satisfy it (`ConsOk`: ORDINAL → `IsOrdinal`, INTEGER →
+> `ClInt`, REAL → `ClReal`, POINTER → `ClPtr`, SCALAR → ordinal or
+> real), else `233`.  Verified: `OrdBox(INTEGER)` compiles and runs;
 > `OrdBox(REAL)` is rejected.  Suite `OrdProg` / `g_realbox`.
 >
-> **Still open:** `GENERIC CLASS`; instance dedup; nested generics as
-> actuals; further constraint names (e.g. `POINTER`, `SCALAR`).
+> **Done (2026-10-16, nested generics as actuals).**  A *qualified*
+> actual is classified as a procedure (`Mod.Proc`) or a type
+> (`Mod.Type`), so an instance's exported type can feed another generic:
+> `WrapB = Wrap(IntBox.Box)`.  Verified end-to-end (suite `GWrapProg`).
+>
+> **Still open:** `GENERIC CLASS` (classes + generics); instance dedup.
 >
 > **Done (Increment 3 — 2026-10-16, continued): procedure parameters.**
 > A formal may be a procedure:

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor