These two procedures came from InterpImpl.mesa (existing Cirio code for local d-machine world).
Tree: TYPE = PPTree.Link;
ParseCedarExpression:
PUBLIC PROC[expr: Rope.
ROPE, errout:
IO.
STREAM ←
NIL]
RETURNS[Tree] =
BEGIN
progTree: PPTree.Link;
assignment: PPTree.Link;
progTree ← Parse[Rope.Cat["Expr: PROGRAM = { x ← ", expr, "\n}."], errout];
IF progTree = NIL THEN CCTypes.CCError[syntax, NIL];
assignment ← GetFirstAssign[progTree];
IF assignment = NIL THEN CCTypes.CCError[syntax, NIL];
WITH assignment
SELECT
FROM
node:
REF PPTree.Node =>
BEGIN
kind: PPTree.NodeName ← node.name;
nsons: CARDINAL = node.sonLimit - 1;
IF kind # assign THEN CCTypes.CCError[syntax, NIL];
RETURN [node[2]];
END;
ENDCASE => CCTypes.CCError[syntax, NIL];
END;
following code copied from InterpreterImpl (via InterpImpl.mesa)
Parse:
ENTRY
PROC [program: Rope.
ROPE, errout:
IO.
STREAM]
RETURNS [root: Tree ← NIL] = TRUSTED {
NOTE: this is an ENTRY procedure to avoid scrambling the poor parser's tiny brains when multiple processes try to interpret at the same time. Don't try to get rid of this protection!
ENABLE UNWIND => NULL;
complete: BOOL;
nErrors: CARDINAL;
PPTreeOps.Initialize[];
[complete, , nErrors] ← PPP1.Parse[program, errout];
root ← IF complete AND nErrors = 0 THEN PPTreeOps.PopTree[] ELSE PPTree.Null;
PPTreeOps.Finalize[];
};
GetFirstAssign:
PROC [tree: Tree]
RETURNS [Tree] = {
returns first assignment in the tree (where "first" is first in the preorder traversal)
WITH tree
SELECT
FROM
node:
REF PPTree.Node => {
kind: PPTree.NodeName ← node.name;
nsons: CARDINAL = node.sonLimit - 1;
IF kind = assign THEN RETURN [node];
FOR i:
CARDINAL
IN [1..nsons]
DO
nt: Tree ← GetFirstAssign[node[i]];
IF nt # NIL THEN RETURN [nt]
ENDLOOP}
ENDCASE;
RETURN [NIL]
};