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
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;
Cross Module private procedures
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];
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.
EnvironmentNode: TYPE = REF EnvironmentNodeBody;
EnvironmentNodeBody: TYPE = RECORD [
mainFileName: Rope.ROPE,
mainContextTree: ContextTreeNode,
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
];
Context Trees
Context Trees
ContextTreeNode: TYPE = REF ContextTreeNodeBody;
ContextTreeNodeBody: TYPE = RECORD [
firstSubTree: CTCell,
lastSubTree: CTCell,
rib: ContextRibNode
];
CTCell: TYPE = REF CTCellBody;
CTCellBody: TYPE = RECORD [
ctn: ContextTreeNode,
next: CTCell
];
Context Ribs
ContextRibNode: TYPE = REF ContextRibNodeBody;
ContextRibNodeBody: TYPE = RECORD [
lc: LocalContextNode
];
Local Contexts
A local context represents a particular scope (containing declarations and, perhaps, code) in a Cedar program.
LocalContextNode: TYPE = REF LocalContextNodeBody;
LocalContextNodeBody: TYPE = RECORD [
parentRib: ContextRibNode,
nestingDepthInFrame: INTTRASH, -- 0 = base context for frame, 1 = nested 1 deep, etc.
contents: LocalContextContents,
fields: FieldListNode,
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
];
Type Graph Nodes
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
];
Values
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
];
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
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
];
type must be array type
Invariants: If v: ArrayVal, then
length[v.items] = numberOfElements[v.type.body.index]
& for all e  v.items,
equivalent[valueType[e], v.type.body.itemType]
Atom
AtomTGN: TYPE = REF AtomTGNBody;
AtomTGNBody: TYPE = RECORD[];
AtomVal: TYPE = REF AtomValBody;
AtomValBody: TYPE = RECORD [
name: Rope.ROPE
];
Block
BlockTGN: TYPE = REF BlockTGNBody;
BlockTGNBody: TYPE = RECORD [
ffl: FrozenFieldListNode
];
BlockVal: TYPE = REF BlockValBody;
BlockValBody: TYPE = RECORD [
code: BD.ProgramFragmentNode
];
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 **
ConditionTGN: TYPE = REF ConditionTGNBody;
ConditionTGNBody: TYPE = RECORD[];
No ConditionVal.
Descriptor **
DescriptorTGN: TYPE = REF DescriptorTGNBody;
DescriptorTGNBody: TYPE = RECORD [
readonly: BOOLEAN,
itemType: TypeGraphNodeNode
];
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 b {x | idxdj; i, j, x  J}, where J is the set of integers, which is defined by the following relations:
FT(FIRST[T]) = i
FT(LAST[T]) = j
e  T, e ` FIRST[T]: FT(PRED[e]) = FT(e) - 1
e  T, e ` LAST[T]: FT(SUCC[e]) = FT(e) + 1
Since FT is an isomorphism, its inverse FT' exists and is also defined by the above relations. Additionally, for all element types T except signed integer base types, we require that FT(FIRST[T]) = 0.
The isomorphism FT is also called VAL; its inverse FT' is also called ORD.
The function FT defines the runtime representation of values of an element type T. The number of elements in the domain/range of FT determine the number of bits required to represent a runtime value of T.
Items
Ord: PROC [e: REF elementType static ValueNodeBody] RETURNS [BigIntegers.BigINT];
Val: PROC [v: BigIntegers.BigINT, t: REF elementType TypeGraphNodeNodeBody] RETURNS [REF elementType static ValueNodeBody];
First: PROC [t: REF elementType TypeGraphNodeNodeBody] RETURNS [REF elementType static ValueNodeBody];
Last: PROC [t: REF elementType TypeGraphNodeNodeBody] RETURNS [REF elementType static ValueNodeBody];
Pred: PROC [e: REF elementType static ValueNodeBody] RETURNS [REF elementType static ValueNodeBody];
Succ: PROC [e: REF elementType static ValueNodeBody] RETURNS [REF elementType static ValueNodeBody];
TGN and Val
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
];
Enumerated
EnumerationRepType: TYPE = CARDINAL;
According to the Mesa manual, section 3.1.1.1. This type declaration determines the maximum number of elements in an enumeration. This should really be a Saffron type, but then it would be more of a hassle to arrange the definition of EnumElementSeqBody, since we can't use a Saffron type for a Cedar index type.
THIS SHOULD BE FROZEN!!!!!!!!!!!!!
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
];
EnumElementSeq: TYPE = REF EnumElementSeqBody;
EnumElementSeqBody: TYPE = RECORD [
foo: SEQUENCE nElements: EnumerationRepType OF GEN.IdNode];
Invariants: If v: EnumeratedVal, then:
0 <= v.index < v.type.body.elements.nElements
Integer
IntegerElementType: TYPE = RECORD [
signed: BOOLEAN,
nBits: CARDINAL,   -- number of bits in rep, not counting the sign bit (if any)
nUnusedBits: CARDINAL
];
Invariants: If v: IntegerVal, then:
If v.type.body.signed
then -(2^v.type.body.nBits) <= v < 2^v.type.body.nBits
else 0 <= v < 2^v.type.body.nBits
Subrange
SubrangeElementType: TYPE = RECORD [
baseType: TypeGraphNodeNode, -- must be base element type
firstElement: ValueNode,
lastElement: ValueNode
];
Invariants: If t: SubrangeTGN, then:
IF NOT (ISTYPE[t.baseType, REF integer base elementType TypeGraphNodeNodeBody] & NARROW[t.baseType.body, REF integer base elementType TypeGraphNodeNodeBody].signed)
THEN t.firstElement >= 0
&& first[t.baseType] <= t.firstElement <= t.firstElement + t.nElements - 1 <= last[t.baseType]
Invariants: ... needs more work!! ...
Identifier
IdentifierTGN: TYPE = REF IdentifierTGNBody;
IdentifierTGNBody: TYPE = RECORD [
id: GEN.IdNode
];
Implementation
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!!!
];
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.
InterfaceTGN: TYPE = REF InterfaceTGNBody;
InterfaceTGNBody: TYPE = RECORD [
cedar: BOOLEAN,
locks: Rope.ROPE,
imports: Rope.ROPE,
shares: Rope.ROPE
];
Interface Contents
InterfaceContentsTGN: TYPE = REF InterfaceContentsTGNBody;
InterfaceContentsTGNBody: TYPE = RECORD [
ffl: FrozenFieldListNode
];
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
ListTGN: TYPE = REF ListTGNBody;
ListTGNBody: TYPE = RECORD [
readOnly: BOOLEAN,
elementType: TypeGraphNodeNode
];
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.)
LongTGN: TYPE = REF LongTGNBody;
LongTGNBody: TYPE = RECORD [
underlyingType: TypeGraphNodeNode
];
LongVal: TYPE = REF LongValBody;
LongValBody: TYPE = RECORD [
];
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.
ModuleTGN: TYPE = REF ModuleTGNBody;
ModuleTGNBody: TYPE = RECORD [
ffl: FrozenFieldListNode
];
Monitorlock
MonitorlockTGN: TYPE = REF MonitorlockTGNBody;
MonitorlockTGNBody: TYPE = RECORD [];
Monitorlocks are never static constants, so there is no "MonitorlockVal"
Named
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
];
Invariants: If v: NamedVal, then
valueType[v.value] = v.type.body.type
Opaque
OpaqueTGN: TYPE = REF OpaqueTGNBody;
OpaqueTGNBody: TYPE = RECORD [
paint: PaintNode,
optSize: ValueNode
];
OpaqueVal: TYPE = REF OpaqueValBody;
OpaqueValBody: TYPE = RECORD [
];
Pointer
PointerTGN: TYPE = REF PointerTGNBody;
PointerTGNBody: TYPE = RECORD [
ordered: BOOLEAN,
base: BOOLEAN,
readOnly: BOOLEAN,
bounds: BoundsValNode,
target: TypeGraphNodeNode
];
PointerVal: TYPE = REF PointerValBody;
PointerValBody: TYPE = RECORD [
type: REF pointer TypeGraphNodeNodeBody
];
Real
RealTGN: TYPE = REF RealTGNBody;
RealTGNBody: TYPE = RECORD [
nMantissaBits: BYTE,
nExponentBits: BYTE,
nUnusedBits: BYTE
];
RealVal: TYPE = REF RealValBody;
RealValBody: TYPE = RECORD [
value: 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
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
];
Invariants: If v: RecordVal, then:
length[v.elements] = nFields[v.type.body.fields]
&& ...
Ref
RefTGN: TYPE = REF RefTGNBody;
RefTGNBody: TYPE = RECORD [
machineDependent: BOOLEAN,
target: TypeGraphNodeNode
];
Refs are never static constants, so there is no "RefVal".
Referent
ReferentTGN: TYPE = REF ReferentTGNBody;
ReferentTGNBody: TYPE = RECORD [
contents: TypeGraphNodeNode
];
refs point to encapsulated types
ReferentVal: TYPE = REF ReferentValBody;
ReferentValBody: TYPE = RECORD [
value: StaticValueNode
];
Invariants: If v: ReferentVal, then:
valueType[v.value] = v.type.body.contents
Relative
RelativeTGN: TYPE = REF RelativeTGNBody;
RelativeTGNBody: TYPE = RECORD [
base: TypeGraphNodeNode,
pointer: TypeGraphNodeNode
];
Sequence
SequenceTGN: TYPE = REF SequenceTGNBody;
SequenceTGNBody: TYPE = RECORD [
packed: BOOLEAN,
indexId: GEN.IdNode,
indexPosition: PositionValNode,
indexAccess: AccessValNode,
tagType: TypeGraphNodeNode, -- must be element type
type: TypeGraphNodeNode
];
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)
SpecianatedTGN: TYPE = REF SpecianatedTGNBody;
SpecianatedTGNBody: TYPE = RECORD [
expParam: ValueNode,
idParam: GEN.IdNode,
underlyingType: TypeGraphNodeNode
];
String
StringTGN: TYPE = REF StringTGNBody;
StringTGNBody: TYPE = RECORD [];
Strings are never static constants, so there is no "StringVal".
Top and Bottom
TopTGN: TYPE = REF TopTGNBody;
TopTGNBody: TYPE = RECORD [];
BottomTGN: TYPE = REF BottomTGNBody;
BottomTGNBody: TYPE = RECORD [];
Transfer
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 [
definingContext: LocalContextNode,
code: BD.ProcedureGraphNode
value: StaticValueNode -- must be block type
];
Unspecified
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
];
Invariants: If v: UnspecifiedVal, then:
v.type.body.nWords = value.nWords
& for all i  [0..value.nWords) :
0 <= value[i] < 2 ^ value.type.body.wordSize
Var
VarTGN: TYPE = REF VarTGNBody;
VarTGNBody: TYPE = RECORD [
target: TypeGraphNodeNode
];
Variant Part and Union List
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,
ffl: FrozenFieldListNode,
next: UnionListCell
];
FrozenUnionList: TYPE = REF FrozenUnionListBody;
FrozenUnionListBody: TYPE = RECORD [
data: SEQUENCE nTypes: CARDINAL OF FULSlot
];
FULSlot: TYPE = RECORD [
id: GEN.IdNode,
fields: FrozenFieldListNode
ffl: FrozenFieldListNode
];
Zone
ZoneTGN: TYPE = REF ZoneTGNBody;
ZoneTGNBody: TYPE = RECORD [
uncounted: BOOLEAN
];
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
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 };
Paint nodes
PaintNode: TYPE = REF PaintNodeBody;
PaintNodeBody: TYPE = RECORD [
parentlc: LocalContextNode,
index: INT
];
Default Exp Nodes
DefaultExpCase: TYPE = { c1, c2, c3, c4, c5 };
see section 3.3.5 of Mesa manual
DefaultExpNode: TYPE = REF DefaultExpNodeBody;
DefaultExpNodeBody: TYPE = RECORD [
case: DefaultExpCase,
exp: ValueNode
exp: ExpPTreeNode
];
position val nodes
PositionValNode: TYPE = REF PositionValNodeBody;
PositionValNodeBody: TYPE = RECORD [
index: ValueNode,
bounds: BoundsValNode
];
bounds val nodes
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?
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.
AccessValNode: TYPE = REF AccessValNodeBody;
AccessValNodeBody: TYPE = AccessValSet;
AccessValSet: TYPE = { private, public, NotSureWhatItShouldBe };
{empty, noOneShouldBeChecking}
Word Sequence
WordSeq: TYPE = REF WordSeqBody;
WordSeqBody: TYPE = RECORD [ws: SEQUENCE nWords: CARDINAL OF BigCardinals.BigCARD];
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
ScopePTreeNode: TYPE = REF ScopePTreeNodeBody;
ScopePTreeNodeBody: TYPE = RECORD [
node: AT.ScopeNode
];
ModulePPTreeNode
ModulePPTreeNode: TYPE = REF ModulePPTreeNodeBody;
ModulePPTreeNodeBody: TYPE = RECORD [
node: AT.ModulePNode
];
DefBodyPTreeNode
DefBodyPTreeNode: TYPE = REF DefBodyPTreeNodeBody;
DefBodyPTreeNodeBody: TYPE = RECORD [
node: AT.DefBodyNode
];
TypeExpPTreeNode
TypeExpPTreeNode: TYPE = REF TypeExpPTreeNodeBody;
TypeExpPTreeNodeBody: TYPE = RECORD [
node: AT.TypeExpNode
];
InitializationPTreeNode
InitializationPTreeNode: TYPE = REF InitializationPTreeNodeBody;
InitializationPTreeNodeBody: TYPE = RECORD [
node: AT.InitializationNode
];
DeclarationPTreeNode
DeclarationPTreeNode: TYPE = REF DeclarationPTreeNodeBody;
DeclarationPTreeNodeBody: TYPE = RECORD [
node: AT.DeclarationNode
];
NameSequence
NameSequenceNode: TYPE = REF NameSequenceNodeBody;
NameSequenceNodeBody: TYPE = LIST OF GEN.IdNode;
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;
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
];
Dependency Analysis
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: BOOLEANTRASH, -- 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};
}.