Просмотр исходного кода

generics inc2 (WIP): instantiation context + unit/refinement queries

Inert scaffold for generic instantiation by re-parse:
- grammar state instActive/instName/instActual (the re-parse context),
  plus unitName/unitWasGen/unitWasDef and refSeen/refIsDef.
- accessors exported via parser.frm: InstBegin/InstAddActual/InstEnd/
  InInst/InstNameGet/InstActualGet, UnitNameGet/UnitIsGeneric/
  UnitIsDefModule, RefineSeen/RefineIsDef/RefineInst/RefineGen/
  RefineActualCount/RefineActualGet.
- DefUnit/ImplUnit override the module name from instName when
  instActive, and record the unit/refinement identity.

No behaviour change yet (the driver does not instantiate).  Suite
189/189.
Eric Streit 1 неделя назад
Родитель
Сommit
31633b823f
2 измененных файлов с 114 добавлено и 13 удалено
  1. 92 12
      compiler/src/M2.atg
  2. 22 1
      compiler/src/parser.frm

+ 92 - 12
compiler/src/M2.atg

@@ -128,6 +128,76 @@ VAR
   refActual: ARRAY [0 .. 15] OF SymTab.TypeIndex;
   isGen: BOOLEAN;
 
+  (* Generics (Increment 2): instantiation re-parse context.  When the
+     driver re-parses a generic's source to instantiate it as `instName`,
+     instActive is TRUE, the module is renamed, and each type formal is
+     bound to the corresponding instActual entry. *)
+  instActive: BOOLEAN;
+  instName: SymTab.Name;
+  instActual: ARRAY [0 .. 15] OF SymTab.TypeIndex;
+  instN: CARDINAL;
+
+  (* Identity of the last-parsed unit and refinement, for the driver's
+     generic registry and its re-parse decision. *)
+  unitName: SymTab.Name;
+  unitWasGen: BOOLEAN;
+  unitWasDef: BOOLEAN;
+  refSeen: BOOLEAN;
+  refIsDef: BOOLEAN;
+
+PROCEDURE InInst () : BOOLEAN;
+  BEGIN RETURN instActive END InInst;
+
+PROCEDURE InstNameGet (VAR nm: SymTab.Name);
+  BEGIN CopyNm(instName, nm) END InstNameGet;
+
+PROCEDURE InstActualGet (i: CARDINAL) : SymTab.TypeIndex;
+  BEGIN
+    IF i >= instN THEN RETURN SymTab.InvalidType END;
+    RETURN instActual[i]
+  END InstActualGet;
+
+PROCEDURE InstBegin (name: ARRAY OF CHAR);
+  BEGIN instActive := TRUE; CopyNm(name, instName); instN := 0 END InstBegin;
+
+PROCEDURE InstAddActual (t: SymTab.TypeIndex);
+  BEGIN
+    IF instN <= HIGH(instActual) THEN instActual[instN] := t; INC(instN) END
+  END InstAddActual;
+
+PROCEDURE InstEnd;
+  BEGIN instActive := FALSE; instN := 0 END InstEnd;
+
+PROCEDURE UnitNameGet (VAR nm: SymTab.Name);
+  BEGIN CopyNm(unitName, nm) END UnitNameGet;
+
+PROCEDURE UnitIsGeneric () : BOOLEAN;
+  BEGIN RETURN unitWasGen END UnitIsGeneric;
+
+PROCEDURE UnitIsDefModule () : BOOLEAN;
+  BEGIN RETURN unitWasDef END UnitIsDefModule;
+
+PROCEDURE RefineSeen () : BOOLEAN;
+  BEGIN RETURN refSeen END RefineSeen;
+
+PROCEDURE RefineIsDef () : BOOLEAN;
+  BEGIN RETURN refIsDef END RefineIsDef;
+
+PROCEDURE RefineInst (VAR nm: SymTab.Name);
+  BEGIN CopyNm(refInst, nm) END RefineInst;
+
+PROCEDURE RefineGen (VAR nm: SymTab.Name);
+  BEGIN CopyNm(refGen, nm) END RefineGen;
+
+PROCEDURE RefineActualCount () : CARDINAL;
+  BEGIN RETURN refN END RefineActualCount;
+
+PROCEDURE RefineActualGet (i: CARDINAL) : SymTab.TypeIndex;
+  BEGIN
+    IF i >= refN THEN RETURN SymTab.InvalidType END;
+    RETURN refActual[i]
+  END RefineActualGet;
+
 PROCEDURE CopyNm (src: ARRAY OF CHAR; VAR dst: SymTab.Name);
   VAR i: CARDINAL;
   BEGIN
@@ -335,11 +405,15 @@ PRODUCTIONS
   DefUnit                               (. VAR m1, m2, pn: SymTab.Name;
                                              g: SymTab.Name;
                                              astSeq, astTail, astProc: AST.Node; .)
-    =                                   (. refN := 0; .)
+    =                                   (. refN := 0; refSeen := FALSE; .)
       "DEFINITION" "MODULE"
-      GetIdent<m1>                      (. IF NOT SymTab.BeginDef(m1) THEN
+      GetIdent<m1>                      (. IF instActive THEN InstNameGet(m1) END;
+                                           IF NOT SymTab.BeginDef(m1) THEN
                                              SemError(200) END;
-                                           QbeGen.SetModule(m1); .)
+                                           QbeGen.SetModule(m1);
+                                           CopyNm(m1, unitName);
+                                           unitWasGen := isGen;
+                                           unitWasDef := TRUE; .)
       [ GenericFormals ]
       ( ";"
       { Import                        (. AstAppend(AST.NkDeclSeq,
@@ -384,6 +458,7 @@ PRODUCTIONS
       | "=" GetIdent<g> [ "(" Actuals ")" ] ";"
                                         (. CopyNm(m1, refInst);
                                            CopyNm(g, refGen);
+                                           refSeen := TRUE; refIsDef := TRUE;
                                            astUnit := AST.MakeNode(AST.NkUnit);
                                            AST.SetChild(astUnit, 0,
                                              AST.MakeLeaf(AST.NkIdent, m1));
@@ -399,16 +474,20 @@ PRODUCTIONS
                                              fname: SymTab.Name;
                                              unres: BOOLEAN;
                                              astNode: AST.Node; .)
-    =                                   (. refN := 0; .)
+    =                                   (. refN := 0; refSeen := FALSE; .)
       "IMPLEMENTATION" "MODULE"
-      GetIdent<m1> (. IF NOT SymTab.BeginImpl(m1) THEN
-                                             SemError(201) END;
-                                           astStmt := AST.NoNode;
-                                           astDecl := AST.NoNode;
-                                           astImp := AST.NoNode;
-                                           astImpTail := AST.NoNode;
-                                           nPendVar := 0;
-                                           QbeGen.SetModule(m1); .)
+      GetIdent<m1> (. IF instActive THEN InstNameGet(m1) END;
+                     IF NOT SymTab.BeginImpl(m1) THEN
+                       SemError(201) END;
+                     astStmt := AST.NoNode;
+                     astDecl := AST.NoNode;
+                     astImp := AST.NoNode;
+                     astImpTail := AST.NoNode;
+                     nPendVar := 0;
+                     CopyNm(m1, unitName);
+                     unitWasGen := isGen;
+                     unitWasDef := FALSE;
+                     QbeGen.SetModule(m1); .)
       [ GenericFormals ]
       ( ";"
       { Import                        (. AstAppend(AST.NkDeclSeq,
@@ -449,6 +528,7 @@ PRODUCTIONS
       | "=" GetIdent<g> [ "(" Actuals ")" ] ";"
                                         (. CopyNm(m1, refInst);
                                            CopyNm(g, refGen);
+                                           refSeen := TRUE; refIsDef := FALSE;
                                            astNode := AST.MakeNode(AST.NkUnit);
                                            AST.SetChild(astNode, 0,
                                              AST.MakeLeaf(AST.NkIdent, m1));

+ 22 - 1
compiler/src/parser.frm

@@ -126,7 +126,7 @@ END -->modulename.
 
 (* Parser generated by Coco/R *)
 
-IMPORT AST;
+IMPORT AST, SymTab;
 
 PROCEDURE Parse;
 
@@ -135,6 +135,27 @@ PROCEDURE Successful (): BOOLEAN;
 PROCEDURE GetUnit (): AST.Node;
 (* The most recently parsed unit's AST root (for the Lower comparison) *)
 
+(* ---- generics: instantiation context and unit/refinement queries
+   (Increment 2), consumed by the driver's re-parse pass ---- *)
+
+PROCEDURE InInst (): BOOLEAN;
+PROCEDURE InstBegin (name: ARRAY OF CHAR);
+PROCEDURE InstAddActual (t: SymTab.TypeIndex);
+PROCEDURE InstEnd;
+PROCEDURE InstNameGet (VAR nm: SymTab.Name);
+PROCEDURE InstActualGet (i: CARDINAL): SymTab.TypeIndex;
+
+PROCEDURE UnitNameGet (VAR nm: SymTab.Name);
+PROCEDURE UnitIsGeneric (): BOOLEAN;
+PROCEDURE UnitIsDefModule (): BOOLEAN;
+
+PROCEDURE RefineSeen (): BOOLEAN;
+PROCEDURE RefineIsDef (): BOOLEAN;
+PROCEDURE RefineInst (VAR nm: SymTab.Name);
+PROCEDURE RefineGen (VAR nm: SymTab.Name);
+PROCEDURE RefineActualCount (): CARDINAL;
+PROCEDURE RefineActualGet (i: CARDINAL): SymTab.TypeIndex;
+
 (* Returns TRUE if no errors have been recorded while parsing *)
 
 PROCEDURE SynError (errNo: INTEGER);