RussellICode.mesa
Intermediate Code formats for Russell84.
Last Edited by: Demers, March 7, 1984 9:41:03 am PST.
DIRECTORY
Rope USING [ROPE],
IO USING [STREAM] ;
RussellICode: CEDAR DEFINITIONS
= BEGIN
ICode nodes.
Intermediate code representation is an abstract syntax tree with the following node formats.
ICExp: TYPE = REF ANY;
Primitive Constant.
ICPrimConst: TYPE = REF PrimConstICNode;
PrimConstICNode: TYPE = RECORD [
nodeType: ATOM ← $PrimConst,
which: ATOMNIL
];
Constant from standard prelude.
ICCharConst: TYPE = REF CharConstICNode;
CharConstICNode: TYPE = RECORD [
nodeType: ATOM ← $CharConst,
which: CHAR
];
ICStringConst: TYPE = REF StringConstICNode;
StringConstICNode: TYPE = RECORD [
nodeType: ATOM ← $StringConst,
which: Rope.ROPENIL
];
ICIntConst: TYPE = REF IntConstICNode;
IntConstICNode: TYPE = RECORD [
nodeType: ATOM ← $IntConst,
which: INT
];
Identifier.
ICId: TYPE = REF IdICNode;
IdICNode: TYPE = RECORD [
nodeType: ATOM ← $Id,
name: ATOMNIL
];
Binding between a name and a value.
ICBinding: TYPE = REF BindingICNode;
BindingICNode: TYPE = RECORD [
nodeType: ATOM ← $Binding,
name: ATOMNIL,
type: ICExp ← NIL,
value: ICExp ← NIL,
next: ICBinding ← NIL
];
Nonrecursive tuple formation.
ICMkTuple: TYPE = REF MkTupleICNode;
MkTupleICNode: TYPE = RECORD [
nodeType: ATOM ← $MkTuple,
localName: ATOMNIL,
bindings: ICBinding ← NIL
];
Recursive tuple formation.
ICMkRecTuple: TYPE = REF MkRecTupleICNode;
MkRecTupleICNode: TYPE = RECORD [
nodeType: ATOM ← $MkRecTuple,
localName: ATOMNIL,
bindings: ICBinding ← NIL
];
Tuple concatenation.
ICConcat: TYPE = REF ConcatICNode;
ConcatICNode: TYPE = RECORD [
nodeType: ATOM ← $Concat,
leftPart: ICExp ← NIL,
rightPart: ICExp ← NIL
];
Selection of a (named) component of a tuple.
ICSelect: TYPE = REF SelectICNode;
SelectICNode: TYPE = RECORD [
nodeType: ATOM ← $Select,
tuple: ICExp ← NIL,
name: ATOMNIL
];
Application of procedure/function to argument. The argument is a tuple, which is usually but not necessarily constructed explicitly at the call.
ICApply: TYPE = REF ApplyICNode;
ApplyICNode: TYPE = RECORD [
nodeType: ATOM ← $Apply,
proc: ICExp ← NIL,
arg: ICExp ← NIL
];
Guarded expressions for use in loops and conditionals.
ICGuardedExp: TYPE = REF GuardedExpICNode;
GuardedExpICNode: TYPE = RECORD [
nodeType: ATOM ← $GuardedExp,
tuple: ICExp ← NIL,
name: ATOMNIL,
result: ICExp ← NIL,
next: ICGuardedExp ← NIL
];
Conditional. A conditional expression is represented by a list of GuardedExp nodes, which are evaluated sequentially, and a special ICExp node for an else value.
ICCond: TYPE = REF CondICNode;
CondICNode: TYPE = RECORD [
nodeType: ATOM ← $Cond,
thenClauses: ICGuardedExp ← NIL,
elseExp: ICExp ← NIL
];
Loop. A loop is represented by a list of GuardedExp nodes, which are evaluated sequentially on each iteration, and a special ICExp node for an exit value.
ICLoop: TYPE = REF LoopICNode;
LoopICNode: TYPE = RECORD [
nodeType: ATOM ← $Loop,
loopClauses: ICGuardedExp ← NIL
];
Sequence of expressions/statements.
ICSeq: TYPE = REF SeqICNode;
SeqICNode: TYPE = RECORD [
nodeType: ATOM ← $Seq,
leftPart: ICExp ← NIL,
rightPart: ICExp ← NIL
];
Lambda -- procedure or function construction.
ICLambda: TYPE = REF LambdaICNode;
LambdaICNode: TYPE = RECORD [
nodeType: ATOM ← $Lambda,
param: ICTyping ← NIL,
body: ICExp ← NIL
];
Open.
ICOpen: TYPE = REF OpenICNode;
OpenICNode: TYPE = RECORD [
nodeType: ATOM ← $Open,
tuple: ICExp ← NIL,
body: ICExp ← NIL
];
Typing.
ICTyping: TYPE = REF TypingICNode;
TypingICNode: TYPE = RECORD [
nodeType: ATOM ← $Typing,
name: ATOMNIL,
type: ICExp ← NIL,
next: ICTyping ← NIL
];
Product (tuple) type.
ICProduct: TYPE = REF ProductICNode;
ProductICNode: TYPE = RECORD [
nodeType: ATOM ← $ProductType,
localName: ATOMNIL,
components: ICTyping ← NIL
];
Union (tuple) type.
ICUnion: TYPE = REF UnionICNode;
UnionICNode: TYPE = RECORD [
nodeType: ATOM ← $UnionType,
components: ICTyping ← NIL
];
Function type.
ICFunc: TYPE = REF FuncICNode;
FuncICNode: TYPE = RECORD [
nodeType: ATOM ← $FuncType,
param: ICTyping ← NIL,
resultType: ICExp ← NIL
];
Procedure type.
ICProc: TYPE = REF ProcICNode;
ProcICNode: TYPE = RECORD [
nodeType: ATOM ← $ProcType,
param: ICTyping ← NIL,
resultType: ICExp ← NIL
];
Ref (variable) type.
ICRef: TYPE = REF RefICNode;
RefICNode: TYPE = RECORD [
nodeType: ATOM ← $RefType,
referentType: ICExp ← NIL
];
Creating ICode.
The client can ignore concrete syntax by using the following procedure to parse an input stream to ICode.
ParseRussellExpression: PROCEDURE [source: IO.STREAM, errMsgProc: ErrMsgProc] RETURNS [ICExp] ;
Read and parse Russell expression from source (until source.EndOf[]). Return the resulting ICode tree.
ErrMsgProc: TYPE = PROCEDURE [errPos: INT, errMsg: Rope.ROPE, severe: BOOLTRUE] ;
Called on each syntax error with position of error in input stream and a rope containing the text of an occasionally-informative error message. The severe flag indicates that the ICExp resulting from the parse is potentially ill-formed and should not be evaluated. A parse can be aborted by generating a signal from errMsgProc which is caught by the caller of ParseRussellExpression.
END .