Copyright (C) 1992, Digital Equipment Corporation
All rights reserved.
See the file COPYRIGHT for a full description.
Last modified on Mon Oct 31 10:06:18 PST 1994 by heydon
modified on Fri Aug 7 21:54:02 PDT 1992 by myers
MODULE JunoAST;
IMPORT JunoASTUtils;
IMPORT Atom;
TYPE (* declare special Nil types *)
NilExprT = Expr BRANDED "JunoAST.NilExprT" OBJECT END;
REVEAL
T = TPub BRANDED "JunoAST.T" OBJECT OVERRIDES
iterator := EmptyIt
END;
Assign = AssignPub BRANDED "JunoAST.Assign" OBJECT OVERRIDES
iterator := AssignIt
END;
ProcCall = ProcCallPub BRANDED "JunoAST.ProcCall" OBJECT OVERRIDES
iterator := ProcCallIt
END;
BodyCmd = BodyCmdPub BRANDED "JunoAST.BodyCmd" OBJECT OVERRIDES
iterator := BodyCmdIt
END;
Proj = ProjPub BRANDED "JunoAST.Proj" OBJECT OVERRIDES
iterator := ProjIt
END;
Guard = GuardPub BRANDED "JunoAST.Guard" OBJECT OVERRIDES
iterator := GuardIt
END;
TwoCmd = TwoCmdPub BRANDED "JunoAST.TwoCmd" OBJECT OVERRIDES
iterator := TwoCmdIt
END;
Query = QueryPub BRANDED "JunoAST.Query" OBJECT OVERRIDES
iterator := QueryIt
END;
TwoForm = TwoFormPub BRANDED "JunoAST.TwoForm" OBJECT OVERRIDES
iterator := TwoFormIt
END;
Not = NotPub BRANDED "JunoAST.Not" OBJECT OVERRIDES
iterator := NotIt
END;
Exists = ExistsPub BRANDED "JunoAST.Exists" OBJECT OVERRIDES
iterator := ExistsIt
END;
BIUPred = BIUPredPub BRANDED "JunoAST.BIUPred" OBJECT OVERRIDES
iterator := BIUPredIt
END;
Relation = RelationPub BRANDED "JunoAST.Relation" OBJECT OVERRIDES
iterator := RelationIt
END;
BIUFunc = BIUFuncPub BRANDED "JunoAST.BIUFunc" OBJECT OVERRIDES
iterator := BIUFuncIt
END;
BIBFunc = BIBFuncPub BRANDED "JunoAST.BIBFunc" OBJECT OVERRIDES
iterator := BIBFuncIt
END;
List = ListPub BRANDED "JunoAST.List" OBJECT OVERRIDES
iterator := ListIt
END;
Call = CallPub BRANDED "JunoAST.Call" OBJECT OVERRIDES
iterator := CallIt
END;
ExprList = ExprListPub BRANDED "JunoAST.ExprList" OBJECT OVERRIDES
iterator := ExprListIt
END;
ConjQuery = ConjQueryPub BRANDED "JunoAST.ConjQuery" OBJECT OVERRIDES
iterator := ConjQueryIt
END;
GroupedExpr = GroupedExprPub BRANDED "JunoAST.GroupedExpr" OBJECT OVERRIDES
iterator := GroupedExprIt
END;
NormalForm = NormalFormPub BRANDED "JunoAST.NormalForm" OBJECT OVERRIDES
iterator := NormalFormIt
END;
NearVarList = NearVarListPub BRANDED "JunoAST.NearVarList" OBJECT OVERRIDES
iterator := NearVarListIt
END;
TYPE
FieldIter = Iterator BRANDED "JunoAST.FieldIter" OBJECT
field := 0
END;
AssignIter = FieldIter BRANDED "JunoAST.AssignIter" OBJECT
ast: Assign
END;
ProcCallIter = FieldIter BRANDED "JunoAST.ProcCallIter" OBJECT
ast: ProcCall
END;
BodyCmdIter = FieldIter BRANDED "JunoAST.BodyCmdIter" OBJECT
ast: BodyCmd
END;
ProjIter = FieldIter BRANDED "JunoAST.ProjIter" OBJECT
ast: Proj
END;
GuardIter = FieldIter BRANDED "JunoAST.GuardIter" OBJECT
ast: Guard
END;
TwoCmdIter = FieldIter BRANDED "JunoAST.TwoCmdIter" OBJECT
ast: TwoCmd
END;
QueryIter = FieldIter BRANDED "JunoAST.QueryIter" OBJECT
ast: Query
END;
TwoFormIter = FieldIter BRANDED "JunoAST.TwoFormIter" OBJECT
ast: TwoForm
END;
NotIter = FieldIter BRANDED "JunoAST.NotIter" OBJECT
ast: Not
END;
ExistsIter = FieldIter BRANDED "JunoAST.ExistsIter" OBJECT
ast: Exists
END;
BIUPredIter = FieldIter BRANDED "JunoAST.BIUPredIter" OBJECT
ast: BIUPred
END;
RelationIter = FieldIter BRANDED "JunoAST.RelationIter" OBJECT
ast: Relation
END;
BIUFuncIter = FieldIter BRANDED "JunoAST.BIUFuncIter" OBJECT
ast: BIUFunc
END;
BIBFuncIter = FieldIter BRANDED "JunoAST.BIBFuncIter" OBJECT
ast: BIBFunc
END;
ExprListIter = Iterator BRANDED "JunoAST.ExprListIter" OBJECT
curr: ExprLink
END;
CallIter = FieldIter BRANDED "JunoAST.CallIter" OBJECT
ast: Call
END;
GrpExprIter = FieldIter BRANDED "JunoAST.GrpExprIter" OBJECT
ast: GroupedExpr
END;
ConjQueryIter = Iterator BRANDED "JunoAST.ConjQueryIter" OBJECT
forms: REF Formulas;
curr := 0
END;
NormalFormIter = Iterator BRANDED "JunoAST.NormalFormIter" OBJECT
forms: REF Formulas;
curr := 0
END;
NVListIter = Iterator BRANDED "JunoAST.NVListIter" OBJECT
curr: NearVarLink
END;
PROCEDURE EmptyIt(<*UNUSED*> ast: T): Iterator =
BEGIN RETURN NEW(Iterator, next := NoNext) END EmptyIt;
PROCEDURE NoNext(
<*UNUSED*> it: Iterator;
<*UNUSED*> VAR (*OUT*) child: T):
BOOLEAN =
BEGIN RETURN FALSE END NoNext;
PROCEDURE AssignIt(ast: Assign): Iterator =
BEGIN RETURN NEW(AssignIter, ast := ast, next := AssignNext) END AssignIt;
PROCEDURE AssignNext(it: AssignIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.vars
| 1 => child := it.ast.exprs
| 2 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END AssignNext;
PROCEDURE ProcCallIt(ast: ProcCall): Iterator =
BEGIN
RETURN NEW(ProcCallIter, ast := ast, next := ProcCallNext)
END ProcCallIt;
PROCEDURE ProcCallNext(it: ProcCallIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.outs
| 1 => child := it.ast.inouts
| 2 => child := it.ast.name
| 3 => child := it.ast.ins
| 4 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END ProcCallNext;
PROCEDURE BodyCmdIt(ast: BodyCmd): Iterator =
BEGIN RETURN NEW(BodyCmdIter, ast := ast, next := BodyCmdNext) END BodyCmdIt;
PROCEDURE BodyCmdNext(it: BodyCmdIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.body
| 1 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END BodyCmdNext;
PROCEDURE ProjIt(ast: Proj): Iterator =
BEGIN RETURN NEW(ProjIter, ast := ast, next := ProjNext) END ProjIt;
PROCEDURE ProjNext(it: ProjIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.vars
| 1 => child := it.ast.body
| 2 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END ProjNext;
PROCEDURE GuardIt(ast: Guard): Iterator =
BEGIN RETURN NEW(GuardIter, ast := ast, next := GuardNext) END GuardIt;
PROCEDURE GuardNext(it: GuardIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.grd
| 1 => child := it.ast.body
| 2 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END GuardNext;
PROCEDURE TwoCmdIt(ast: TwoCmd): Iterator =
BEGIN RETURN NEW(TwoCmdIter, ast := ast, next := TwoCmdNext) END TwoCmdIt;
PROCEDURE TwoCmdNext(it: TwoCmdIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.c1
| 1 => child := it.ast.c2
| 2 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END TwoCmdNext;
PROCEDURE QueryIt(ast: Query): Iterator =
BEGIN RETURN NEW(QueryIter, ast := ast, next := QueryNext) END QueryIt;
PROCEDURE QueryNext(it: QueryIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.f
| 1 => child := it.ast.vars
| 2 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END QueryNext;
PROCEDURE ConjQueryIt(ast: ConjQuery): Iterator =
BEGIN
RETURN NEW(ConjQueryIter, forms := ast.conj, next := ConjQueryNext)
END ConjQueryIt;
PROCEDURE ConjQueryNext(it: ConjQueryIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
IF it.curr > LAST(it.forms^) THEN RETURN FALSE END;
child := it.forms[it.curr];
INC(it.curr);
RETURN TRUE
END ConjQueryNext;
PROCEDURE TwoFormIt(ast: TwoForm): Iterator =
BEGIN RETURN NEW(TwoFormIter, ast := ast, next := TwoFormNext) END TwoFormIt;
PROCEDURE TwoFormNext(it: TwoFormIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.f1
| 1 => child := it.ast.f2
| 2 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END TwoFormNext;
PROCEDURE NotIt(ast: Not): Iterator =
BEGIN RETURN NEW(NotIter, ast := ast, next := NotNext) END NotIt;
PROCEDURE NotNext(it: NotIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.f
| 1 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END NotNext;
PROCEDURE ExistsIt(ast: Exists): Iterator =
BEGIN RETURN NEW(ExistsIter, ast := ast, next := ExistsNext) END ExistsIt;
PROCEDURE ExistsNext(it: ExistsIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.vars
| 1 => child := it.ast.f
| 2 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END ExistsNext;
PROCEDURE BIUPredIt(ast: BIUPred): Iterator =
BEGIN RETURN NEW(BIUPredIter, ast := ast, next := BIUPredNext) END BIUPredIt;
PROCEDURE BIUPredNext(it: BIUPredIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.e
| 1 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END BIUPredNext;
PROCEDURE RelationIt(ast: Relation): Iterator =
BEGIN
RETURN NEW(RelationIter, ast := ast, next := RelationNext)
END RelationIt;
PROCEDURE RelationNext(it: RelationIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.e1
| 1 => child := it.ast.e2
| 2 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END RelationNext;
PROCEDURE BIUFuncIt(ast: BIUFunc): Iterator =
BEGIN RETURN NEW(BIUFuncIter, ast := ast, next := BIUFuncNext) END BIUFuncIt;
PROCEDURE BIUFuncNext(it: BIUFuncIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.e
| 1 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END BIUFuncNext;
PROCEDURE BIBFuncIt(ast: BIBFunc): Iterator =
BEGIN RETURN NEW(BIBFuncIter, ast := ast, next := BIBFuncNext) END BIBFuncIt;
PROCEDURE BIBFuncNext(it: BIBFuncIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.e1
| 1 => child := it.ast.e2
| 2 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END BIBFuncNext;
PROCEDURE ListIt(ast: List): Iterator =
BEGIN
RETURN NEW(ExprListIter, curr := ast.elts.head, next := ExprListNext)
END ListIt;
PROCEDURE ExprListIt(ast: ExprList): Iterator =
BEGIN
RETURN NEW(ExprListIter, curr := ast.head, next := ExprListNext)
END ExprListIt;
PROCEDURE ExprListNext(it: ExprListIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
IF it.curr = NIL THEN RETURN FALSE END;
child := it.curr.expr;
it.curr := it.curr.next;
RETURN TRUE
END ExprListNext;
PROCEDURE CallIt(ast: Call): Iterator =
BEGIN RETURN NEW(CallIter, ast := ast, next := CallNext) END CallIt;
PROCEDURE CallNext(it: CallIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.inouts
| 1 => child := it.ast.name
| 2 => child := it.ast.ins
| 3 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END CallNext;
PROCEDURE GroupedExprIt(ast: GroupedExpr): Iterator =
BEGIN
RETURN NEW(GrpExprIter, ast := ast, next := GroupedExprNext)
END GroupedExprIt;
PROCEDURE GroupedExprNext(it: GrpExprIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
CASE it.field OF <* NOWARN *>
0 => child := it.ast.expr
| 1 => RETURN FALSE
END;
INC(it.field);
RETURN TRUE
END GroupedExprNext;
PROCEDURE NormalFormIt(ast: NormalForm): Iterator =
BEGIN
RETURN NEW(NormalFormIter, forms := ast.conj, next := NormalFormNext)
END NormalFormIt;
PROCEDURE NormalFormNext(it: NormalFormIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
IF it.curr > LAST(it.forms^) THEN RETURN FALSE END;
child := it.forms[it.curr];
INC(it.curr);
RETURN TRUE
END NormalFormNext;
PROCEDURE NearVarListIt(ast: NearVarList): Iterator =
BEGIN
RETURN NEW(NVListIter, curr := ast.head, next := NearVarListNext)
END NearVarListIt;
PROCEDURE NearVarListNext(it: NVListIter; VAR (*OUT*) child: T): BOOLEAN =
BEGIN
IF it.curr = NIL THEN RETURN FALSE END;
child := it.curr.hint;
it.curr := it.curr.next;
RETURN TRUE
END NearVarListNext;
REVEAL
Block = T BRANDED "JunoAST.Block" OBJECT END;
Decl = DeclPublic BRANDED "JunoAST.Decl" OBJECT END;
Cmd = T BRANDED "JunoAST.Cmd" OBJECT END;
LitPred = Formula BRANDED "JunoAST.LitPred" OBJECT END;
AtomicExpr = Expr BRANDED "JunoAST.AtomicExpr" OBJECT END;
BuiltInPred = Expr BRANDED "JunoAST.BuiltInPred" OBJECT END;
BuiltInFunc = Expr BRANDED "JunoAST.BuiltInFunc" OBJECT END;
PROCEDURE Predecessor(ast: T): T =
VAR node: T := ast; BEGIN
WHILE node # NIL AND node.bp # End DO node := node.bp END;
<* ASSERT node = NIL OR node.bp = End *>
RETURN node
END Predecessor;
BEGIN
(* Initialize special Nil variables *)
NilId := Atom.FromText("*NilId*");
NilExpr := NEW(NilExprT);
(* Initialize empty lists *)
EmptyIdList := NEW(IdList);
EmptyNVList := NEW(NearVarList);
EmptyQIdList := NEW(QIdList);
EmptyExprList := EmptyQIdList;
(* Initialize constant structures *)
End := NEW(T);
SkipVal := NEW(Skip, bp := End);
AbortVal := NEW(Abort, bp := End);
HaltVal := NEW(Halt, bp := End);
FailVal := NEW(Fail, bp := End);
TrueVal := NEW(True, bp := End);
FalseVal := NEW(False, bp := End);
NilVal := NEW(Nil, bp := End);
(* Initialize pred and func names *)
CongName := JunoASTUtils.QIdFromText("_CONG");
ParaName := JunoASTUtils.QIdFromText("_PARA");
HorName := JunoASTUtils.QIdFromText("_HOR");
VerName := JunoASTUtils.QIdFromText("_VER");
UMinusName := JunoASTUtils.QIdFromText("_UMINUS");
CarName := JunoASTUtils.QIdFromText("_CAR");
CdrName := JunoASTUtils.QIdFromText("_CDR");
MinusName := JunoASTUtils.QIdFromText("_MINUS");
DivideName := JunoASTUtils.QIdFromText("_DIVIDE");
RelName := JunoASTUtils.QIdFromText("_REL");
END JunoAST.