|
|
@@ -1782,6 +1782,70 @@ PROCEDURE LowerDecls (seq: AST.Node);
|
|
|
END
|
|
|
END LowerDecls;
|
|
|
|
|
|
+PROCEDURE MaterializeGlobals (unitName: ARRAY OF CHAR; decls: AST.Node);
|
|
|
+(* Make a unit's module-level VAR/CONST visible in the (global) scope
|
|
|
+ Lower runs in at session end, so GlobalRef resolves "<unit>_<name>". *)
|
|
|
+ VAR i, j: CARDINAL; c: AST.Node; nm: SymTab.Name;
|
|
|
+ BEGIN
|
|
|
+ IF decls = AST.NoNode THEN RETURN END;
|
|
|
+ i := 0;
|
|
|
+ WHILE i < AST.NChild(decls) DO
|
|
|
+ c := AST.Child(decls, i);
|
|
|
+ IF i = AST.MaxChild - 1 THEN MaterializeGlobals(unitName, c)
|
|
|
+ ELSIF AST.Kind(c) = AST.NkDeclSeq THEN MaterializeGlobals(unitName, c)
|
|
|
+ ELSIF (AST.Kind(c) = AST.NkVarDecl) OR (AST.Kind(c) = AST.NkConstDecl) THEN
|
|
|
+ j := 0;
|
|
|
+ WHILE j < AST.NChild(c) DO
|
|
|
+ IF AST.Kind(AST.Child(c, j)) = AST.NkIdent THEN
|
|
|
+ Name(AST.Child(c, j), nm);
|
|
|
+ IF NOT SymTab.Materialize(unitName, nm) THEN END
|
|
|
+ END;
|
|
|
+ INC(j)
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ INC(i)
|
|
|
+ END
|
|
|
+ END MaterializeGlobals;
|
|
|
+
|
|
|
+PROCEDURE LowerOneUnit (u: AST.Node; isProg: BOOLEAN);
|
|
|
+ VAR nm: SymTab.Name;
|
|
|
+ BEGIN
|
|
|
+ Name(AST.Child(u, 0), nm);
|
|
|
+ QbeGen.SetModule(nm);
|
|
|
+ MaterializeGlobals(nm, AST.Child(u, 1));
|
|
|
+ LowerDecls(AST.Child(u, 1));
|
|
|
+ IF isProg THEN
|
|
|
+ QbeGen.BeginBody;
|
|
|
+ LowerStmt(AST.Child(u, 2))
|
|
|
+ ELSIF AST.Child(u, 2) # AST.NoNode THEN
|
|
|
+ QbeGen.BeginInit(nm);
|
|
|
+ LowerStmt(AST.Child(u, 2));
|
|
|
+ QbeGen.EndInit
|
|
|
+ END
|
|
|
+ END LowerOneUnit;
|
|
|
+
|
|
|
+PROCEDURE LowerSession (units: ARRAY OF AST.Node; n: CARDINAL;
|
|
|
+ progName: ARRAY OF CHAR);
|
|
|
+(* Re-emit a whole session (all units, in order) into one image. *)
|
|
|
+ VAR i, j: CARDINAL; out: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ BEGIN
|
|
|
+ j := 0;
|
|
|
+ WHILE (j <= 254) AND (j <= HIGH(progName)) AND (progName[j] # CHR(0)) DO
|
|
|
+ out[j] := progName[j]; INC(j)
|
|
|
+ END;
|
|
|
+ out[j] := "L"; INC(j); out[j] := CHR(0);
|
|
|
+ withTop := 0;
|
|
|
+ curImplCls := SymTab.InvalidType;
|
|
|
+ QbeGen.OpenModule(progName);
|
|
|
+ QbeGen.SetOutName(out);
|
|
|
+ i := 0;
|
|
|
+ WHILE i < n DO
|
|
|
+ LowerOneUnit(units[i], i = n - 1);
|
|
|
+ INC(i)
|
|
|
+ END;
|
|
|
+ QbeGen.EndModule(progName)
|
|
|
+ END LowerSession;
|
|
|
+
|
|
|
PROCEDURE LowerUnit (unit: AST.Node);
|
|
|
VAR nm: SymTab.Name; out: ARRAY [0 .. 255] OF CHAR; i: CARDINAL;
|
|
|
BEGIN
|