|
@@ -106,25 +106,48 @@ BEGIN
|
|
|
RETURN t
|
|
RETURN t
|
|
|
END EvalExpr;
|
|
END EvalExpr;
|
|
|
|
|
|
|
|
-PROCEDURE PropNode (n: AST.Node);
|
|
|
|
|
|
|
+PROCEDURE CheckAssign (n: AST.Node);
|
|
|
|
|
+(* Re-check a designator assignment whose operand types were unknown at
|
|
|
|
|
+ parse time (a forward reference): the parser skipped it. *)
|
|
|
|
|
+ VAR lt, vt: SymTab.TypeIndex;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF AST.Child(n, 0) < 0 THEN RETURN END;
|
|
|
|
|
+ IF AST.Kind(AST.Child(n, 0)) # AST.NkDesignator THEN RETURN END;
|
|
|
|
|
+ lt := AST.Ty(AST.Child(n, 0));
|
|
|
|
|
+ vt := AST.Ty(AST.Child(n, 1));
|
|
|
|
|
+ IF (lt = SymTab.InvalidType) OR (vt = SymTab.InvalidType) THEN RETURN END;
|
|
|
|
|
+ IF NOT SymTab.Assignable(vt, lt) THEN
|
|
|
|
|
+ M2S.Error(210, M2S.line, M2S.col, M2S.pos)
|
|
|
|
|
+ ELSIF SymTab.ClassOf(lt) = SymTab.ClClass THEN
|
|
|
|
|
+ M2S.Error(230, M2S.line, M2S.col, M2S.pos)
|
|
|
|
|
+ END
|
|
|
|
|
+END CheckAssign;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE PropNode (n: AST.Node): BOOLEAN;
|
|
|
(* Post-order: re-type any expression node whose type is still unknown
|
|
(* Post-order: re-type any expression node whose type is still unknown
|
|
|
- (i.e. one whose operands included a forward reference). *)
|
|
|
|
|
- VAR i: CARDINAL; k: INTEGER; t: SymTab.TypeIndex;
|
|
|
|
|
|
|
+ (i.e. one whose operands included a forward reference), and re-check an
|
|
|
|
|
+ assignment statement whose operands were so affected. Returns TRUE
|
|
|
|
|
+ when this subtree was touched by a forward reference. *)
|
|
|
|
|
+ VAR i: CARDINAL; k: INTEGER; t: SymTab.TypeIndex; tn: BOOLEAN;
|
|
|
BEGIN
|
|
BEGIN
|
|
|
- IF n < 0 THEN RETURN END;
|
|
|
|
|
|
|
+ IF n < 0 THEN RETURN FALSE END;
|
|
|
k := AST.Kind(n);
|
|
k := AST.Kind(n);
|
|
|
IF (k >= AST.NkIdent) AND (k <= AST.NkCharLit) THEN
|
|
IF (k >= AST.NkIdent) AND (k <= AST.NkCharLit) THEN
|
|
|
- RETURN (* a leaf: child 0 is a text index, not a node *)
|
|
|
|
|
|
|
+ RETURN FALSE (* a leaf: child 0 is a text index, not a node *)
|
|
|
END;
|
|
END;
|
|
|
|
|
+ tn := (k = AST.NkDesignator) AND (AST.Op(n) = 1);
|
|
|
i := 0;
|
|
i := 0;
|
|
|
WHILE i < AST.NChild(n) DO
|
|
WHILE i < AST.NChild(n) DO
|
|
|
- PropNode(AST.Child(n, i)); INC(i)
|
|
|
|
|
|
|
+ IF PropNode(AST.Child(n, i)) THEN tn := TRUE END;
|
|
|
|
|
+ INC(i)
|
|
|
END;
|
|
END;
|
|
|
IF (k >= AST.NkBinExpr) AND (k <= AST.NkSetLit)
|
|
IF (k >= AST.NkBinExpr) AND (k <= AST.NkSetLit)
|
|
|
AND (AST.Ty(n) = -1) THEN
|
|
AND (AST.Ty(n) = -1) THEN
|
|
|
t := EvalExpr(n);
|
|
t := EvalExpr(n);
|
|
|
- IF t # -1 THEN AST.SetTy(n, t) END
|
|
|
|
|
- END
|
|
|
|
|
|
|
+ IF t # -1 THEN AST.SetTy(n, t); tn := TRUE END
|
|
|
|
|
+ END;
|
|
|
|
|
+ IF (k = AST.NkAssign) AND tn THEN CheckAssign(n) END;
|
|
|
|
|
+ RETURN tn
|
|
|
END PropNode;
|
|
END PropNode;
|
|
|
|
|
|
|
|
PROCEDURE BeginSession (progName: ARRAY OF CHAR);
|
|
PROCEDURE BeginSession (progName: ARRAY OF CHAR);
|
|
@@ -170,9 +193,10 @@ BEGIN
|
|
|
END FlushForward;
|
|
END FlushForward;
|
|
|
|
|
|
|
|
PROCEDURE Resolve (unit: AST.Node);
|
|
PROCEDURE Resolve (unit: AST.Node);
|
|
|
|
|
+ VAR touched: BOOLEAN;
|
|
|
BEGIN
|
|
BEGIN
|
|
|
FlushForward;
|
|
FlushForward;
|
|
|
- PropNode(unit)
|
|
|
|
|
|
|
+ touched := PropNode(unit)
|
|
|
END Resolve;
|
|
END Resolve;
|
|
|
|
|
|
|
|
PROCEDURE EndSession;
|
|
PROCEDURE EndSession;
|