|
|
@@ -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));
|