|
|
@@ -77,6 +77,10 @@ VAR
|
|
|
statement. StatSeq folds these into an NkBlock. *)
|
|
|
astStmt: AST.Node;
|
|
|
|
|
|
+ (* Declaration-AST result slot (slice 6): the most recently built
|
|
|
+ declaration; DeclSeq folds these into an NkDeclSeq. *)
|
|
|
+ astDecl: AST.Node;
|
|
|
+
|
|
|
(* Class of the method named by the last `obj.Method` designator
|
|
|
(InvalidType when the callee is an ordinary procedure). Set by
|
|
|
Design, consumed by the following ArgList. *)
|
|
|
@@ -186,7 +190,7 @@ TOKENS
|
|
|
|
|
|
PRODUCTIONS
|
|
|
M2
|
|
|
- = (. AST.Init; twoPhase := TRUE; astCur := AST.NoNode; astStmt := AST.NoNode; .)
|
|
|
+ = (. AST.Init; twoPhase := TRUE; astCur := AST.NoNode; astStmt := AST.NoNode; astDecl := AST.NoNode; .)
|
|
|
Unit "." .
|
|
|
(* Units: program modules compile fully; DEFINITION and
|
|
|
IMPLEMENTATION modules parse + check now but lower in step 4
|
|
|
@@ -292,9 +296,15 @@ PRODUCTIONS
|
|
|
SemError(202) END;
|
|
|
QbeGen.EndModule(m1);
|
|
|
SymTab.EndUnit; .) .
|
|
|
- DeclSeq
|
|
|
- = { ConstBlock | TypeBlock<FALSE> | VarBlock | ProcDecl ";"
|
|
|
- | NestedModule ";" | ClassItem ";" } .
|
|
|
+ DeclSeq (. VAR astSeq: AST.Node; .)
|
|
|
+ = (. astSeq := AST.MakeNode(AST.NkDeclSeq); .)
|
|
|
+ { (. astDecl := AST.NoNode; .)
|
|
|
+ ( ConstBlock | TypeBlock<FALSE> | VarBlock | ProcDecl ";"
|
|
|
+ | NestedModule ";" | ClassItem ";" )
|
|
|
+ (. IF astDecl # AST.NoNode THEN
|
|
|
+ AST.SetChild(astSeq,
|
|
|
+ AST.NChild(astSeq), astDecl) END; .) }
|
|
|
+ (. astDecl := astSeq; .) .
|
|
|
(* Local module, Wirth form. Declarations lower like top-level ones
|
|
|
(same QBE module prefix); a BEGIN body becomes an init function
|
|
|
that main calls; the EXPORT list is hoisted into the enclosing
|
|
|
@@ -374,14 +384,20 @@ PRODUCTIONS
|
|
|
{ TypeItem<isDef> ";" | ClassItem ";" }
|
|
|
(. SymTab.EndTypeBlock; .) .
|
|
|
TypeItem<isDef: BOOLEAN> (. VAR n: SymTab.Name;
|
|
|
- t, op: SymTab.TypeIndex; .)
|
|
|
+ t, op: SymTab.TypeIndex;
|
|
|
+ astNode: AST.Node; .)
|
|
|
= GetIdent<n> (. op := SymTab.OpaqueBase(n);
|
|
|
IF op = SymTab.InvalidType THEN
|
|
|
IF NOT SymTab.Enter(n,
|
|
|
SymTab.KindType) THEN
|
|
|
SemError(200) END
|
|
|
END; .)
|
|
|
- ( "=" Type<t, FALSE> (. IF op # SymTab.InvalidType THEN
|
|
|
+ ( "=" Type<t, FALSE> (. astNode := AST.MakeNode(AST.NkTypeDecl);
|
|
|
+ AST.SetChild(astNode, 0,
|
|
|
+ AST.MakeLeaf(AST.NkIdent, n));
|
|
|
+ AST.SetTy(astNode, t);
|
|
|
+ astDecl := astNode;
|
|
|
+ IF op # SymTab.InvalidType THEN
|
|
|
SymTab.SetTarget(op, t)
|
|
|
ELSE SymTab.SetSymType(n, t)
|
|
|
END; .)
|
|
|
@@ -802,17 +818,29 @@ PRODUCTIONS
|
|
|
methRes := SymTab.CurRes();
|
|
|
SymTab.CloseProc;
|
|
|
QbeGen.EndFunc(methRes); .) ) .
|
|
|
- ConstBlock
|
|
|
- = "CONST" { ConstDecl ";" } .
|
|
|
+ ConstBlock (. VAR astSeq: AST.Node; .)
|
|
|
+ = "CONST" (. astSeq := AST.MakeNode(AST.NkDeclSeq);
|
|
|
+ astDecl := AST.NoNode; .)
|
|
|
+ { ConstDecl ";" (. IF astDecl # AST.NoNode THEN
|
|
|
+ AST.SetChild(astSeq,
|
|
|
+ AST.NChild(astSeq), astDecl) END; .) }
|
|
|
+ (. astDecl := astSeq; .) .
|
|
|
ConstDecl (. VAR n: SymTab.Name;
|
|
|
t: SymTab.TypeIndex;
|
|
|
qv: QbeGen.QVal;
|
|
|
- cls: INTEGER; .)
|
|
|
+ cls: INTEGER;
|
|
|
+ astNode: AST.Node; .)
|
|
|
= GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
SymTab.KindConst) THEN
|
|
|
SemError(200) END; .)
|
|
|
"="
|
|
|
- Expr<t, qv> (. SymTab.SetSymType(n, t);
|
|
|
+ Expr<t, qv> (. astNode := AST.MakeNode(AST.NkConstDecl);
|
|
|
+ AST.SetChild(astNode, 0,
|
|
|
+ AST.MakeLeaf(AST.NkIdent, n));
|
|
|
+ AST.SetChild(astNode, 1, astCur);
|
|
|
+ AST.SetTy(astNode, t);
|
|
|
+ astDecl := astNode;
|
|
|
+ SymTab.SetSymType(n, t);
|
|
|
cls := SymTab.ClassOf(t);
|
|
|
IF (cls = SymTab.ClArray)
|
|
|
OR (cls = SymTab.ClRecord)
|
|
|
@@ -830,14 +858,31 @@ PRODUCTIONS
|
|
|
SymTab.SetSymVal(n, qv);
|
|
|
QbeGen.DeclConst(n, qv, t)
|
|
|
END; .) .
|
|
|
- VarBlock
|
|
|
- = "VAR" { VarDecl ";" } .
|
|
|
+ VarBlock (. VAR astSeq: AST.Node; .)
|
|
|
+ = "VAR" (. astSeq := AST.MakeNode(AST.NkDeclSeq);
|
|
|
+ astDecl := AST.NoNode; .)
|
|
|
+ { VarDecl ";" (. IF astDecl # AST.NoNode THEN
|
|
|
+ AST.SetChild(astSeq,
|
|
|
+ AST.NChild(astSeq), astDecl) END; .) }
|
|
|
+ (. astDecl := astSeq; .) .
|
|
|
VarDecl (. VAR nm: SymTab.Name;
|
|
|
t: SymTab.TypeIndex;
|
|
|
i: CARDINAL;
|
|
|
- cls: INTEGER; .)
|
|
|
+ cls: INTEGER;
|
|
|
+ astNode: AST.Node; .)
|
|
|
= VarIdents ":"
|
|
|
- Type<t, FALSE> (. cls := SymTab.ClassOf(t);
|
|
|
+ Type<t, FALSE> (. astNode := AST.MakeNode(AST.NkVarDecl);
|
|
|
+ i := 0;
|
|
|
+ WHILE i < SymTab.PendCount() DO
|
|
|
+ SymTab.PendName(i, nm);
|
|
|
+ AST.SetChild(astNode,
|
|
|
+ AST.NChild(astNode),
|
|
|
+ AST.MakeLeaf(AST.NkIdent, nm));
|
|
|
+ INC(i)
|
|
|
+ END;
|
|
|
+ AST.SetTy(astNode, t);
|
|
|
+ astDecl := astNode;
|
|
|
+ cls := SymTab.ClassOf(t);
|
|
|
IF (t # SymTab.InvalidType)
|
|
|
AND NOT SymTab.IsUnresolved(t)
|
|
|
AND (cls # SymTab.ClInt)
|
|
|
@@ -986,20 +1031,30 @@ PRODUCTIONS
|
|
|
(* Nested procedures lower like top-level ones (4.2): the
|
|
|
static link gives them their parent's frame. Methods keep
|
|
|
parse-now/230-later. *)
|
|
|
- ProcDecl (. VAR pn: SymTab.Name; .)
|
|
|
+ ProcDecl (. VAR pn: SymTab.Name;
|
|
|
+ astNode: AST.Node; .)
|
|
|
= ProcHeading<pn, SymTab.InvalidType> ";"
|
|
|
- ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
+ (. astNode := AST.MakeNode(AST.NkProcDecl);
|
|
|
+ AST.SetChild(astNode, 0,
|
|
|
+ AST.MakeLeaf(AST.NkIdent, pn)); .)
|
|
|
+ ( "FORWARD" (. AST.SetOp(astNode, 1);
|
|
|
+ astDecl := astNode;
|
|
|
+ SymTab.MarkFwd;
|
|
|
SymTab.CloseProc;
|
|
|
QbeGen.AbortFunc; .)
|
|
|
- | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
+ | "EXTERNAL" (. AST.SetOp(astNode, 2);
|
|
|
+ astDecl := astNode;
|
|
|
+ SymTab.MarkExternal("");
|
|
|
SymTab.CloseProc;
|
|
|
QbeGen.AbortFunc; .)
|
|
|
| (. QbeGen.EndFuncHeader; .)
|
|
|
- Block<pn> (. SymTab.CloseProc;
|
|
|
+ Block<pn> (. AST.SetChild(astNode, 1, astStmt);
|
|
|
+ astDecl := astNode;
|
|
|
+ SymTab.CloseProc;
|
|
|
QbeGen.EndFunc(
|
|
|
SymTab.ProcRes(pn)); .) ) .
|
|
|
Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
- = DeclSeq
|
|
|
+ = DeclSeq (. astStmt := AST.NoNode; .)
|
|
|
[ "BEGIN"
|
|
|
[ StatSeq ] ]
|
|
|
"END"
|