DIRECTORY BigCardinals USING [BigCARD], BigIntegers USING [BigINT], Rope USING [ ROPE ], SaffronATDef USING [ DeclarationNode, DefBodyNode, ExpNode, InitializationNode, ModulePNode, ScopeNode, TypeExpNode ], SaffronBaseDef USING [ProcedureGraphNode, ProgramFragmentNode, ProgramGraphNode], SaffronContext USING [ ], SaffronGenericDef USING [ IdNode ]; SaffronContextPrivateTypes: CEDAR DEFINITIONS = { OPEN AT: SaffronATDef, BD: SaffronBaseDef, GEN: SaffronGenericDef; TypeProc: TYPE = PROC [name: GEN.IdNode, access: AccessValNode, type: TypeGraphNodeNode, default: DefaultExpNode]; ConstantProc: TYPE = PROC [name: GEN.IdNode, access: AccessValNode, type: TypeGraphNodeNode, value: ValueNode]; VarProc: TYPE = PROC [name: GEN.IdNode, access: AccessValNode, type: TypeGraphNodeNode, default: DefaultExpNode]; MapOntoFields: PROC [fields: FieldListNode, typeProc: TypeProc, constantProc: ConstantProc, varProc: VarProc]; EnvironmentNode: TYPE = REF EnvironmentNodeBody; EnvironmentNodeBody: TYPE = RECORD [ firstIncludedFile: IncludedFileCell, lastIncludedFile: IncludedFileCell ]; IncludedFileCell: TYPE = REF IncludedFileCellBody; IncludedFileCellBody: TYPE = RECORD [ fileName: Rope.ROPE, next: IncludedFileCell, contextTree: ContextTreeNode, c: SELECT kind: * FROM definitions => [], implementation => [code: BD.ProgramGraphNode], ENDCASE ]; ContextTreeNode: TYPE = REF ContextTreeNodeBody; ContextTreeNodeBody: TYPE = RECORD [ firstSubTree: CTCell, lastSubTree: CTCell, rib: ContextRibNode ]; CTCell: TYPE = REF CTCellBody; CTCellBody: TYPE = RECORD [ ctn: ContextTreeNode, next: CTCell ]; ContextRibNode: TYPE = REF ContextRibNodeBody; ContextRibNodeBody: TYPE = RECORD [ lc: LocalContextNode ]; LocalContextNode: TYPE = REF LocalContextNodeBody; LocalContextNodeBody: TYPE = RECORD [ parentRib: ContextRibNode, nestingDepthInFrame: INT _ TRASH, -- 0 = base context for frame, 1 = nested 1 deep, etc. contents: LocalContextContents, maxTGNodeIndex: INT _ 0, paintIndex: INT _ 0, unpaintedPaint: PaintNode _ NIL, tgNodes: TypeGraphNodeNode _ NIL, dependencyGraph: DependencyGraphNode ]; LocalContextContents: TYPE = REF LocalContextContentsBody; LocalContextContentsBody: TYPE = RECORD [ foo: SELECT status: * FROM unfrozen => [], frozen => [block: TypeGraphNodeNode] -- must be a block tgn or module tgn ENDCASE ]; TypeGraphNodeListNode: TYPE = REF TypeGraphNodeListNodeBody; TypeGraphNodeListNodeBody: TYPE = LIST OF TypeGraphNodeNode; TypeGraphNodeNode: TYPE = REF TypeGraphNodeNodeBody; TypeGraphNodeNodeBody: TYPE = RECORD [ shown: BOOLEAN, -- used during show routines index: INT, localContext: LocalContextNode, next: TypeGraphNodeNode, -- tgNodes chain from localContext body: REF ANY ]; ValueNode: TYPE = REF ValueNodeBody; StaticValueNode: TYPE = REF static ValueNodeBody; ValueNodeBody: TYPE = RECORD [ k: SELECT kind: * FROM dummy => [info: Rope.ROPE], unparsed => [parseTree: AT.ExpNode], defaultMe => [], static => [code: BD.ProgramFragmentNode, type: TypeGraphNodeNode, body: REF ANY], trash => [code: BD.ProgramFragmentNode, type: TypeGraphNodeNode], runtime => [code: BD.ProgramFragmentNode, type: TypeGraphNodeNode], ENDCASE ]; ArrayTGN: TYPE = REF ArrayTGNBody; ArrayTGNBody: TYPE = RECORD [ packed: BOOLEAN, indexType: TypeGraphNodeNode, -- must be element type itemType: TypeGraphNodeNode ]; ArrayVal: TYPE = REF ArrayValBody; ArrayValBody: TYPE = RECORD [ indices: StaticValueNode, -- type must be type.body.indexType items: LIST OF StaticValueNode ]; AtomTGN: TYPE = REF AtomTGNBody; AtomTGNBody: TYPE = RECORD[]; AtomVal: TYPE = REF AtomValBody; AtomValBody: TYPE = RECORD [ name: Rope.ROPE ]; BlockTGN: TYPE = REF BlockTGNBody; BlockTGNBody: TYPE = RECORD [ ffl: FrozenFieldListNode ]; BlockVal: TYPE = REF BlockValBody; BlockValBody: TYPE = RECORD [ code: BD.ProgramFragmentNode ]; ConditionTGN: TYPE = REF ConditionTGNBody; ConditionTGNBody: TYPE = RECORD[]; DescriptorTGN: TYPE = REF DescriptorTGNBody; DescriptorTGNBody: TYPE = RECORD [ readonly: BOOLEAN, itemType: TypeGraphNodeNode ]; ElementTGN: TYPE = REF ElementTGNBody; ElementTGNBody: TYPE = RECORD [ v: SELECT k: * FROM base => [v1: SELECT k1: * FROM boolean => [], character => [], enumerated => [body: EnumeratedElementType], integer => [body: IntegerElementType], ENDCASE], subrange => [body: SubrangeElementType], ENDCASE ]; ElementVal: TYPE = REF ElementValBody; ElementValBody: TYPE = RECORD [ v: SELECT k: * FROM base => [v1: SELECT k1: * FROM boolean => [val: BOOLEAN], character => [val: CHARACTER], enumerated => [val: BigCardinals.BigCARD], integer => [val: BigIntegers.BigINT], ENDCASE], subrange => [val: BigCardinals.BigCARD], ENDCASE ]; EnumerationRepType: TYPE = CARDINAL; EnumeratedElementType: TYPE = RECORD [ machineDependent: BOOLEAN, paint: PaintNode, firstElement: EnumElementCell, lastElement: EnumElementCell ]; EnumElementCell: TYPE = REF EnumElementCellBody; EnumElementCellBody: TYPE = RECORD [ id: GEN.IdNode, rep: ValueNode, next: EnumElementCell ]; IntegerElementType: TYPE = RECORD [ signed: BOOLEAN, nBits: CARDINAL, -- number of bits in rep, not counting the sign bit (if any) nUnusedBits: CARDINAL ]; SubrangeElementType: TYPE = RECORD [ baseType: TypeGraphNodeNode, -- must be base element type firstElement: ValueNode, lastElement: ValueNode ]; IdentifierTGN: TYPE = REF IdentifierTGNBody; IdentifierTGNBody: TYPE = RECORD [ id: GEN.IdNode ]; ImplementationKind: TYPE = {monitor, program}; ImplementationTGN: TYPE = REF ImplementationTGNBody; ImplementationTGNBody: TYPE = RECORD [ cedar: BOOLEAN, kind: ImplementationKind, locks: Rope.ROPE, imports: Rope.ROPE, exports: Rope.ROPE, shares: Rope.ROPE, type: TypeGraphNodeNode -- this had better be a program Transfer type!!! ]; InterfaceTGN: TYPE = REF InterfaceTGNBody; InterfaceTGNBody: TYPE = RECORD [ cedar: BOOLEAN, locks: Rope.ROPE, imports: Rope.ROPE, shares: Rope.ROPE ]; InterfaceContentsTGN: TYPE = REF InterfaceContentsTGNBody; InterfaceContentsTGNBody: TYPE = RECORD [ ffl: FrozenFieldListNode ]; ListTGN: TYPE = REF ListTGNBody; ListTGNBody: TYPE = RECORD [ readOnly: BOOLEAN, elementType: TypeGraphNodeNode ]; LongTGN: TYPE = REF LongTGNBody; LongTGNBody: TYPE = RECORD [ underlyingType: TypeGraphNodeNode ]; LongVal: TYPE = REF LongValBody; LongValBody: TYPE = RECORD [ ]; ModuleTGN: TYPE = REF ModuleTGNBody; ModuleTGNBody: TYPE = RECORD [ ffl: FrozenFieldListNode ]; MonitorlockTGN: TYPE = REF MonitorlockTGNBody; MonitorlockTGNBody: TYPE = RECORD []; NamedTGN: TYPE = REF NamedTGNBody; NamedTGNBody: TYPE = RECORD [ name: GEN.IdNode, access: AccessValNode, -- access is initially Nil type: TypeGraphNodeNode, -- type is initially Nil default: DefaultExpNode, -- default is initially Nil restriction: LIST OF GEN.IdNode _ NIL ]; NamedVal: TYPE = REF NamedValBody; NamedValBody: TYPE = RECORD [ value: StaticValueNode ]; OpaqueTGN: TYPE = REF OpaqueTGNBody; OpaqueTGNBody: TYPE = RECORD [ paint: PaintNode, optSize: ValueNode ]; PointerTGN: TYPE = REF PointerTGNBody; PointerTGNBody: TYPE = RECORD [ ordered: BOOLEAN, base: BOOLEAN, readOnly: BOOLEAN, bounds: BoundsValNode, target: TypeGraphNodeNode ]; RealTGN: TYPE = REF RealTGNBody; RealTGNBody: TYPE = RECORD [ nMantissaBits: BYTE, nExponentBits: BYTE, nUnusedBits: BYTE ]; RealVal: TYPE = REF RealValBody; RealValBody: TYPE = RECORD [ value: REAL ]; RecordTGN: TYPE = REF RecordTGNBody; RecordTGNBody: TYPE = RECORD [ paint: PaintNode, machineDependent: BOOLEAN, monitoredRecord: BOOLEAN, fields: FrozenFieldListNode ]; RecordVal: TYPE = REF RecordValBody; RecordValBody: TYPE = RECORD [ elements: LIST OF StaticValueNode ]; RefTGN: TYPE = REF RefTGNBody; RefTGNBody: TYPE = RECORD [ machineDependent: BOOLEAN, target: TypeGraphNodeNode ]; ReferentTGN: TYPE = REF ReferentTGNBody; ReferentTGNBody: TYPE = RECORD [ contents: TypeGraphNodeNode ]; ReferentVal: TYPE = REF ReferentValBody; ReferentValBody: TYPE = RECORD [ value: StaticValueNode ]; RelativeTGN: TYPE = REF RelativeTGNBody; RelativeTGNBody: TYPE = RECORD [ base: TypeGraphNodeNode, pointer: TypeGraphNodeNode ]; SequenceTGN: TYPE = REF SequenceTGNBody; SequenceTGNBody: TYPE = RECORD [ packed: BOOLEAN, indexId: GEN.IdNode, indexPosition: PositionValNode, indexAccess: AccessValNode, tagType: TypeGraphNodeNode, -- must be element type type: TypeGraphNodeNode ]; SpecianatedTGN: TYPE = REF SpecianatedTGNBody; SpecianatedTGNBody: TYPE = RECORD [ expParam: ValueNode, idParam: GEN.IdNode, underlyingType: TypeGraphNodeNode ]; StringTGN: TYPE = REF StringTGNBody; StringTGNBody: TYPE = RECORD []; TopTGN: TYPE = REF TopTGNBody; TopTGNBody: TYPE = RECORD []; BottomTGN: TYPE = REF BottomTGNBody; BottomTGNBody: TYPE = RECORD []; TransferMode: TYPE = {proc, port, signal, error, process, program}; TransferTGN: TYPE = REF TransferTGNBody; TransferTGNBody: TYPE = RECORD [ safe: BOOLEAN, mode: TransferMode, arguments: FrozenFieldListNode, results: FrozenFieldListNode ]; TransferVal: TYPE = REF TransferValBody; TransferValBody: TYPE = RECORD [ code: BD.ProcedureGraphNode ]; UnspecifiedTGN: TYPE = REF UnspecifiedTGNBody; UnspecifiedTGNBody: TYPE = RECORD [ wordSize: CARDINAL, -- property of the target architecture nWords: CARDINAL ]; UnspecifiedVal: TYPE = REF UnspecifiedValBody; UnspecifiedValBody: TYPE = RECORD [ value: WordSeq ]; VarTGN: TYPE = REF VarTGNBody; VarTGNBody: TYPE = RECORD [ target: TypeGraphNodeNode ]; VariantPartTGN: TYPE = REF VariantPartTGNBody; VariantPartTGNBody: TYPE = RECORD [ flavor: VariantFlavorNode, tagType: TypeGraphNodeNode, types: FrozenUnionList ]; UnionListNode: TYPE = REF UnionListNodeBody; UnionListNodeBody: TYPE = RECORD [ nCells: CARDINAL, first: UnionListCell, last: UnionListCell ]; UnionListCell: TYPE = REF UnionListCellBody; UnionListCellBody: TYPE = RECORD [ id: GEN.IdNode, fields: FrozenFieldListNode, next: UnionListCell ]; FrozenUnionList: TYPE = REF FrozenUnionListBody; FrozenUnionListBody: TYPE = RECORD [ data: SEQUENCE nTypes: CARDINAL OF FULSlot ]; FULSlot: TYPE = RECORD [ id: GEN.IdNode, fields: FrozenFieldListNode ]; ZoneTGN: TYPE = REF ZoneTGNBody; ZoneTGNBody: TYPE = RECORD [ uncounted: BOOLEAN ]; VariantFlavorNode: TYPE = REF VariantFlavorNodeBody; VariantFlavorNodeBody: TYPE = RECORD [ SELECT flavor: VFlavor FROM overlaid => [ ], computed => [ ], vanilla => [ id: GEN.IdNode, position: PositionValNode, access: AccessValNode ], ENDCASE ]; VFlavor: TYPE = { overlaid, computed, vanilla }; PaintNode: TYPE = REF PaintNodeBody; PaintNodeBody: TYPE = RECORD [ parentlc: LocalContextNode, index: INT ]; DefaultExpCase: TYPE = { c1, c2, c3, c4, c5 }; DefaultExpNode: TYPE = REF DefaultExpNodeBody; DefaultExpNodeBody: TYPE = RECORD [ case: DefaultExpCase, exp: ValueNode ]; PositionValNode: TYPE = REF PositionValNodeBody; PositionValNodeBody: TYPE = RECORD [ index: ValueNode, bounds: BoundsValNode ]; OpenClosed: TYPE = { open, closed }; BoundsValNode: TYPE = REF BoundsValNodeBody; BoundsValNodeBody: TYPE = RECORD [ left: OpenClosed, first: ValueNode, last: ValueNode, right: OpenClosed ]; -- what about closed and open end points? AccessValNode: TYPE = REF AccessValNodeBody; AccessValNodeBody: TYPE = AccessValSet; AccessValSet: TYPE = { private, public, NotSureWhatItShouldBe }; WordSeq: TYPE = REF WordSeqBody; WordSeqBody: TYPE = RECORD [ws: SEQUENCE nWords: CARDINAL OF BigCardinals.BigCARD]; ScopePTreeNode: TYPE = REF ScopePTreeNodeBody; ScopePTreeNodeBody: TYPE = RECORD [ node: AT.ScopeNode ]; ModulePPTreeNode: TYPE = REF ModulePPTreeNodeBody; ModulePPTreeNodeBody: TYPE = RECORD [ node: AT.ModulePNode ]; DefBodyPTreeNode: TYPE = REF DefBodyPTreeNodeBody; DefBodyPTreeNodeBody: TYPE = RECORD [ node: AT.DefBodyNode ]; TypeExpPTreeNode: TYPE = REF TypeExpPTreeNodeBody; TypeExpPTreeNodeBody: TYPE = RECORD [ node: AT.TypeExpNode ]; InitializationPTreeNode: TYPE = REF InitializationPTreeNodeBody; InitializationPTreeNodeBody: TYPE = RECORD [ node: AT.InitializationNode ]; DeclarationPTreeNode: TYPE = REF DeclarationPTreeNodeBody; DeclarationPTreeNodeBody: TYPE = RECORD [ node: AT.DeclarationNode ]; NameSequenceNode: TYPE = REF NameSequenceNodeBody; NameSequenceNodeBody: TYPE = LIST OF GEN.IdNode; FrozenFieldListNode: TYPE = REF FrozenFieldListNodeBody; FrozenFieldListNodeBody: TYPE = RECORD [ shown: BOOLEAN, nSlots: INT, cells: FieldListNode ]; FieldListNode: TYPE = REF FieldListNodeBody; FieldListNodeBody: TYPE = RECORD [ frozen: BOOLEAN, any: BOOLEAN, first: FieldListCell, last: FieldListCell ]; FieldListCell: TYPE = REF FieldListCellBody; FieldListCellBody: TYPE = RECORD [ node: FieldNode, next: FieldListCell ]; FieldNode: TYPE = REF FieldNodeBody; FieldNodeBody: TYPE = RECORD [ name: GEN.IdNode, position: PositionValNode, k: SELECT kind: * FROM typeDecl => [access: AccessValNode, type: TypeGraphNodeNode, parseTree: AT.TypeExpNode], -- type must be named TGN module => [type: TypeGraphNodeNode], -- type must be named module TGN constant => [access: AccessValNode, type: TypeGraphNodeNode, initialization: InitializationPTreeNode, value: ValueNode, declaration: DeclarationPTreeNode], variable => [access: AccessValNode, type: TypeGraphNodeNode, initialization: InitializationPTreeNode, declaration: DeclarationPTreeNode], recordField => [access: AccessValNode, type: TypeGraphNodeNode, initialization: DefaultExpNode], ENDCASE ]; DependencyGraphNode: TYPE = REF DependencyGraphNodeBody; DependencyGraphNodeBody: TYPE = RECORD [ lc: LocalContextNode, -- back pointer to the relevant context roots: LIST OF DependencyGraphNodeNode ]; DependencyGraphNodeNode: TYPE = REF DependencyGraphNodeNodeBody; DependencyGraphNodeNodeBody: TYPE = RECORD [ visited: BOOLEAN _ TRASH, -- for the walker first: DependencyGraphNodeCell, last: DependencyGraphNodeCell, kind: SELECT dependencyKind: DependencyKind FROM value => [of: FieldNode], first => [of: FieldNode], last => [of: FieldNode], size => [of: FieldNode], runtime => [], ENDCASE ]; DependencyGraphNodeCell: TYPE = REF DependencyGraphNodeCellBody; DependencyGraphNodeCellBody: TYPE = RECORD [ dependsOn: DependencyGraphNodeNode, next: DependencyGraphNodeCell ]; DependencyKind: TYPE = {value, first, last, size, runtime}; }. (,SaffronContextPrivateTypes.Mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Sturgis, July 15, 1987 12:56:40 pm PDT Bill Jackson (bj) August 12, 1987 4:50:05 pm PDT James Rauen, July 16, 1988 2:33:27 pm PDT Last edited by: James Rauen August 25, 1988 4:17:24 pm PDT Cross Module private procedures GenRopeNames: PROC [rns: RopeNames, for: PROC [Rope.ROPE, REF ANY] ]; MapOntoLocalNames: PROC [vn: VisibleNames, typeProc: TypeProc, constantProc: ConstantProc, varProc: VarProc]; MapOntoAllVisibleNames: PROC [vn: VisibleNames, typeProc: TypeProc, constantProc: ConstantProc, varProc: VarProc]; GenVisibleNames: PROC [vn: VisibleNames, for: PROC [name: GEN.IdNode, access: AccessValNode, value: REF ANY] ]; Environments An Environment accumulates all the definitions files which (recursively) appear in the directory of the main file. There is a cell in the environment for each such file; this cell maps the file's name to its context tree. There is also a field in the Environment for the context tree of the main file. mainFileName: Rope.ROPE, mainContextTree: ContextTreeNode, Context Trees Context Trees Context Ribs Local Contexts A local context represents a particular scope (containing declarations and, perhaps, code) in a Cedar program. fields: FieldListNode, Type Graph Nodes Values body must be one of the ...Val's defined below. Specific Types and Values Following are the definitions of the variant parts of TypeGraphNodeNodes and ValueNodes. Note that the variant part of every ValueNode contains a field pointing to the value's type...this is necessary for implementing the valueType[] function. Array type must be array type Invariants: If v: ArrayVal, then length[v.items] = numberOfElements[v.type.body.index] & for all e B v.items, equivalent[valueType[e], v.type.body.itemType] Atom Block Since exactly one instance of each block type is created, we can use one structure (a FrozenFieldListNode) to represent both the type and the value. Condition ** No ConditionVal. Descriptor ** Help! I don't know what this is! Element Discussion Element types are defined in section 3.1 of the Mesa manual. Their properties are detailed in section 4.7 of CLRM (where they are referred to as "Discrete Types"). For each element type T, there exists an isomorphism FT: T _ {Ax | i= 0 && first[t.baseType] <= t.firstElement <= t.firstElement + t.nElements - 1 <= last[t.baseType] Invariants: ... needs more work!! ... Identifier Implementation Interface I'm not sure where the "sharedAccess" field belongs. InterfaceTGN: TYPE = RECORD [ sharedAccess: BOOLEAN -- allows access to private items ]; An interface type ("interface") is somewhat similar to a record type. This is what you get when you compile a definitions file. An InterfaceTGN is what you get when you compile a DEFINITIONS binding. Interface Contents Link used to interface between one module and another LinkTGN: TYPE = REF LinkTGNBody; LinkTGNBody: TYPE = RECORD[ tgn: TypeGraphNodeNode, -- in target module if: TypeGraphNodeNode, -- of target module - must be interface type itemName: GEN.IdNode-- name of item in interface ]; LinkVal: TYPE = REF LinkValBody; LinkValBody: TYPE = RECORD[ type: REF link TypeGraphNodeNodeBody ]; List perhaps I could use record type constructors, except they are not set up for making cyclic types directly, and perhaps there are some special semantics associated with list types Lists are never static constants, so there is no "ListVal" Long (For now we treat this as a constructor, but we could take it as a parameter during the construction of the underlying type) (In the world of 16bit words, the underlying type must be a 16bit numerical quantity, a 16bit pointer, or an (array) descriptor. LONG makes it into a 32bit quantity. In other worlds, this may be a no-op, or not, depending.) Module The field list of a ModuleTGN contains one entry for each name at the top level in a file. All of these fields are typeDecl fields. There is one for each entry in the DIRECTORY, and one for each name in the DEFINITIONS or PROGRAM or MONITOR binding. Monitorlock Monitorlocks are never static constants, so there is no "MonitorlockVal" Named Invariants: If v: NamedVal, then valueType[v.value] = v.type.body.type Opaque OpaqueVal: TYPE = REF OpaqueValBody; OpaqueValBody: TYPE = RECORD [ ]; Pointer PointerVal: TYPE = REF PointerValBody; PointerValBody: TYPE = RECORD [ type: REF pointer TypeGraphNodeNodeBody ]; Real This crock works because the size & representation of a REAL on the compiling machine is identical to that on the target machine. However, we really ought to be simulating arbitrary REAL types, similar to how we represent arbitrary integers. The size of a real is (nMantissaBits + nExponentBits + nGarbageBits + 1). Record Invariants: If v: RecordVal, then: length[v.elements] = nFields[v.type.body.fields] && ... Ref Refs are never static constants, so there is no "RefVal". Referent refs point to encapsulated types Invariants: If v: ReferentVal, then: valueType[v.value] = v.type.body.contents Relative Sequence Sequences are never static constants, so there is no "SequenceVal". Specianated (we are either : 1) specializing a sequence or array of length 0, 2) discriminating a variant, 3) selecting an interface type.) There is one syntactic case in which we can't tell which until the data structures are completely built. ("foo[red]"), so we use this more general term for now.) (Dan Swinehart selected the word Specianated, if you can't figure out what this word means, try another field.) (underlying type must be a variant style record type, a sequence style record type, an array type with empty index domain, or an interface TGN.) (In the case of a def file TGN we do the appropriate look up, as this case can be distinguished during this construction pass.) (only one of expParameter and idParam will be non nil) String Strings are never static constants, so there is no "StringVal". Top and Bottom Transfer definingContext: LocalContextNode, value: StaticValueNode -- must be block type Unspecified Invariants: If v: UnspecifiedVal, then: v.type.body.nWords = value.nWords & for all i B [0..value.nWords) : 0 <= value[i] < 2 ^ value.type.body.wordSize Var Variant Part and Union List ffl: FrozenFieldListNode, ffl: FrozenFieldListNode Zone Top and Bottom SpecialKind: TYPE = { bottom, top }; SpecialTGN: TYPE = REF SpecialTGNBody; SpecialTGNBody: TYPE = RECORD [ kind: SpecialKind ]; base and pointer must both be pointerTGNs, base must have base = true Variant Flavors Paint nodes Default Exp Nodes see section 3.3.5 of Mesa manual exp: ExpPTreeNode position val nodes bounds val nodes access val nodes A note about access val nodes: In the case "x: PUBLIC TYPE = PRIVATE INT;", there are two access val nodes. The PUBLIC one is associated with the name "x", i.e., it appears in the FieldList where x is defined. The PRIVATE one is associated with the named type graph node which x is bound to. {empty, noOneShouldBeChecking} Word Sequence ExpPTree I can't remember why these boxes are needed (ExpPTree, ScopePTree, ...). Perhaps it is a flaw in the current version of ThreeCasabaFour. ExpPTreeNode: TYPE = REF ExpPTreeNodeBody; ExpPTreeNodeBody: TYPE = RECORD [ node: AT.ExpNode ]; ScopePTree ModulePPTreeNode DefBodyPTreeNode TypeExpPTreeNode InitializationPTreeNode DeclarationPTreeNode NameSequence Field Lists FieldLists are a slightly fuzzy abstraction used to represent fields of a record type, a procedure frame type, an interface type, or a program frame type. The cells of a FieldList are ordered, and each of the names is a distinct identifier. A typeDecl cell corresponds to the type declaration: name: access TYPE = type default; A constant cell corresponds to the constant declaration: name: access type = value; A varDecl cell corresponds to the variable declaration or record field: name: access type default; Dependency Analysis Κε˜šœ™Jšœ<™