|
|
@@ -151,8 +151,9 @@ VAR
|
|
|
refInst, refGen: SymTab.Name;
|
|
|
refN: CARDINAL;
|
|
|
refActual: ARRAY [0 .. 15] OF SymTab.TypeIndex;
|
|
|
- refKind: ARRAY [0 .. 15] OF INTEGER; (* 0 = type actual, 1 = value *)
|
|
|
+ refKind: ARRAY [0 .. 15] OF INTEGER; (* 0 = type, 1 = value, 2 = proc *)
|
|
|
refVal: ARRAY [0 .. 15] OF SymTab.Name;
|
|
|
+ refMod: ARRAY [0 .. 15] OF SymTab.Name;
|
|
|
isGen: BOOLEAN;
|
|
|
|
|
|
(* Generics (Increment 2): instantiation re-parse context. When the
|
|
|
@@ -164,6 +165,7 @@ VAR
|
|
|
instActual: ARRAY [0 .. 15] OF SymTab.TypeIndex;
|
|
|
instKind: ARRAY [0 .. 15] OF INTEGER;
|
|
|
instVal: ARRAY [0 .. 15] OF SymTab.Name;
|
|
|
+ instMod: ARRAY [0 .. 15] OF SymTab.Name;
|
|
|
instN: CARDINAL;
|
|
|
instFk: CARDINAL; (* formal cursor while binding during re-parse *)
|
|
|
|
|
|
@@ -220,8 +222,20 @@ PROCEDURE InstActualVal (i: CARDINAL; VAR v: SymTab.Name);
|
|
|
v[k] := CHR(0)
|
|
|
END InstActualVal;
|
|
|
|
|
|
+PROCEDURE InstActualMod (i: CARDINAL; VAR m: SymTab.Name);
|
|
|
+ VAR k: CARDINAL;
|
|
|
+ BEGIN
|
|
|
+ m[0] := CHR(0);
|
|
|
+ IF i >= instN THEN RETURN END;
|
|
|
+ k := 0;
|
|
|
+ WHILE (k <= HIGH(m)) AND (instMod[i][k] # CHR(0)) DO
|
|
|
+ m[k] := instMod[i][k]; INC(k)
|
|
|
+ END;
|
|
|
+ m[k] := CHR(0)
|
|
|
+ END InstActualMod;
|
|
|
+
|
|
|
PROCEDURE InstAddActual (kind: INTEGER; t: SymTab.TypeIndex;
|
|
|
- val: ARRAY OF CHAR);
|
|
|
+ val, m: ARRAY OF CHAR);
|
|
|
VAR k: CARDINAL;
|
|
|
BEGIN
|
|
|
IF instN > HIGH(instActual) THEN RETURN END;
|
|
|
@@ -231,6 +245,11 @@ PROCEDURE InstAddActual (kind: INTEGER; t: SymTab.TypeIndex;
|
|
|
instVal[instN][k] := val[k]; INC(k)
|
|
|
END;
|
|
|
instVal[instN][k] := CHR(0);
|
|
|
+ k := 0;
|
|
|
+ WHILE (k <= HIGH(instMod[instN])) AND (m[k] # CHR(0)) DO
|
|
|
+ instMod[instN][k] := m[k]; INC(k)
|
|
|
+ END;
|
|
|
+ instMod[instN][k] := CHR(0);
|
|
|
INC(instN)
|
|
|
END InstAddActual;
|
|
|
|
|
|
@@ -273,6 +292,18 @@ PROCEDURE RefineActualKind (i: CARDINAL) : INTEGER;
|
|
|
RETURN refKind[i]
|
|
|
END RefineActualKind;
|
|
|
|
|
|
+PROCEDURE RefineActualMod (i: CARDINAL; VAR m: SymTab.Name);
|
|
|
+ VAR k: CARDINAL;
|
|
|
+ BEGIN
|
|
|
+ m[0] := CHR(0);
|
|
|
+ IF i >= refN THEN RETURN END;
|
|
|
+ k := 0;
|
|
|
+ WHILE (k <= HIGH(m)) AND (refMod[i][k] # CHR(0)) DO
|
|
|
+ m[k] := refMod[i][k]; INC(k)
|
|
|
+ END;
|
|
|
+ m[k] := CHR(0)
|
|
|
+ END RefineActualMod;
|
|
|
+
|
|
|
PROCEDURE RefineActualVal (i: CARDINAL; VAR v: SymTab.Name);
|
|
|
VAR k: CARDINAL;
|
|
|
BEGIN
|
|
|
@@ -546,6 +577,10 @@ PRODUCTIONS
|
|
|
GenericFormal (. VAR nm: SymTab.Name; vt: SymTab.TypeIndex;
|
|
|
names: ARRAY [0 .. 15] OF SymTab.Name;
|
|
|
nn, k: CARDINAL;
|
|
|
+ mmod: SymTab.Name;
|
|
|
+ quid, qdep: CARDINAL;
|
|
|
+ qres: SymTab.TypeIndex;
|
|
|
+ qext: BOOLEAN;
|
|
|
isTypeFormal: BOOLEAN; .)
|
|
|
= (. nn := 0; .)
|
|
|
GetIdent<nm> (. k := 0;
|
|
|
@@ -558,6 +593,7 @@ PRODUCTIONS
|
|
|
names[nn][k] := CHR(0); INC(nn); .) }
|
|
|
":" (. vt := SymTab.InvalidType; isTypeFormal := FALSE; .)
|
|
|
( "TYPE" (. isTypeFormal := TRUE; .)
|
|
|
+ | ProcType<vt> (. isTypeFormal := FALSE; .)
|
|
|
| TypeIdent<vt> ) (. k := 0;
|
|
|
WHILE k < nn DO
|
|
|
IF isTypeFormal THEN
|
|
|
@@ -571,6 +607,26 @@ PRODUCTIONS
|
|
|
SemError(200) END
|
|
|
ELSIF NOT SymTab.EnterTypeParam(names[k]) THEN
|
|
|
SemError(200) END
|
|
|
+ ELSIF SymTab.ClassOf(vt) = SymTab.ClProc THEN
|
|
|
+ (* procedure formal *)
|
|
|
+ IF instActive THEN
|
|
|
+ IF InstActualKind(instFk) # 2 THEN
|
|
|
+ SemError(233) END;
|
|
|
+ InstActualMod(instFk, mmod);
|
|
|
+ InstActualVal(instFk, nm);
|
|
|
+ IF NOT SymTab.AliasProc(names[k], mmod, nm) THEN
|
|
|
+ SemError(201)
|
|
|
+ ELSIF SymTab.QualProcInfo(mmod, nm, quid, qdep, qres, qext) THEN
|
|
|
+ Lower.AliasProc(names[k], quid, qres, qdep, qext)
|
|
|
+ END
|
|
|
+ ELSE
|
|
|
+ (* template: a callable
|
|
|
+ placeholder of the
|
|
|
+ formal's proc type *)
|
|
|
+ IF NOT SymTab.Enter(names[k], SymTab.KindVar) THEN
|
|
|
+ SemError(200) END;
|
|
|
+ SymTab.SetSymType(names[k], vt)
|
|
|
+ END
|
|
|
ELSE
|
|
|
(* constraint: a value
|
|
|
formal needs a value
|
|
|
@@ -595,34 +651,58 @@ PRODUCTIONS
|
|
|
s: ARRAY [0 .. 255] OF CHAR;
|
|
|
qv: QbeGen.QVal;
|
|
|
isCh, isV: BOOLEAN;
|
|
|
+ aKind: INTEGER;
|
|
|
+ amod: SymTab.Name;
|
|
|
+ nm2: SymTab.Name;
|
|
|
k: CARDINAL; .)
|
|
|
- = (. isV := FALSE; at := SymTab.InvalidType; nm[0] := CHR(0); .)
|
|
|
+ = (. isV := FALSE; at := SymTab.InvalidType;
|
|
|
+ nm[0] := CHR(0); nm2[0] := CHR(0);
|
|
|
+ aKind := 0; amod[0] := CHR(0); .)
|
|
|
( integer (. LexString(s); QbeGen.NormInt(s, qv);
|
|
|
- isV := TRUE; at := SymTab.IntType();
|
|
|
+ isV := TRUE; aKind := 1; at := SymTab.IntType();
|
|
|
CopyNm(qv, nm); .)
|
|
|
| charConst (. LexString(s); QbeGen.NormLit(s, qv, isCh);
|
|
|
- isV := TRUE; at := SymTab.CharType();
|
|
|
+ isV := TRUE; aKind := 1; at := SymTab.CharType();
|
|
|
CopyNm(qv, nm); .)
|
|
|
- | GetIdent<nm> (. IF SymTab.Lookup(nm)
|
|
|
+ | GetIdent<nm> [ "." GetIdent<nm2> ]
|
|
|
+ (. 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;
|
|
|
+ CopyNm(nm, amod);
|
|
|
+ CopyNm(nm2, nm)
|
|
|
+ ELSIF SymTab.Lookup(nm)
|
|
|
AND ((SymTab.SymKind(nm) = SymTab.KindType)
|
|
|
OR (SymTab.SymKind(nm) = SymTab.KindPredef)) THEN
|
|
|
- at := SymTab.SymType(nm); isV := FALSE
|
|
|
+ at := SymTab.SymType(nm)
|
|
|
+ ELSIF SymTab.Lookup(nm)
|
|
|
+ AND (SymTab.SymKind(nm) = SymTab.KindProc) THEN
|
|
|
+ aKind := 2; at := SymTab.SymType(nm);
|
|
|
+ IF NOT SymTab.SymMod(nm, amod) THEN
|
|
|
+ amod[0] := CHR(0) END
|
|
|
ELSIF SymTab.Lookup(nm)
|
|
|
AND (SymTab.SymKind(nm) = SymTab.KindConst) THEN
|
|
|
- isV := TRUE; at := SymTab.SymType(nm);
|
|
|
+ isV := TRUE; aKind := 1; at := SymTab.SymType(nm);
|
|
|
IF NOT SymTab.GetSymVal(nm, s) THEN s[0] := CHR(0) END;
|
|
|
CopyNm(s, nm)
|
|
|
- ELSE SemError(201);
|
|
|
- at := SymTab.InvalidType; isV := FALSE
|
|
|
+ ELSE SemError(201)
|
|
|
END; .) )
|
|
|
(. IF refN <= HIGH(refActual) THEN
|
|
|
- IF isV THEN refKind[refN] := 1
|
|
|
- ELSE refKind[refN] := 0 END;
|
|
|
+ IF aKind = 0 THEN
|
|
|
+ IF isV THEN refKind[refN] := 1
|
|
|
+ ELSE refKind[refN] := 0 END
|
|
|
+ ELSE refKind[refN] := aKind END;
|
|
|
refActual[refN] := at;
|
|
|
k := 0;
|
|
|
WHILE (k <= HIGH(refVal[refN])) AND (nm[k] # CHR(0)) DO
|
|
|
refVal[refN][k] := nm[k]; INC(k) END;
|
|
|
refVal[refN][k] := CHR(0);
|
|
|
+ k := 0;
|
|
|
+ WHILE (k <= HIGH(refMod[refN])) AND (amod[k] # CHR(0)) DO
|
|
|
+ refMod[refN][k] := amod[k]; INC(k) END;
|
|
|
+ refMod[refN][k] := CHR(0);
|
|
|
INC(refN)
|
|
|
END; .) .
|
|
|
Unit
|
|
|
@@ -822,6 +902,7 @@ PRODUCTIONS
|
|
|
AST.MakeLeaf(AST.NkIdent, m1));
|
|
|
astDecl := AST.NoNode;
|
|
|
astStmt := AST.NoNode; .)
|
|
|
+ { Import (. (* refinement unit import *) .) }
|
|
|
"END"
|
|
|
GetIdent<m2> (. IF NOT SymTab.Equal(m1, m2) THEN
|
|
|
SemError(202) END;
|