|
|
@@ -151,6 +151,8 @@ 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 *)
|
|
|
+ refVal: ARRAY [0 .. 15] OF SymTab.Name;
|
|
|
isGen: BOOLEAN;
|
|
|
|
|
|
(* Generics (Increment 2): instantiation re-parse context. When the
|
|
|
@@ -160,6 +162,8 @@ VAR
|
|
|
instActive: BOOLEAN;
|
|
|
instName: SymTab.Name;
|
|
|
instActual: ARRAY [0 .. 15] OF SymTab.TypeIndex;
|
|
|
+ instKind: ARRAY [0 .. 15] OF INTEGER;
|
|
|
+ instVal: ARRAY [0 .. 15] OF SymTab.Name;
|
|
|
instN: CARDINAL;
|
|
|
instFk: CARDINAL; (* formal cursor while binding during re-parse *)
|
|
|
|
|
|
@@ -198,9 +202,36 @@ PROCEDURE InstBegin (name: ARRAY OF CHAR);
|
|
|
BEGIN instActive := TRUE; CopyNm(name, instName); instN := 0;
|
|
|
instFk := 0 END InstBegin;
|
|
|
|
|
|
-PROCEDURE InstAddActual (t: SymTab.TypeIndex);
|
|
|
+PROCEDURE InstActualKind (i: CARDINAL) : INTEGER;
|
|
|
BEGIN
|
|
|
- IF instN <= HIGH(instActual) THEN instActual[instN] := t; INC(instN) END
|
|
|
+ IF i >= instN THEN RETURN 0 END;
|
|
|
+ RETURN instKind[i]
|
|
|
+ END InstActualKind;
|
|
|
+
|
|
|
+PROCEDURE InstActualVal (i: CARDINAL; VAR v: SymTab.Name);
|
|
|
+ VAR k: CARDINAL;
|
|
|
+ BEGIN
|
|
|
+ v[0] := CHR(0);
|
|
|
+ IF i >= instN THEN RETURN END;
|
|
|
+ k := 0;
|
|
|
+ WHILE (k <= HIGH(v)) AND (instVal[i][k] # CHR(0)) DO
|
|
|
+ v[k] := instVal[i][k]; INC(k)
|
|
|
+ END;
|
|
|
+ v[k] := CHR(0)
|
|
|
+ END InstActualVal;
|
|
|
+
|
|
|
+PROCEDURE InstAddActual (kind: INTEGER; t: SymTab.TypeIndex;
|
|
|
+ val: ARRAY OF CHAR);
|
|
|
+ VAR k: CARDINAL;
|
|
|
+ BEGIN
|
|
|
+ IF instN > HIGH(instActual) THEN RETURN END;
|
|
|
+ instKind[instN] := kind; instActual[instN] := t;
|
|
|
+ k := 0;
|
|
|
+ WHILE (k <= HIGH(instVal[instN])) AND (val[k] # CHR(0)) DO
|
|
|
+ instVal[instN][k] := val[k]; INC(k)
|
|
|
+ END;
|
|
|
+ instVal[instN][k] := CHR(0);
|
|
|
+ INC(instN)
|
|
|
END InstAddActual;
|
|
|
|
|
|
PROCEDURE InstEnd;
|
|
|
@@ -236,6 +267,24 @@ PROCEDURE RefineActualGet (i: CARDINAL) : SymTab.TypeIndex;
|
|
|
RETURN refActual[i]
|
|
|
END RefineActualGet;
|
|
|
|
|
|
+PROCEDURE RefineActualKind (i: CARDINAL) : INTEGER;
|
|
|
+ BEGIN
|
|
|
+ IF i >= refN THEN RETURN 0 END;
|
|
|
+ RETURN refKind[i]
|
|
|
+ END RefineActualKind;
|
|
|
+
|
|
|
+PROCEDURE RefineActualVal (i: CARDINAL; VAR v: SymTab.Name);
|
|
|
+ VAR k: CARDINAL;
|
|
|
+ BEGIN
|
|
|
+ v[0] := CHR(0);
|
|
|
+ IF i >= refN THEN RETURN END;
|
|
|
+ k := 0;
|
|
|
+ WHILE (k <= HIGH(v)) AND (refVal[i][k] # CHR(0)) DO
|
|
|
+ v[k] := refVal[i][k]; INC(k)
|
|
|
+ END;
|
|
|
+ v[k] := CHR(0)
|
|
|
+ END RefineActualVal;
|
|
|
+
|
|
|
PROCEDURE NoteLabel (nm: ARRAY OF CHAR);
|
|
|
(* Record a statement label; duplicate is 200. *)
|
|
|
VAR i: CARDINAL;
|
|
|
@@ -494,27 +543,77 @@ PRODUCTIONS
|
|
|
TYPE parameters only; actuals are type identifiers. *)
|
|
|
GenericFormals
|
|
|
= "(" GenericFormal { ";" GenericFormal } ")" .
|
|
|
- GenericFormal (. VAR nm: SymTab.Name; .)
|
|
|
- = GetIdent<nm> (. IF instActive THEN
|
|
|
- IF NOT SymTab.EnterTypeParamBound(nm,
|
|
|
- InstActualGet(instFk)) THEN
|
|
|
- SemError(200) END
|
|
|
- ELSIF NOT SymTab.EnterTypeParam(nm) THEN
|
|
|
- SemError(200) END;
|
|
|
- INC(instFk); .)
|
|
|
- { "," GetIdent<nm> (. IF instActive THEN
|
|
|
- IF NOT SymTab.EnterTypeParamBound(nm,
|
|
|
- InstActualGet(instFk)) THEN
|
|
|
- SemError(200) END
|
|
|
- ELSIF NOT SymTab.EnterTypeParam(nm) THEN
|
|
|
- SemError(200) END;
|
|
|
- INC(instFk); .) }
|
|
|
- ":" "TYPE" .
|
|
|
+ GenericFormal (. VAR nm: SymTab.Name; vt: SymTab.TypeIndex;
|
|
|
+ names: ARRAY [0 .. 15] OF SymTab.Name;
|
|
|
+ nn, k: CARDINAL;
|
|
|
+ isTypeFormal: BOOLEAN; .)
|
|
|
+ = (. nn := 0; .)
|
|
|
+ GetIdent<nm> (. k := 0;
|
|
|
+ WHILE (k <= HIGH(names[nn])) AND (nm[k] # CHR(0)) DO
|
|
|
+ names[nn][k] := nm[k]; INC(k) END;
|
|
|
+ names[nn][k] := CHR(0); INC(nn); .)
|
|
|
+ { "," GetIdent<nm> (. k := 0;
|
|
|
+ WHILE (k <= HIGH(names[nn])) AND (nm[k] # CHR(0)) DO
|
|
|
+ names[nn][k] := nm[k]; INC(k) END;
|
|
|
+ names[nn][k] := CHR(0); INC(nn); .) }
|
|
|
+ ":" (. vt := SymTab.InvalidType; isTypeFormal := FALSE; .)
|
|
|
+ ( "TYPE" (. isTypeFormal := TRUE; .)
|
|
|
+ | TypeIdent<vt> ) (. k := 0;
|
|
|
+ WHILE k < nn DO
|
|
|
+ IF isTypeFormal THEN
|
|
|
+ IF instActive THEN
|
|
|
+ IF NOT SymTab.EnterTypeParamBound(names[k], InstActualGet(instFk)) THEN
|
|
|
+ SemError(200) END
|
|
|
+ ELSIF NOT SymTab.EnterTypeParam(names[k]) THEN
|
|
|
+ SemError(200) END
|
|
|
+ ELSE
|
|
|
+ IF NOT SymTab.Enter(names[k], SymTab.KindConst) THEN
|
|
|
+ SemError(200) END;
|
|
|
+ SymTab.SetSymType(names[k], vt);
|
|
|
+ IF instActive THEN
|
|
|
+ InstActualVal(instFk, nm);
|
|
|
+ SymTab.SetSymVal(names[k], nm)
|
|
|
+ ELSE SymTab.SetSymVal(names[k], "0")
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ INC(instFk); INC(k)
|
|
|
+ END; .) .
|
|
|
Actuals
|
|
|
= Actual { "," Actual } .
|
|
|
- Actual (. VAR at: SymTab.TypeIndex; .)
|
|
|
- = TypeIdent<at> (. IF refN <= HIGH(refActual) THEN
|
|
|
- refActual[refN] := at; INC(refN)
|
|
|
+ Actual (. VAR at: SymTab.TypeIndex;
|
|
|
+ nm: SymTab.Name;
|
|
|
+ s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ qv: QbeGen.QVal;
|
|
|
+ isCh, isV: BOOLEAN;
|
|
|
+ k: CARDINAL; .)
|
|
|
+ = (. isV := FALSE; at := SymTab.InvalidType; nm[0] := CHR(0); .)
|
|
|
+ ( integer (. LexString(s); QbeGen.NormInt(s, qv);
|
|
|
+ isV := TRUE; at := SymTab.IntType();
|
|
|
+ CopyNm(qv, nm); .)
|
|
|
+ | charConst (. LexString(s); QbeGen.NormLit(s, qv, isCh);
|
|
|
+ isV := TRUE; at := SymTab.CharType();
|
|
|
+ CopyNm(qv, nm); .)
|
|
|
+ | GetIdent<nm> (. IF SymTab.Lookup(nm)
|
|
|
+ AND ((SymTab.SymKind(nm) = SymTab.KindType)
|
|
|
+ OR (SymTab.SymKind(nm) = SymTab.KindPredef)) THEN
|
|
|
+ at := SymTab.SymType(nm); isV := FALSE
|
|
|
+ ELSIF SymTab.Lookup(nm)
|
|
|
+ AND (SymTab.SymKind(nm) = SymTab.KindConst) THEN
|
|
|
+ isV := TRUE; 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
|
|
|
+ END; .) )
|
|
|
+ (. IF refN <= HIGH(refActual) THEN
|
|
|
+ IF isV THEN refKind[refN] := 1
|
|
|
+ ELSE refKind[refN] := 0 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);
|
|
|
+ INC(refN)
|
|
|
END; .) .
|
|
|
Unit
|
|
|
= (. isGen := FALSE;
|