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: ATOM ← NIL
];
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.ROPE ← NIL
];
ICIntConst: TYPE = REF IntConstICNode;
IntConstICNode:
TYPE =
RECORD [
nodeType: ATOM ← $IntConst,
which: INT
];
Identifier.
ICId: TYPE = REF IdICNode;
IdICNode:
TYPE =
RECORD [
nodeType: ATOM ← $Id,
name: ATOM ← NIL
];
Binding between a name and a value.
ICBinding: TYPE = REF BindingICNode;
BindingICNode:
TYPE =
RECORD [
nodeType: ATOM ← $Binding,
name: ATOM ← NIL,
type: ICExp ← NIL,
value: ICExp ← NIL,
next: ICBinding ← NIL
];
Nonrecursive tuple formation.
ICMkTuple: TYPE = REF MkTupleICNode;
MkTupleICNode:
TYPE =
RECORD [
nodeType: ATOM ← $MkTuple,
localName: ATOM ← NIL,
bindings: ICBinding ← NIL
];
Recursive tuple formation.
ICMkRecTuple: TYPE = REF MkRecTupleICNode;
MkRecTupleICNode:
TYPE =
RECORD [
nodeType: ATOM ← $MkRecTuple,
localName: ATOM ← NIL,
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: ATOM ← NIL
];
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: ATOM ← NIL,
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: ATOM ← NIL,
type: ICExp ← NIL,
next: ICTyping ← NIL
];
Product (tuple) type.
ICProduct: TYPE = REF ProductICNode;
ProductICNode:
TYPE =
RECORD [
nodeType: ATOM ← $ProductType,
localName: ATOM ← NIL,
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:
BOOL ←
TRUE] ;
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.