|
|
@@ -541,6 +541,10 @@ PROCEDURE CanStmt (n: AST.Node): BOOLEAN;
|
|
|
PROCEDURE CanDecl (c: AST.Node): BOOLEAN;
|
|
|
VAR i: CARDINAL;
|
|
|
BEGIN
|
|
|
+ IF AST.Kind(c) = AST.NkUnit THEN
|
|
|
+ IF AST.Child(c, 3) # AST.NoNode THEN RETURN FALSE END;
|
|
|
+ RETURN CanDecls(AST.Child(c, 1)) AND CanStmt(AST.Child(c, 2))
|
|
|
+ END;
|
|
|
IF AST.Kind(c) = AST.NkTypeDecl THEN RETURN TRUE END;
|
|
|
IF AST.Kind(c) = AST.NkVarDecl THEN
|
|
|
IF NOT CanType(AST.Ty(c)) THEN RETURN FALSE END;
|
|
|
@@ -1336,6 +1340,32 @@ PROCEDURE LowerStmt (seq: AST.Node);
|
|
|
END
|
|
|
END LowerStmt;
|
|
|
|
|
|
+PROCEDURE ReenterGlobals (seq: AST.Node);
|
|
|
+(* Re-registers a nested module's non-exported globals in the enclosing
|
|
|
+ (still-open) module scope, so QbeGen.GlobalRef can resolve their
|
|
|
+ "<outer>_<name>" symbols after the nested scope has been popped. *)
|
|
|
+ VAR i, j: CARDINAL; c: AST.Node; nm: SymTab.Name;
|
|
|
+ BEGIN
|
|
|
+ IF seq = AST.NoNode THEN RETURN END;
|
|
|
+ i := 0;
|
|
|
+ WHILE i < AST.NChild(seq) DO
|
|
|
+ c := AST.Child(seq, i);
|
|
|
+ IF i = AST.MaxChild - 1 THEN ReenterGlobals(c)
|
|
|
+ ELSIF AST.Kind(c) = AST.NkDeclSeq THEN ReenterGlobals(c)
|
|
|
+ ELSIF AST.Kind(c) = AST.NkVarDecl THEN
|
|
|
+ j := 0;
|
|
|
+ WHILE j < AST.NChild(c) DO
|
|
|
+ Name(AST.Child(c, j), nm);
|
|
|
+ IF SymTab.Enter(nm, SymTab.KindVar) THEN
|
|
|
+ SymTab.SetSymType(nm, AST.Ty(c))
|
|
|
+ END;
|
|
|
+ INC(j)
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ INC(i)
|
|
|
+ END
|
|
|
+ END ReenterGlobals;
|
|
|
+
|
|
|
PROCEDURE LowerDecls (seq: AST.Node);
|
|
|
VAR i, j: CARDINAL; c: AST.Node; nm, txt: SymTab.Name; qv: QbeGen.QVal;
|
|
|
mg: QbeGen.QVal; uid, depth, np: CARDINAL; res, pt: SymTab.TypeIndex;
|
|
|
@@ -1347,6 +1377,15 @@ PROCEDURE LowerDecls (seq: AST.Node);
|
|
|
c := AST.Child(seq, i);
|
|
|
IF i = AST.MaxChild - 1 THEN LowerDecls(c)
|
|
|
ELSIF AST.Kind(c) = AST.NkDeclSeq THEN LowerDecls(c)
|
|
|
+ ELSIF AST.Kind(c) = AST.NkUnit THEN
|
|
|
+ Name(AST.Child(c, 0), nm);
|
|
|
+ ReenterGlobals(AST.Child(c, 1));
|
|
|
+ LowerDecls(AST.Child(c, 1));
|
|
|
+ IF AST.Child(c, 2) # AST.NoNode THEN
|
|
|
+ QbeGen.BeginInit(nm);
|
|
|
+ LowerStmt(AST.Child(c, 2));
|
|
|
+ QbeGen.EndInit
|
|
|
+ END
|
|
|
ELSIF AST.Kind(c) = AST.NkVarDecl THEN
|
|
|
j := 0;
|
|
|
WHILE j < AST.NChild(c) DO
|