ExpressTreeImpl.mesa
Handles the Expression parsing trees for the Express Package
Created Tuesday, July 17, 1984 3:05 pm PDT
Last edited by Eric Nickell, July 18, 1984 1:09:13 pm PDT
DIRECTORY
ExpressTree;
ExpressTreeImpl: CEDAR PROGRAM
EXPORTS ExpressTree
~ {
OPEN ExpressTree;
XTreeFromId: PUBLIC PROC [op: ATOM] RETURNS [XTree] ~ {
x: REF IdX ← NEW[IdX];
x.op ← op;
RETURN[x];
};
XTreeFromConstant: PUBLIC PROC [value: REAL] RETURNS [XTree] ~ {
x: REF ConstantX ← NEW[ConstantX];
x.value ← value;
RETURN[x];
};
ApplyUnOp: PUBLIC PROC [op: ATOM, exp1: XTree] RETURNS [XTree] ~ {
x: REF UnX ← NEW[UnX];
x.op ← op;
x.exp1 ← exp1;
RETURN[x];
};
ApplyBinOp: PUBLIC PROC [op: ATOM, exp1, exp2: XTree] RETURNS [XTree] ~ {
x: REF BinX ← NEW[BinX];
x.op ← op;
x.exp1 ← exp1;
x.exp2 ← exp2;
RETURN[x];
};
ApplyTrinOp: PUBLIC PROC [op: ATOM, exp1, exp2, exp3: XTree] RETURNS [XTree] ~ {
x: REF TrinX ← NEW[TrinX];
x.op ← op;
x.exp1 ← exp1;
x.exp2 ← exp2;
x.exp3 ← exp3;
RETURN[x];
};
ApplyFcn: PUBLIC PROC [proc: PROC ANY RETURNS ANY, args: LIST OF XTree] RETURNS [XTree] ~ {
x: REF FcnX ← NEW[FcnX];
x.proc ← proc;
x.args ← args;
RETURN[x];
};
EnumChildren: PUBLIC PROC [x: XTree, enum: EnumerateProc] RETURNS [finished: BOOLEAN, client: REF ANY] ~ TRUSTED {
WITH narrowX: x SELECT FROM
id => RETURN[TRUE, NIL];
constant => RETURN[TRUE, NIL];
unX => {
continue: BOOL;
ref: REF ANY;
[continue, ref] ← enum[narrowX.exp1];
IF ~continue THEN RETURN[FALSE, ref];
RETURN[TRUE, NIL];
};
binX => {
continue: BOOL;
ref: REF ANY;
[continue, ref] ← enum[narrowX.exp1];
IF ~continue THEN RETURN[FALSE, ref];
[continue, ref] ← enum[narrowX.exp2];
IF ~continue THEN RETURN[FALSE, ref];
RETURN[TRUE, NIL];
};
trinX => {
continue: BOOL;
ref: REF ANY;
[continue, ref] ← enum[narrowX.exp1];
IF ~continue THEN RETURN[FALSE, ref];
[continue, ref] ← enum[narrowX.exp2];
IF ~continue THEN RETURN[FALSE, ref];
[continue, ref] ← enum[narrowX.exp3];
IF ~continue THEN RETURN[FALSE, ref];
RETURN[TRUE, NIL];
};
fcn => {
continue: BOOL;
ref: REF ANY;
FOR xChild: LIST OF XTree ← narrowX.args, xChild.rest UNTIL xChild=NIL DO
[continue, ref] ← enum[xChild.first];
IF ~continue THEN RETURN[FALSE, ref];
ENDLOOP;
RETURN[TRUE, NIL];
};
ENDCASE => ERROR;
};
EnumDescendants: PUBLIC PROC [x: XTree, beforeChildren, afterChildren: EnumerateProc] RETURNS [finished: BOOLEAN, client: REF ANY] ~ {
Recurse: EnumerateProc ~ {
cont: BOOLEAN;
ref: REF ANY;
IF beforeChildren#NIL THEN {
[cont, ref] ← beforeChildren[x];
IF ~cont THEN RETURN[FALSE, ref];
};
[cont, ref] ← EnumChildren[x, Recurse];
IF ~cont THEN RETURN[FALSE, ref];
IF afterChildren#NIL THEN {
[cont, ref] ← afterChildren[x];
IF ~cont THEN RETURN[FALSE, ref];
};
else RETURN[TRUE, NIL];, which is the default
};
[finished, client] ← Recurse[x];
};
}.