|
|
@@ -227,9 +227,47 @@ PRODUCTIONS
|
|
|
| ArrayType<t, allowOpen>
|
|
|
| SetType<t>
|
|
|
| RecordType<t>
|
|
|
- | PointerType<t> .
|
|
|
+ | PointerType<t>
|
|
|
+ | ProcType<t> .
|
|
|
PointerType<VAR t: SymTab.TypeIndex> (. VAR base: SymTab.TypeIndex; .)
|
|
|
= "POINTER" "TO" Type<base, FALSE>(. t := SymTab.NewPtr(base); .) .
|
|
|
+ (* Procedure types (step 8.5): PROCEDURE (params): result. Values
|
|
|
+ are code pointers; params are collected into the descriptor. *)
|
|
|
+ ProcType<VAR t: SymTab.TypeIndex> (. VAR res, pt: SymTab.TypeIndex;
|
|
|
+ isV: BOOLEAN; .)
|
|
|
+ = "PROCEDURE" (. res := SymTab.InvalidType;
|
|
|
+ t := SymTab.NewProcType(res); .)
|
|
|
+ [ "(" [ ProcTypeSection<t> { ";" ProcTypeSection<t> } ] ")" ]
|
|
|
+ [ ":" TypeIdent<res> (. SymTab.SetProcTypeRes(t, res); .) ] .
|
|
|
+ ProcTypeSection<t: SymTab.TypeIndex> (. VAR pt: SymTab.TypeIndex;
|
|
|
+ isV: BOOLEAN;
|
|
|
+ cnt, k: CARDINAL;
|
|
|
+ names: ARRAY [0 .. 15] OF SymTab.Name; .)
|
|
|
+ = (. isV := FALSE; cnt := 0; .)
|
|
|
+ [ "VAR" (. isV := TRUE; .) ]
|
|
|
+ GetIdent<names[cnt]> (. INC(cnt); .)
|
|
|
+ { "," GetIdent<names[cnt]> (. INC(cnt); .) }
|
|
|
+ ( ":" Type<pt, FALSE> (. k := 0;
|
|
|
+ WHILE k < cnt DO
|
|
|
+ SymTab.ProcTypeAdd(t, isV, pt);
|
|
|
+ INC(k)
|
|
|
+ END; .)
|
|
|
+ | (. (* type-only parameter list:
|
|
|
+ each name is a type (GNU
|
|
|
+ shorthand used by the
|
|
|
+ Coco/R scanner frame) *)
|
|
|
+ k := 0;
|
|
|
+ WHILE k < cnt DO
|
|
|
+ IF SymTab.Lookup(names[k])
|
|
|
+ AND ((SymTab.SymKind(names[k]) = SymTab.KindType)
|
|
|
+ OR (SymTab.SymKind(names[k]) = SymTab.KindPredef)) THEN
|
|
|
+ pt := SymTab.SymType(names[k])
|
|
|
+ ELSE SemError(201);
|
|
|
+ pt := SymTab.InvalidType
|
|
|
+ END;
|
|
|
+ SymTab.ProcTypeAdd(t, isV, pt);
|
|
|
+ INC(k)
|
|
|
+ END; .) ) .
|
|
|
(* Arrays: "OF" without bounds is an open formal (allowed only
|
|
|
where allowOpen); "[lo..hi, ...]" nests bounded levels inside
|
|
|
out. Bounds are folded literals (int/char); anything else 230.
|
|
|
@@ -527,7 +565,8 @@ PRODUCTIONS
|
|
|
AND (cls # SymTab.ClSet)
|
|
|
AND (cls # SymTab.ClRecord)
|
|
|
AND (cls # SymTab.ClPtr)
|
|
|
- AND (cls # SymTab.ClLong) THEN
|
|
|
+ AND (cls # SymTab.ClLong)
|
|
|
+ AND (cls # SymTab.ClProc) THEN
|
|
|
SemError(230) END;
|
|
|
IF QbeGen.LocFull() THEN
|
|
|
SemError(233) END;
|
|
|
@@ -864,8 +903,10 @@ PRODUCTIONS
|
|
|
ELSIF SymTab.ClassOf(dt) =
|
|
|
SymTab.ClRecord THEN
|
|
|
QbeGen.CopyRecord(qd, qe, dt)
|
|
|
- ELSIF SymTab.ClassOf(dt) =
|
|
|
- SymTab.ClPtr THEN
|
|
|
+ ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ SymTab.ClPtr)
|
|
|
+ OR (SymTab.ClassOf(dt) =
|
|
|
+ SymTab.ClProc) THEN
|
|
|
QbeGen.StorePtr(qn, qe)
|
|
|
ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
IF wconv THEN
|
|
|
@@ -880,7 +921,7 @@ PRODUCTIONS
|
|
|
QbeGen.StoreVar(qn, qe, isR)
|
|
|
END
|
|
|
END; .)
|
|
|
- | ArgList<qn, FALSE, ct2, q2, called>
|
|
|
+ | ArgList<qn, dt, qd, FALSE, ct2, q2, called>
|
|
|
| (* bare `P;`: proper parameterless
|
|
|
procedure call; anything else
|
|
|
here is 233 (was a bare syntax
|
|
|
@@ -908,29 +949,45 @@ PRODUCTIONS
|
|
|
want selects CallEnd's result handling; t/q carry the call
|
|
|
value (statement calls discard). Arity/type failures are 233;
|
|
|
evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
- ArgList<pn: SymTab.Name; want: BOOLEAN;
|
|
|
+ ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
+ want: BOOLEAN;
|
|
|
VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
VAR called: BOOLEAN> (. VAR i: CARDINAL;
|
|
|
res: SymTab.TypeIndex;
|
|
|
mg: QbeGen.QVal;
|
|
|
- ok: BOOLEAN; .)
|
|
|
+ ok, ind: BOOLEAN; .)
|
|
|
= "(" (. called := TRUE;
|
|
|
- res := SymTab.ProcRes(pn);
|
|
|
ok := TRUE;
|
|
|
- IF SymTab.SymKind(pn) #
|
|
|
+ ind := FALSE;
|
|
|
+ IF SymTab.SymKind(pn) =
|
|
|
SymTab.KindProc THEN
|
|
|
- SemError(233); ok := FALSE
|
|
|
- ELSE QbeGen.Mangled(pn,
|
|
|
- SymTab.ProcUid(pn), mg);
|
|
|
+ res := SymTab.ProcRes(pn);
|
|
|
+ QbeGen.Mangled(pn,
|
|
|
+ SymTab.ProcUid(pn), mg);
|
|
|
QbeGen.CallBegin(mg, res,
|
|
|
SymTab.ProcDepthOf(pn),
|
|
|
SymTab.IsExternal(pn))
|
|
|
+ ELSIF (pt # SymTab.InvalidType)
|
|
|
+ AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
+ ind := TRUE;
|
|
|
+ res :=
|
|
|
+ SymTab.ProcTypeRes(pt);
|
|
|
+ QbeGen.CallBeginInd(callee,
|
|
|
+ res, FALSE)
|
|
|
+ ELSE SemError(233);
|
|
|
+ ok := FALSE;
|
|
|
+ res := SymTab.InvalidType
|
|
|
END;
|
|
|
i := 0; .)
|
|
|
- [ ActParam<pn, i> (. INC(i); .)
|
|
|
- { "," ActParam<pn, i> (. INC(i); .) } ]
|
|
|
+ [ ActParam<pn, pt, ind, i> (. INC(i); .)
|
|
|
+ { "," ActParam<pn, pt, ind, i> (. INC(i); .) } ]
|
|
|
")" (. IF ok THEN
|
|
|
- IF i #
|
|
|
+ IF ind THEN
|
|
|
+ IF i #
|
|
|
+ SymTab.ProcTypeNPar(pt) THEN
|
|
|
+ SemError(233); ok := FALSE
|
|
|
+ END
|
|
|
+ ELSIF i #
|
|
|
SymTab.ProcNPar(pn) THEN
|
|
|
SemError(233); ok := FALSE
|
|
|
END
|
|
|
@@ -958,11 +1015,21 @@ PRODUCTIONS
|
|
|
END; .) .
|
|
|
(* One actual: VAR formals take recorded designator addresses
|
|
|
(233 otherwise); value formals take converted expressions. *)
|
|
|
- ActParam<pn: SymTab.Name; i: CARDINAL>(. VAR at, ft: SymTab.TypeIndex;
|
|
|
+ ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
+ i: CARDINAL> (. VAR at, ft: SymTab.TypeIndex;
|
|
|
qe, qa, qt: QbeGen.QVal;
|
|
|
isV, conv: BOOLEAN; .)
|
|
|
- = Expr<at, qe> (. ft := SymTab.ParamType(pn, i);
|
|
|
- isV := SymTab.ParamIsVar(pn, i);
|
|
|
+ = Expr<at, qe> (. IF ind THEN
|
|
|
+ ft :=
|
|
|
+ SymTab.ProcTypeParamType(pt,
|
|
|
+ i);
|
|
|
+ isV :=
|
|
|
+ SymTab.ProcTypeParamIsVar(pt,
|
|
|
+ i)
|
|
|
+ ELSE
|
|
|
+ ft := SymTab.ParamType(pn, i);
|
|
|
+ isV := SymTab.ParamIsVar(pn, i)
|
|
|
+ END;
|
|
|
IF (at = SymTab.InvalidType)
|
|
|
OR (ft =
|
|
|
SymTab.InvalidType) THEN
|
|
|
@@ -1334,7 +1401,8 @@ PRODUCTIONS
|
|
|
= SymTab.ClReal) THEN
|
|
|
QbeGen.LoadVar(n,
|
|
|
cls = SymTab.ClReal, q)
|
|
|
- ELSIF cls = SymTab.ClPtr THEN
|
|
|
+ ELSIF (cls = SymTab.ClPtr)
|
|
|
+ OR (cls = SymTab.ClProc) THEN
|
|
|
QbeGen.LoadPtr(n, q)
|
|
|
ELSIF cls = SymTab.ClLong THEN
|
|
|
QbeGen.LoadLong(n, q)
|
|
|
@@ -1851,7 +1919,7 @@ PRODUCTIONS
|
|
|
SymTab.ClRecord)) THEN
|
|
|
QbeGen.NoteAddr(qd, qd)
|
|
|
END; .)
|
|
|
- [ ArgList<qn, TRUE, ct2, q2, called>
|
|
|
+ [ ArgList<qn, dt, qd, TRUE, ct2, q2, called>
|
|
|
(. t := ct2;
|
|
|
QbeGen.CopyOp(q2, q); .) ]
|
|
|
(. IF NOT called
|
|
|
@@ -1872,7 +1940,15 @@ PRODUCTIONS
|
|
|
SymTab.IsExternal(qn));
|
|
|
QbeGen.CallEnd(TRUE, q);
|
|
|
t := SymTab.ProcRes(qn)
|
|
|
- ELSE SemError(230)
|
|
|
+ ELSE
|
|
|
+ (* procedure used as a
|
|
|
+ value (assign to a
|
|
|
+ procedure variable):
|
|
|
+ its code address *)
|
|
|
+ t := SymTab.ProcTypeOf(qn);
|
|
|
+ QbeGen.Mangled(qn,
|
|
|
+ SymTab.ProcUid(qn), qm0);
|
|
|
+ QbeGen.ProcAddr(qm0, q)
|
|
|
END
|
|
|
END; .)
|
|
|
| ( "HIGH" (. isHigh := TRUE; .)
|