<<>> <> <> <> <> <<>> DIRECTORY Rope USING [ROPE]; <> <> IntCodeDefs: CEDAR DEFINITIONS = BEGIN <> <<>> <> <<>> <> Align: TYPE = NAT; < don't care)>> <<>> Offset: TYPE = INT; <> <<>> Count: TYPE = INT; <> <<>> LogicalId: TYPE = INT; nullLogicalId: LogicalId = FIRST[LogicalId]; <> <<>> ByteSequence: TYPE = Rope.ROPE; nullByteSequence: ByteSequence = NIL; <> <<>> Word: TYPE = PACKED ARRAY [0..bitsPerWord) OF BOOL; bitsPerWord: NAT = 32; zerosWord: Word = LOOPHOLE[INT[0]]; onesWord: Word = LOOPHOLE[INT[-1]]; <> <> VariableId: TYPE = INT; nullVariableId: VariableId = 0; <> <> FileId: TYPE = INT; nullFileId: FileId = 0; <> <<>> <> <> <> Node: TYPE = REF NodeRep; nullNode: Node = NIL; NodeRep: TYPE = RECORD [ bits: Count ¬ 0, <> details: SELECT kind: NodeKind FROM var => [ flags: VariableFlags ¬ nullVariableFlags, -- flags for the variable id: VariableId ¬ nullVariableId, -- the unique id location: Location ¬ NIL], -- the location (NIL if not yet known) <> const => [ data: SELECT kind: ConstKind FROM word => [word: Word], <> bytes => [align: Align, bytes: ByteSequence], <> refLiteral => [litKind: RefLitKind, contents: ByteSequence], <> numLiteral => [class: ArithClass, contents: ByteSequence], <> ENDCASE], block => [nodes: NodeList], <> <> decl => [var: Var, init: Node], <> <> enable => [handle: Handler, scope: NodeList], <> assign => [lhs: Var, rhs: Node], <> cond => [cases: CaseList], <> label => [label: Label], <> goto => [dest: Label, backwards: BOOL ¬ FALSE], <> <> apply => [ proc: Node, -- designates the procedure to be applied args: NodeList ¬ NIL, -- the values to which the lambda is applied handler: Handler ¬ NIL], -- the handler to call on an error <> lambda => [ parent: Label, -- the proc parent (NIL if outer level) descBody: Var, -- the proc desc body (NIL if outer level or catch phrase) kind: LambdaKind, -- the kind of procedure bitsOut: INT, -- bits returned formalArgs: VarList, -- the formal argument values body: NodeList], -- the body that yields a value (via return nodes) <> return => [rets: NodeList], <> <> oper => [oper: Oper], <> <> machineCode => [bytes: ByteSequence], <> <> <> <> module => [vars: VarList, procs: NodeList], <> <> source => [source: SourceRange, nodes: NodeList], <> <> comment => [bytes: ByteSequence], <> <> ENDCASE]; NodeKind: TYPE = { var, const, block, decl, enable, assign, cond, label, goto, apply, lambda, return, oper, machineCode, module, source, comment}; ConstKind: TYPE = {word, bytes, refLiteral, numLiteral}; LambdaKind: TYPE = { outer, -- normal outer-level procedure inner, -- normal inner-level procedure install, -- installation procedure init, -- initialization procedure catch, -- catch procedure scope, -- enable scope procedure fork, -- fork base procedure unknown}; -- unknown kind of procedure NodeList: TYPE = REF NodeListRep; nullNodeList: NodeList = NIL; NodeListRep: TYPE = RECORD [ first: Node ¬ NIL, -- the first node in execution order rest: NodeList ¬ NIL]; -- the rest of the nodes in this block <<>> VarList: TYPE = REF VarListRep; nullVarList: VarList = NIL; VarListRep: TYPE = RECORD [first: Var, rest: VarList]; Var: TYPE = REF VarRep; nullVar: Var = NIL; VarRep: TYPE = NodeRep.var; VariableFlags: TYPE = PACKED ARRAY VariableFlag OF BOOL; nullVariableFlags: VariableFlags = ALL[FALSE]; VariableFlag: TYPE = { frequent, -- TRUE iff the var is used "frequently" used, -- TRUE iff the var is used outside of a decl constant, -- TRUE iff the var cannot change its value addressed, -- TRUE iff this var referenced by @ assigned, -- TRUE iff the var is assigned after declaration upLevel, -- TRUE iff the var is referenced up level notRegister, -- TRUE iff the var is forced into memory named -- TRUE iff the var is named }; Handler: TYPE = REF HandlerRep; HandlerRep: TYPE = RECORD [context: Node, proc: Node]; <> Label: TYPE = REF LabelRep; nullLabel: Label = NIL; LabelRep: TYPE = PACKED RECORD [ id: LogicalId, -- a unique id for the label node: Node, -- the node that defines the label backTarget: BOOL, -- TRUE if this label is the target of a backwards goto node jumpedTo: BOOL, -- TRUE if this label is used by a goto used: BOOL -- TRUE if this label is used by anything (other than a label node) ]; <> <> <> <> Location: TYPE = REF LocationRep; nullLocation: Location = NIL; LocationRep: TYPE = RECORD [ SELECT kind: LocationKind FROM system => [id: LogicalId], <> <> globalVar => [id: LogicalId], <> <> localVar => [id: LogicalId, parent: Label], <> <> register => [id: LogicalId], <> <> link => [id: LogicalId], <> <> stack => [offset: Offset], <> <> deref => [addr: Node, align: Align], <> <> <> indexed => [base: Node, index: Node], <> <> field => [base: Node, start: Offset, cross: BOOL ¬ FALSE], <> <> <> upLevel => [link: Var, reg: Var, format: LogicalId ¬ 0], <> <> composite => [parts: NodeList], <> <> escape => [id: LogicalId, base: Node, offset: Offset], <> dummy => NULL, <> ENDCASE]; LocationKind: TYPE = {system, globalVar, localVar, register, link, stack, deref, indexed, field, upLevel, composite, escape, dummy}; <<>> <> CaseList: TYPE = REF CaseListRep; nullCaseList: CaseList = NIL; CaseListRep: TYPE = RECORD [ tests: NodeList, -- NIL => ELSE or ENDCASE body: Node, -- the node to execute when the test is true rest: CaseList]; -- the rest of the cases (NIL if none) SourceRange: TYPE = RECORD [ start: Offset, -- the first character index for the range chars: Count, -- the number of characters for the range file: FileId]; -- the file where the source originated nullSourceRange: SourceRange = [0, 0, 0]; RefLitKind: TYPE = {rope, atom, refText, other}; <> Oper: TYPE = REF OperRep; nullOper: Oper = NIL; OperRep: TYPE = PACKED RECORD [ SELECT kind: OperKind FROM code => [label: Label, offset: Offset, direct: BOOL], <> <> arith => [class: ArithClass, select: ArithSelector], <> boolean => [class: BoolClass, bits: Count ¬ 1], <> convert => [to: ArithClass, from: ArithClass], <> check => [class: ArithClass, sense: Comparator], <> compare => [class: ArithClass, sense: Comparator], <> mesa => [mesa: MesaSelector, info: INT], <> cedar => [cedar: CedarSelector, info: INT], <> escape => [escape: LogicalId, info: INT], <> ENDCASE]; OperKind: TYPE = {code, arith, boolean, convert, check, compare, mesa, cedar, escape}; ArithSelector: TYPE = {add, sub, mul, div, mod, pow, abs, neg, min, max}; <> <<>> ArithClass: TYPE = PACKED RECORD [kind: ArithClassKind, checked: BOOL, precision: ArithPrecision]; <> < perform overflow checking, FALSE => no overflow checking>> <> ArithClassKind: TYPE = MACHINE DEPENDENT { signed (0), unsigned (1), address (2), real (3), <> firstExtension (4), lastExtension (15)}; <> <> ArithPrecision: TYPE = [0..256]; <> BoolClass: TYPE = {and, not, or, xor}; Comparator: TYPE = {eq, lt, le, ne, ge, gt}; MesaSelector: TYPE = { <> addr, <> all, <> equal, notEqual, <> nilck, <> alloc, <> free, <> fork, join, <> monitorEntry, monitorExit, notify, broadcast, wait, <> unnamedError, unwindError, abortedError, uncaughtError, boundsError, narrowFault, <> signal, error, unwind, resume, reject, <> copyGlobal, startGlobal, restartGlobal, stopGlobal, checkInit, <> globalFrame <> }; CedarSelector: TYPE = { <> simpleAssign, <> <> simpleAssignInit, <> <> complexAssign, <> <> complexAssignInit, <> <> new, <> <> code, <> <> narrow, <> <> referentType, <> <> procCheck <> <> <> }; <<>> <> <> ConstNode: TYPE = REF NodeRep.const; WordConstNode: TYPE = REF NodeRep.const.word; BytesConstNode: TYPE = REF NodeRep.const.bytes; RefLiteralConstNode: TYPE = REF NodeRep.const.refLiteral; BlockNode: TYPE = REF NodeRep.block; DeclNode: TYPE = REF NodeRep.decl; EnableNode: TYPE = REF NodeRep.enable; AssignNode: TYPE = REF NodeRep.assign; CondNode: TYPE = REF NodeRep.cond; LabelNode: TYPE = REF NodeRep.label; GotoNode: TYPE = REF NodeRep.goto; ApplyNode: TYPE = REF NodeRep.apply; LambdaNode: TYPE = REF NodeRep.lambda; ReturnNode: TYPE = REF NodeRep.return; OperNode: TYPE = REF NodeRep.oper; MachineCodeNode: TYPE = REF NodeRep.machineCode; ModuleNode: TYPE = REF NodeRep.module; SourceNode: TYPE = REF NodeRep.source; CommentNode: TYPE = REF NodeRep.comment; <> SystemLocation: TYPE = REF LocationRep.system; GlobalVarLocation: TYPE = REF LocationRep.globalVar; LocalVarLocation: TYPE = REF LocationRep.localVar; RegisterLocation: TYPE = REF LocationRep.register; LinkLocation: TYPE = REF LocationRep.link; StackLocation: TYPE = REF LocationRep.stack; DerefLocation: TYPE = REF LocationRep.deref; IndexedLocation: TYPE = REF LocationRep.indexed; FieldLocation: TYPE = REF LocationRep.field; UpLevelLocation: TYPE = REF LocationRep.upLevel; CompositeLocation: TYPE = REF LocationRep.composite; EscapeLocation: TYPE = REF LocationRep.escape; DummyLocation: TYPE = REF LocationRep.dummy; <> CodeOper: TYPE = REF OperRep.code; ArithOper: TYPE = REF OperRep.arith; BooleanOper: TYPE = REF OperRep.boolean; ConvertOper: TYPE = REF OperRep.convert; CheckOper: TYPE = REF OperRep.check; CompareOper: TYPE = REF OperRep.compare; MesaOper: TYPE = REF OperRep.mesa; CedarOper: TYPE = REF OperRep.cedar; EscapeOper: TYPE = REF OperRep.escape; END.