DIRECTORY
BigCardinals USING [BigFromSmall, BigSubtract, TwoToTheNth],
BigIntegers USING [BigFromBigCARD, BigFromSmall, BigINT],
FS USING[ComponentPositions, Error, ExpandName, StreamOpen],
IO USING [Close, PutFR, rope, STREAM],
Rope USING [Cat, Equal, ROPE, Substr],
SaffronAG1aDef USING[TopmodulepProdData],
SaffronATDef USING [ DeclarationNode, DefBodyNode, ExpNode, InitializationNode, ModulePNode, ScopeNode, TopNode, TypeExpNode ],
SaffronBaseDef USING [CastIntegerValue, CompilerStateNode, MakeStaticBoolean, MakeStaticCharacter, MakeTrash, ProgramFragmentNode, ProgramGraphNode],
SaffronCentralDef USING[ParseOneStream],
SaffronContext USING [],
SaffronContextPrivateTypes,
SaffronErrorHandling USING [Error, Message, FatalError, InternalError],
SaffronGenericDef USING [IdNode, IdNodeBody],
SaffronPGDef USING [AddNestedCellToPFD, AddVarsCellToPFD, EmptyPFD, MakePGLoadIndirect, MakePGLoadLocal],
SaffronProgramGraphPrivateTypes USING [ParameterizedFieldDescriptorCell, ParameterizedFieldDescriptorCellBody, ParameterizedFieldDescriptorNodeBody],
SaffronTargetArchitecture USING [TargetArchitecture],
ThreeC4Support USING[GetReportStream],
VersionMap USING[MapAndNameList, MapList, ShortNameToNames],
VersionMapDefaults USING[GetMapList];

SaffronContextCreateCTImpl: CEDAR PROGRAM
IMPORTS BigCardinals, BigIntegers, FS, IO, Rope, SaffronBaseDef, SaffronCentralDef, SaffronErrorHandling, SaffronPGDef, ThreeC4Support, VersionMap, VersionMapDefaults
EXPORTS SaffronATDef, SaffronBaseDef, SaffronContext = BEGIN
OPEN 
AT: SaffronATDef, 
BC: BigCardinals,
BD: SaffronBaseDef,
EH: SaffronErrorHandling,
GEN: SaffronGenericDef, 
PG: SaffronProgramGraphPrivateTypes,
PGD: SaffronPGDef,
PT: SaffronContextPrivateTypes, 
TA: SaffronTargetArchitecture;


ReadDefFile: PUBLIC PROC [ fname: Rope.ROPE ] RETURNS [ ModulePPTreeNode ] ~ {
actualFileName: Rope.ROPE;
data: IO.STREAM;
root: AT.TopNode;
rootData: SaffronAG1aDef.TopmodulepProdData;
reportStream: IO.STREAM _ ThreeC4Support.GetReportStream[];
[actualFileName, data] _ FindFile[fname];

IF data = NIL THEN
ERROR EH.FatalError[0, Rope.Cat["Failed to find ", actualFileName]];
SIGNAL EH.Message[Rope.Cat["Parsing from ", actualFileName]];
root _ NARROW [SaffronCentralDef.ParseOneStream[data, 0, reportStream]];
IO.Close[data];
rootData _ NARROW[root.data];
RETURN[ModulePPTreeVal[rootData.ModuleP]];
};

FindFile: PUBLIC PROC[short: Rope.ROPE, extension: Rope.ROPE _ NIL] RETURNS[fullName: Rope.ROPE, s: IO.STREAM _ NIL] =
BEGIN
fileName: Rope.ROPE;
mapList: VersionMap.MapList ~ VersionMapDefaults.GetMapList[$Symbols];
list: VersionMap.MapAndNameList;

IF ( extension = NIL ) THEN extension _ "Mesa";
fileName _ Rope.Cat[short, ".", extension];
IF ( (s _ FS.StreamOpen[fileName ! FS.Error => CONTINUE]) # NIL ) THEN RETURN[fileName, s];
list _ VersionMap.ShortNameToNames[mapList, Rope.Cat[short, ".", "BCD"]];
FOR p: VersionMap.MapAndNameList _ list, p.rest UNTIL p=NIL DO
remoteFileName: Rope.ROPE ~ p.first.name;
cp: FS.ComponentPositions;
package: Rope.ROPE;
src: Rope.ROPE;
fullFName: Rope.ROPE;
[fullFName, cp] _ FS.ExpandName[remoteFileName];
package _ Rope.Substr[fullFName, 0, cp.ext.start];
src _ Rope.Cat[package, extension];
IF ( (s _ FS.StreamOpen[src ! FS.Error => LOOP]) # NIL ) THEN RETURN[src, s];
ENDLOOP;
END;




EnvironmentNode: TYPE ~ REF EnvironmentNodeBody;
EnvironmentNodeBody: PUBLIC TYPE ~ PT.EnvironmentNodeBody;

IncludedFileCell: TYPE ~ REF IncludedFileCellBody;
IncludedFileCellBody: PUBLIC TYPE ~ PT.IncludedFileCellBody;

CreateEmptyEnvironment: PUBLIC PROC RETURNS [EnvironmentNode] ~ {
env: EnvironmentNode _ NEW[EnvironmentNodeBody _ [NIL, NIL]];
RETURN[env];
};

AddCompiledDefinitionsFileToEnvironment: PUBLIC PROC [env: EnvironmentNode, fileName: Rope.ROPE, ct: ContextTreeNode] RETURNS [EnvironmentNode] ~ {
includedFileCell: IncludedFileCell _ NEW[IncludedFileCellBody _ 
[fileName, NIL, ct, definitions[]]];
IF env.firstIncludedFile = NIL 
THEN env.firstIncludedFile _ includedFileCell
ELSE env.lastIncludedFile.next _ includedFileCell;
env.lastIncludedFile _ includedFileCell;
RETURN[env];
};

AddCompiledImplementationFileToEnvironment: PUBLIC PROC [env: EnvironmentNode, fileName: Rope.ROPE, ct: ContextTreeNode, pg: BD.ProgramGraphNode] RETURNS [EnvironmentNode] ~ {
includedFileCell: IncludedFileCell _ NEW[IncludedFileCellBody _ 
[fileName, NIL, ct, implementation[pg]]];
IF env.firstIncludedFile = NIL 
THEN env.firstIncludedFile _ includedFileCell
ELSE env.lastIncludedFile.next _ includedFileCell;
env.lastIncludedFile _ includedFileCell;
RETURN[env];
};

LookupCompiledFileInEnv: PUBLIC PROC [env: EnvironmentNode, fileName: Rope.ROPE]
RETURNS [ContextTreeNode] ~ {
includedFileCell: IncludedFileCell _ env.firstIncludedFile;
WHILE includedFileCell # NIL DO
IF Rope.Equal[includedFileCell.fileName, fileName]
THEN RETURN [includedFileCell.contextTree]
ELSE includedFileCell _ includedFileCell.next;
ENDLOOP;
RETURN[NIL];
};

LookupInterfaceInEnv: PUBLIC PROC [env: EnvironmentNode, fileName: Rope.ROPE, interfaceName: GEN.IdNode] RETURNS [TypeGraphNodeNode] = BEGIN
contextTree: ContextTreeNode _ LookupCompiledFileInEnv[env, fileName];
IF contextTree = NIL THEN ERROR EH.InternalError["Interface not found in environment"];
RETURN[FieldType[LookupNameInContextRib[interfaceName, contextTree.rib]]];
END;


IsCompiledFileInEnv: PUBLIC PROC [env: EnvironmentNode, fileName: Rope.ROPE] RETURNS [BOOLEAN] ~ {
RETURN[LookupCompiledFileInEnv[env, fileName] # NIL];
};

FakeDamageEnvironment: PUBLIC PROC [env: EnvironmentNode] RETURNS [EnvironmentNode] = {RETURN[env]};


InterfaceTGN: TYPE = REF InterfaceTGNBody;
InterfaceTGNBody: PUBLIC TYPE = PT.InterfaceTGNBody;








ContextTreeNode: TYPE ~ REF ContextTreeNodeBody;
ContextTreeNodeBody: PUBLIC TYPE ~ PT.ContextTreeNodeBody;

CTCell: TYPE = REF CTCellBody;
CTCellBody: PUBLIC TYPE = PT.CTCellBody;



EmptyContextTree: PUBLIC PROC [ rib: ContextRibNode ] RETURNS [ ContextTreeNode ] ~ { RETURN[NEW [ContextTreeNodeBody _ [NIL, NIL, rib]]] };

FakeDamageContextTree: PUBLIC PROC [ ctn: ContextTreeNode ] RETURNS [ ctnp: ContextTreeNode ] ~ { RETURN[ctn] };

AddSubContextTree: PUBLIC PROC [ ctn: ContextTreeNode, subCtn: ContextTreeNode ] RETURNS [ ctnp: ContextTreeNode ] ~ {
cell: CTCell _ NEW [CTCellBody_[subCtn, NIL]];
IF subCtn.rib.lc.parentRib # ctn.rib THEN 
ERROR EH.InternalError["Parent rib of child context tree is not rib of parent context tree."];
IF ctn.firstSubTree = NIL THEN ctn.firstSubTree _ cell ELSE ctn.lastSubTree.next _ cell;
ctn.lastSubTree _ cell;
RETURN[ctn];
};

Rib: PUBLIC PROC [ctn: ContextTreeNode] RETURNS [ContextRibNode] = {
RETURN [ctn.rib];
};
ContextRibNode: TYPE ~ REF ContextRibNodeBody;
ContextRibNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.ContextRibNodeBody;

CompilerStateNode: TYPE ~ BD.CompilerStateNode;

FreezeLocalContext: PUBLIC PROC [ lc: LocalContextNode, contents: TypeGraphNodeNode ] RETURNS [ rib: ContextRibNode ] ~ {
lc.contents _ NEW[PT.LocalContextContentsBody _ [frozen[contents]]];
RETURN[NEW [ContextRibNodeBody _ [lc]]];
};
LocalContextNode: TYPE ~ REF LocalContextNodeBody;
LocalContextNodeBody: PUBLIC TYPE ~ PT.LocalContextNodeBody;

LocalContextContents: TYPE = REF LocalContextContentsBody;
LocalContextContentsBody: TYPE = PT.LocalContextContentsBody;

CreateEmptyContext: PUBLIC PROC [parentRib: ContextRibNode, newFrame: BOOLEAN]
RETURNS [ LocalContextNode ] ~ {
lc: LocalContextNode _ NEW [LocalContextNodeBody _ [
parentRib: parentRib,
nestingDepthInFrame: 
IF (parentRib = NIL) OR newFrame 
THEN 0 
ELSE parentRib.lc.nestingDepthInFrame + 1,
contents: NEW[PT.LocalContextContentsBody _ [unfrozen[]]]
]];
lc.unpaintedPaint _ IF parentRib = NIL 
THEN CreateUnpaintedPaint[lc] 
ELSE parentRib.lc.unpaintedPaint;
RETURN[lc];
};

ParentRib: PUBLIC PROC [lc: LocalContextNode] RETURNS [ContextRibNode] = BEGIN
RETURN [lc.parentRib];
END;

FakeDamageContext: PUBLIC PROC [lc: LocalContextNode] RETURNS [lcp: LocalContextNode] ~ {lcp _ lc};

CreateRootContextRib: PUBLIC PROC [ta: TA.TargetArchitecture] RETURNS [rootContextRib: ContextRibNode, top, bottom: TypeGraphNodeNode] = BEGIN

ws: BYTE _ ta.wordSize;
is: BYTE _ ta.integerSize;
lis: BYTE _ ta.longIntegerSize;

lc: LocalContextNode _ CreateEmptyContext[NIL, TRUE];

fl: FieldListNode _ CreateEmptyFieldList[];

AddBaseType[lc,fl, "ATOM", 	NEW[PT.AtomTGNBody]];
AddBaseType[lc,fl, "BOOL", 	NEW[PT.ElementTGNBody _ [base[boolean[]]]]];
AddBaseType[lc,fl, "BOOLEAN",	NEW[PT.ElementTGNBody _ [base[boolean[]]]]];
AddBaseType[lc,fl, "CHAR", 	NEW[PT.ElementTGNBody _ [base[character[]]]]];
AddBaseType[lc,fl, "CHARACTER",	NEW[PT.ElementTGNBody _ [base[character[]]]]];
AddBaseType[lc,fl, "CONDITION", 	NEW[PT.ConditionTGNBody]];
AddBaseType[lc,fl, "MONITORLOCK", 	NEW[PT.MonitorlockTGNBody]];
AddBaseType[lc,fl, "STRING", 	NEW[PT.StringTGNBody]];
AddBaseType[lc,fl, "REAL",	NEW[PT.RealTGNBody _ [5, 8, 20]]];

AddIntegerBaseType[lc, fl, "CARDINAL",	FALSE,	lis,	0]; 
AddIntegerBaseType[lc, fl, "CARD16",		FALSE,	16,	0]; 
AddIntegerBaseType[lc, fl, "CARD32",		FALSE,	32,	0]; 
AddIntegerBaseType[lc, fl, "CARD64",		FALSE,	64,	0]; 

AddIntegerBaseType[lc, fl, "NAT",		FALSE,	is-1,	1]; 
AddIntegerBaseType[lc, fl, "NATURAL",	FALSE,	is-1,	1]; 
AddIntegerBaseType[lc, fl, "NAT15",		FALSE,	15,	1]; 
AddIntegerBaseType[lc, fl, "NAT31",		FALSE,	31,	1]; 
AddIntegerBaseType[lc, fl, "NAT63",		FALSE,	63,	1]; 

AddIntegerBaseType[lc, fl, "INT",		TRUE,	lis-1,	0]; 
AddIntegerBaseType[lc, fl, "INTEGER",	TRUE,	is-1,	0]; 
AddIntegerBaseType[lc, fl, "INT16",		TRUE,	15,	0]; 
AddIntegerBaseType[lc, fl, "INT32",		TRUE,	31,	0]; 
AddIntegerBaseType[lc, fl, "INT64",		TRUE,	63,	0]; 

AddIntegerBaseType[lc, fl, "BIT",		FALSE,	1,	0]; 
AddIntegerBaseType[lc, fl, "BYTE",		FALSE,	8,	0]; 
AddIntegerBaseType[lc, fl, "WORD",		FALSE,	ws,	0]; 

BEGIN
ffl: FrozenFieldListNode _ FreezeFieldList[fl];
block: TypeGraphNodeNode _ CreateBlockTGN[lc, ffl].tgn;
[lc, top] _ CreateTopTGN[lc];
[lc, bottom] _ CreateBottomTGN[lc];
rootContextRib _ FreezeLocalContext[lc, block];
END;

END;

AddBaseType: PROC [lc: LocalContextNode, fl: FieldListNode, name: Rope.ROPE, body: REF ANY] = BEGIN
nameAsIdNode: GEN.IdNode _ NEW [GEN.IdNodeBody _ [name, 0, 0]];
position: PositionValNode _ NIL;
access: AccessValNode _ AccessValConst["public"];
tgn: TypeGraphNodeNode _ CreateTGN[lc, body];
namedTGN: TypeGraphNodeNode _ CreateTGN[lc, NEW[PT.NamedTGNBody _ [
name: nameAsIdNode,
access: AccessValConst["public"],
type: tgn,
default: NIL 		-- is this right?
]]];
field: FieldNode _ CreateNamedTypeField[nameAsIdNode, position, access, namedTGN, NIL];
[] _ AppendFieldToFieldList[fl, field];
END;

AddIntegerBaseType: PROC [lc: LocalContextNode, fl: FieldListNode, name: Rope.ROPE, signed: BOOLEAN, nBits: CARDINAL, nUnusedBits: CARDINAL] = BEGIN
body: PT.ElementTGN _ NEW[PT.ElementTGNBody _ 
[base[integer[[signed, nBits, nUnusedBits]]]]];
AddBaseType[lc, fl, name, body];
END;



TypeGraphNodeListNode: TYPE ~ REF TypeGraphNodeListNodeBody;
TypeGraphNodeListNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.TypeGraphNodeListNodeBody;

TypeGraphNodeNode: TYPE ~ REF TypeGraphNodeNodeBody;
TypeGraphNodeNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.TypeGraphNodeNodeBody;

CreateTGN: PROC [ lc: LocalContextNode, body: REF ANY ]
RETURNS [ tgn: TypeGraphNodeNode ] ~ {
tgn _ NEW [TypeGraphNodeNodeBody _ [
shown: FALSE,
index: lc.maxTGNodeIndex + 1,
localContext: lc,
body: body,
next: lc.tgNodes]];
lc.maxTGNodeIndex _ tgn.index;
lc.tgNodes _ tgn;
};

FakeDamageTypeGraphNode: PUBLIC PROC [tgn: TypeGraphNodeNode] RETURNS [TypeGraphNodeNode] = BEGIN
RETURN [tgn];
END;



ValueNode: TYPE = REF ValueNodeBody;
ValueNodeBody: PUBLIC TYPE = PT.ValueNodeBody;

MakeUnparsedValue: PUBLIC PROC [ node: AT.ExpNode ] RETURNS [ ValueNode ] ~ {
RETURN[NEW [ValueNodeBody _ [unparsed[node]]]];
};

MakeUnparsedNullValue: PUBLIC PROC RETURNS [ ValueNode ] = BEGIN
RETURN [NEW[ValueNodeBody _ [unparsed[NIL]]]];
END;

MakeDummy: PUBLIC PROC [r: Rope.ROPE] RETURNS [ValueNode] = BEGIN
RETURN [NEW[ValueNodeBody _ [dummy[r]]]];
END;

CreateArrayTGN: PUBLIC PROC [ lc: LocalContextNode, packed: BOOLEAN, indexType: TypeGraphNodeNode, itemType: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.ArrayTGN _ NEW [PT.ArrayTGNBody _ [packed, indexType, itemType]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateBlockTGN: PUBLIC PROC [ lc: LocalContextNode, contents: FrozenFieldListNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.BlockTGN _ NEW [PT.BlockTGNBody _ [contents]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateBottomTGN: PRIVATE PROC [lc: LocalContextNode] RETURNS [lcp: LocalContextNode, tgn: TypeGraphNodeNode] ~ {
body: PT.BottomTGN _ NEW [PT.BottomTGNBody];
RETURN[lc, CreateTGN[lc, body]];
};
CreateDescriptorTGN: PUBLIC PROC [ lc: LocalContextNode, readonly: BOOLEAN, itemType: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.DescriptorTGN _ NEW [PT.DescriptorTGNBody _ [readonly, itemType]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateSubrangeTGN: PUBLIC PROC [ lc: LocalContextNode, subrangeOf: TypeGraphNodeNode, bounds: BoundsValNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] = BEGIN
body: PT.ElementTGN _ NEW [PT.ElementTGNBody _ [subrange[[subrangeOf, bounds.first, bounds.last]]]];
RETURN[lc, CreateTGN[lc, body]];
END;

CreateEmptyEnumTypeTGN: PUBLIC PROC [ lc: LocalContextNode, machineDependent: BOOLEAN ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.ElementTGN _ NEW [PT.ElementTGNBody _ 
[base[enumerated[[machineDependent, GetUniquePaint[lc].p, NIL, NIL]]]]];
RETURN[lc, CreateTGN[lc, body]];
};

AppendElementToEnumTypeTGN: PUBLIC PROC [ lc: LocalContextNode, tgn: TypeGraphNodeNode, elementName: GEN.IdNode, rep: ValueNode ] RETURNS [ lcp: LocalContextNode ] ~ {
body: REF enumerated base PT.ElementTGNBody _ NARROW[tgn.body];
cell: PT.EnumElementCell _ NEW [PT.EnumElementCellBody _ [elementName, rep, NIL]];
IF body.body.lastElement = NIL
THEN body.body.firstElement _ cell
ELSE body.body.lastElement.next _ cell;
body.body.lastElement _ cell;
RETURN[lc];
};

First: PUBLIC PROC [tgn: TypeGraphNodeNode] RETURNS [ValueNode] = BEGIN
WHILE ISTYPE[tgn.body, PT.NamedTGN] DO
tgn _ NARROW[tgn.body, PT.NamedTGN].type;
ENDLOOP;
WITH tgn.body SELECT FROM
e: REF subrange PT.ElementTGNBody =>
RETURN [e.body.firstElement];
e: REF boolean base PT.ElementTGNBody =>
RETURN [BD.MakeStaticBoolean[FALSE, tgn]];
e: REF character base PT.ElementTGNBody => 
RETURN [BD.MakeStaticCharacter[0C, tgn]];
e: REF enumerated base PT.ElementTGNBody =>
ERROR EH.InternalError["FIRST[enumerated type] not implemented"];
e: REF integer base PT.ElementTGNBody => {
typeList: TypeGraphNodeListNode _ NEW[TypeGraphNodeListNodeBody _ LIST[tgn]];
val: BigIntegers.BigINT _ IF e.body.signed
THEN BigIntegers.BigFromBigCARD[BC.TwoToTheNth[e.body.nBits], minus]
ELSE BigIntegers.BigFromSmall[0];
RETURN[BD.CastIntegerValue[val, typeList]];
};
ENDCASE => {
SIGNAL EH.Error[0, "Bad type passed to FIRST"];
RETURN [BD.MakeTrash[tgn]];
};
END;

Last: PUBLIC PROC [tgn: TypeGraphNodeNode] RETURNS [ValueNode] = BEGIN
WHILE ISTYPE[tgn.body, PT.NamedTGN] DO
tgn _ NARROW[tgn.body, PT.NamedTGN].type;
ENDLOOP;
WITH tgn.body SELECT FROM
e: REF subrange PT.ElementTGNBody =>
RETURN [e.body.lastElement];
e: REF boolean base PT.ElementTGNBody =>
RETURN [BD.MakeStaticBoolean[TRUE, tgn]];
e: REF character base PT.ElementTGNBody =>
RETURN [BD.MakeStaticCharacter[377C, tgn]];
e: REF enumerated base PT.ElementTGNBody =>
ERROR EH.InternalError["LAST[enumerated type] not implemented"];
e: REF integer base PT.ElementTGNBody => {
typeList: TypeGraphNodeListNode _ NEW[TypeGraphNodeListNodeBody _ LIST[tgn]];
val: BigIntegers.BigINT _ BigIntegers.BigFromBigCARD[
BC.BigSubtract[
BC.TwoToTheNth[e.body.nBits], 
BC.BigFromSmall[1]],
plus];
RETURN[BD.CastIntegerValue[val, typeList]];
};
ENDCASE => {
SIGNAL EH.Error[0, "Bad type passed to LAST"];
RETURN [BD.MakeTrash[tgn]];
};
END;


FindFrameTGN: PUBLIC PROC [ lc: LocalContextNode, id: GEN.IdNode ]
RETURNS [ tgn: TypeGraphNodeNode ] = BEGIN
ERROR EH.InternalError ["FindFrameTGN not implemented"];
END;

CreateIdentifierTGN: PUBLIC PROC [ lc: LocalContextNode, id: GEN.IdNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.IdentifierTGN _ NEW [PT.IdentifierTGNBody _ [id]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateImplementationTGN: PUBLIC PROC [ lc: LocalContextNode, cedar: BOOLEAN, transferType: TypeGraphNodeNode, locks, imports, exports, shares: Rope.ROPE ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.ImplementationTGN _ NEW [PT.ImplementationTGNBody _ 
[cedar, program, locks, imports, exports, shares, transferType]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateInterfaceTGN: PUBLIC PROC [ lc: LocalContextNode, cedar: BOOLEAN, locks, imports, shares: Rope.ROPE ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.InterfaceTGN _ NEW [PT.InterfaceTGNBody _ 
[cedar, locks, imports, shares]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateInterfaceContentsTGN: PUBLIC PROC [ lc: LocalContextNode, contents: FrozenFieldListNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.InterfaceContentsTGN _ NEW [PT.InterfaceContentsTGNBody _ [contents]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateListTGN: PUBLIC PROC [ lc: LocalContextNode, readOnly: BOOLEAN, itemType: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.ListTGN _ NEW [PT.ListTGNBody _ [readOnly, itemType]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateLongTGN: PUBLIC PROC [ lc: LocalContextNode,
underlyingType: TypeGraphNodeNode ]
RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.LongTGN _ NEW [PT.LongTGNBody _ [underlyingType]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateModuleTGN: PUBLIC PROC [lc: LocalContextNode, contents: FrozenFieldListNode] RETURNS [LocalContextNode, TypeGraphNodeNode] = BEGIN
body: PT.ModuleTGN _ NEW [PT.ModuleTGNBody _ [contents]];
RETURN[lc, CreateTGN[lc, body]];
END;

CreateNamedTGN: PUBLIC PROC [lc: LocalContextNode, name: GEN.IdNode, position: PositionValNode, access: AccessValNode, type: TypeGraphNodeNode, default: DefaultExpNode] RETURNS [LocalContextNode, TypeGraphNodeNode] = BEGIN
body: PT.NamedTGN _ NEW[PT.NamedTGNBody _ [name, access, type, default]];
tgn: TypeGraphNodeNode _ CreateTGN[lc, body];
RETURN[lc, tgn];
END;


AddIdToRestrictionList: PUBLIC PROC [id: GEN.IdNode, tgn: TypeGraphNodeNode] RETURNS [TypeGraphNodeNode] = BEGIN
namedTGN: PT.NamedTGN _ NARROW[tgn.body];
namedTGN.restriction _ CONS [id, namedTGN.restriction];
RETURN [tgn];
END;

AddAllIdsToRestrictionList: PUBLIC PROC [tgn: TypeGraphNodeNode] RETURNS [TypeGraphNodeNode] = BEGIN
interface: PT.InterfaceTGN _ NARROW[NARROW[tgn.body, PT.NamedTGN].type.body];
RETURN[tgn];
END;


BogusTypeExpPTree: PUBLIC PROC RETURNS [TypeExpPTreeNode] = BEGIN
RETURN [NIL];
END;
CreatePointerTGN: PUBLIC PROC [ lc: LocalContextNode, ordered, base: BOOLEAN, bounds: BoundsValNode, readOnly: BOOLEAN, targetTgn: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.PointerTGN _ NEW [PT.PointerTGNBody _ [ordered, base, readOnly, bounds, targetTgn]];
RETURN[lc, CreateTGN[lc, body]];
};


CreateRecordTGN: PUBLIC PROC [ lc: LocalContextNode, paint: PaintNode, machineDependent, monitoredRecord: BOOLEAN, ffl: FrozenFieldListNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.RecordTGN _ NEW [PT.RecordTGNBody _ [
paint, machineDependent, monitoredRecord, ffl]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateRefTGN: PUBLIC PROC [ lc: LocalContextNode, machineDependent: BOOLEAN, contentsTgn: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
referent: PT.ReferentTGN _ NEW [PT.ReferentTGNBody _ [contentsTgn]];
body: PT.RefTGN _ NEW [PT.RefTGNBody _ [machineDependent, CreateTGN[lc, referent]]];
RETURN[lc, CreateTGN[lc, body]];
};

CreateRelativeTGN: PUBLIC PROC [ lc: LocalContextNode, base, pointer: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.RelativeTGN _ NEW [PT.RelativeTGNBody _ [base, pointer]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateSpecianatedTGNUsingId: PUBLIC PROC [ lc: LocalContextNode, underlyingType: TypeGraphNodeNode, id: GEN.IdNode ] RETURNS [ lcp: LocalContextNode,
tgn: TypeGraphNodeNode ] ~ {
body: PT.SpecianatedTGN _ NEW [PT.SpecianatedTGNBody _ [NIL, id, underlyingType]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateSpecianatedTGNUsingExp: PUBLIC PROC [ lc: LocalContextNode, underlyingType: TypeGraphNodeNode, parameter: ValueNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.SpecianatedTGN _ NEW [PT.SpecianatedTGNBody _ [parameter, NIL, underlyingType]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateTransferTGN: PUBLIC PROC [ lc: LocalContextNode, safe: BOOLEAN, modeName: Rope.ROPE, arguments, results: FrozenFieldListNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
mode: PT.TransferMode _ SELECT TRUE FROM
Rope.Equal["proc", modeName] => proc,
Rope.Equal["port", modeName] => port,
Rope.Equal["signal", modeName] => signal,
Rope.Equal["error", modeName] => error,
Rope.Equal["process", modeName] => process,
Rope.Equal["program", modeName] => program,
ENDCASE => ERROR;
body: PT.TransferTGN _ NEW [PT.TransferTGNBody _ [safe, mode, arguments, results]];
RETURN[lc, CreateTGN[lc, body]];
};
CreateTopTGN: PRIVATE PROC [lc: LocalContextNode] RETURNS [lcp: LocalContextNode, tgn: TypeGraphNodeNode] ~ {
body: PT.TopTGN _ NEW [PT.TopTGNBody];
RETURN[lc, CreateTGN[lc, body]];
};
CreateVarTGN: PUBLIC PROC [ lc: LocalContextNode, targetTgn: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.VarTGN _ NEW [PT.VarTGNBody _ [targetTgn]];
RETURN[lc, CreateTGN[lc, body]];
};
UnionListNode: TYPE ~ REF UnionListNodeBody;
UnionListNodeBody: PUBLIC TYPE ~ PT.UnionListNodeBody;

CreateVariantPartTGN: PUBLIC PROC [ lc: LocalContextNode, flavor: VariantFlavorNode, tagType: TypeGraphNodeNode, types: UnionListNode ]
RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.VariantPartTGN _ NEW [PT.VariantPartTGNBody _ [
flavor,
tagType,
FreezeUnionList[types]]];
RETURN[lc, CreateTGN[lc, body]];
};

IsVariantPartTGN: PROC [ tgn: TypeGraphNodeNode ] RETURNS [ BOOLEAN ] ~ {
WITH tgn.body SELECT FROM
vptgn: PT.VariantPartTGN => RETURN[TRUE];
ENDCASE => RETURN[FALSE];
};

GetVariantPartUnionList: PROC [ tgn: TypeGraphNodeNode ]
RETURNS [PT.FrozenUnionList] ~ {
WITH tgn.body SELECT FROM
vptgn: PT.VariantPartTGN => RETURN[vptgn.types];
ENDCASE => ERROR;
};

CreateEmptyUnionList: PUBLIC PROC RETURNS [ UnionListNode ] ~ {
RETURN[NEW [UnionListNodeBody _ [0, NIL, NIL]]];
};

AppendToUnionList: PUBLIC PROC [ ul: UnionListNode, id: GEN.IdNode,
ffl: FrozenFieldListNode ] RETURNS [ ulnp: UnionListNode ] ~ {
newCell: PT.UnionListCell _ NEW [PT.UnionListCellBody _ [id, ffl, NIL]];
IF ( ul.first = NIL ) THEN ul.first _ newCell ELSE ul.last.next _ newCell;
ul.last _ newCell;
ul.nCells _ ul.nCells+1;
RETURN[ul];
};

FreezeUnionList: PROC[ ul: UnionListNode ] RETURNS [PT.FrozenUnionList] ~ {
ful: PT.FrozenUnionList _ NEW [PT.FrozenUnionListBody[ul.nCells]];
cell: PT.UnionListCell _ ul.first;
FOR i: CARDINAL IN [0..ful.nTypes) DO
ful[i] _ [cell.id, cell.fields];
cell _ cell.next;
ENDLOOP;
RETURN[ful]
};
CreateZoneTGN: PUBLIC PROC [ lc: LocalContextNode, uncounted: BOOLEAN ]
RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: PT.ZoneTGN _ NEW [PT.ZoneTGNBody _ [uncounted]];
RETURN[lc, CreateTGN[lc, body]];
};


ResolveNamedNodes: PROC[tgn: TypeGraphNodeNode] RETURNS[TypeGraphNodeNode] =
BEGIN
x: TypeGraphNodeNode _ tgn;
WHILE TRUE DO
WITH x.body SELECT FROM
namedNode: PT.NamedTGN => x _ namedNode.type;
ENDCASE => RETURN[x];
ENDLOOP;
ERROR;
END;
VariantFlavorNode: TYPE ~ REF VariantFlavorNodeBody;
VariantFlavorNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.VariantFlavorNodeBody;

OverlaidVariantFlavorConst: PUBLIC PROC RETURNS [ VariantFlavorNode ] ~ { RETURN[NEW [overlaid VariantFlavorNodeBody _ [overlaid[]]]] };

ComputedVariantFlavorConst: PUBLIC PROC RETURNS [ VariantFlavorNode ] ~ { RETURN[NEW [computed VariantFlavorNodeBody _ [computed[]]]] };

VanillaVariantFlavorVal: PUBLIC PROC [ id: GEN.IdNode, position: PositionValNode, access: AccessValNode ] RETURNS [ VariantFlavorNode ] ~ { RETURN[NEW [vanilla VariantFlavorNodeBody _ [vanilla[id, position, access]]]] };
SequenceTGN: TYPE ~ REF SequenceTGNBody;
SequenceTGNBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.SequenceTGNBody;

CreateSequenceTGN: PUBLIC PROC [ lc: LocalContextNode, packed: BOOLEAN, id: GEN.IdNode, position: PositionValNode, access: AccessValNode, tagType: TypeGraphNodeNode,
type: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode,
tgn: TypeGraphNodeNode ] ~ {
body: SequenceTGN _ NEW [SequenceTGNBody _ [packed, id, position, access, tagType, type]];
RETURN[lc, CreateTGN[lc, body]];
};






RenameInterface: PUBLIC PROC [lc: LocalContextNode, name: GEN.IdNode, interface: TypeGraphNodeNode] RETURNS [lcp: LocalContextNode] ~ {RETURN[lc]};
OpenInterface: PUBLIC PROC [ lc: LocalContextNode, interfaceTGN: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode ] ~ {RETURN[lc]};

OpaqueTGN: TYPE = REF OpaqueTGNBody;
OpaqueTGNBody: PUBLIC TYPE = SaffronContextPrivateTypes.OpaqueTGNBody;

CreateOpaqueTGN: PUBLIC PROC[lc: LocalContextNode, paint: PaintNode, optSize: ValueNode] RETURNS[lcp: LocalContextNode, tgn: TypeGraphNodeNode ] =
BEGIN
body: OpaqueTGN _ NEW[OpaqueTGNBody_[paint, optSize]];
RETURN[lc, CreateTGN[lc, body]];
END; 
PaintNode: TYPE ~ REF PaintNodeBody;
PaintNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.PaintNodeBody;

CreateUnpaintedPaint: PROC [ lc: LocalContextNode ] RETURNS [ PaintNode ] ~ { RETURN[NEW [PaintNodeBody _ [lc, 0]]] };

GetUnpaintedPaint: PUBLIC PROC [ lc: LocalContextNode ] RETURNS [ lcp: LocalContextNode, p: PaintNode ] ~ { RETURN[lc, lc.unpaintedPaint] };
GetUniquePaint: PUBLIC PROC [ lc: LocalContextNode ] RETURNS [ lcp: LocalContextNode, p: PaintNode ] ~ {
lc.paintIndex _ lc.paintIndex + 1;
RETURN[lc, NEW [PaintNodeBody _ [lc, lc.paintIndex]]];
};
DefaultExpNode: TYPE ~ REF DefaultExpNodeBody;
DefaultExpNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.DefaultExpNodeBody;

DefaultExpVal: PUBLIC PROC [case: Rope.ROPE, exp: ValueNode]
RETURNS [ DefaultExpNode ] ~ {
RETURN[NEW [DefaultExpNodeBody _ [
SELECT TRUE FROM
Rope.Equal[case, ""] => c1,
Rope.Equal[case, "_"] => c2,
Rope.Equal[case, "_e"] => c3,
Rope.Equal[case, "_TRASH"] => c4,
Rope.Equal[case, "_e|TRASH"] => c5,
ENDCASE => ERROR,
exp]]];
};

NullDefaultVal: PUBLIC PROC RETURNS [ DefaultExpNode ] ~ {
RETURN[NIL];
};
PositionValNode: TYPE ~ REF PositionValNodeBody;
PositionValNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.PositionValNodeBody;

PositionValFun: PUBLIC PROC [ index: ValueNode, bounds: BoundsValNode ]
RETURNS [ PositionValNode ] ~ {
RETURN[NEW[PositionValNodeBody _ [index, bounds]]];
};

NullPosition: PUBLIC PROC RETURNS [ PositionValNode ] ~ {
RETURN[NIL];
};
BoundsValNode: TYPE ~ REF BoundsValNodeBody;
BoundsValNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.BoundsValNodeBody;

BoundsValFun: PUBLIC PROC [ leftBracket: Rope.ROPE, first: ValueNode, last: ValueNode, rightBracket: Rope.ROPE ] RETURNS [ BoundsValNode ] ~ {
bvn: BoundsValNode _ NEW [BoundsValNodeBody _ [open, first, last, open]];
bvn.left _ SELECT TRUE FROM
Rope.Equal["[", leftBracket] => closed,
Rope.Equal["(", leftBracket] => open,
ENDCASE => ERROR;
bvn.right _ SELECT TRUE FROM
Rope.Equal["]", rightBracket] => closed,
Rope.Equal[")", rightBracket] => open,
ENDCASE => ERROR;
RETURN[bvn];
};

NullBounds: PUBLIC PROC RETURNS [ BoundsValNode ] ~ { RETURN[NIL] };
AccessValNode: TYPE ~ REF AccessValNodeBody;
AccessValNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.AccessValNodeBody;

AccessValConst: PUBLIC PROC [ r: Rope.ROPE ] RETURNS [ AccessValNode ] ~ {
SELECT TRUE FROM
Rope.Equal[r, "private"] => RETURN[NEW [AccessValNodeBody _ private]];
Rope.Equal[r, "public"] => RETURN[NEW [AccessValNodeBody _ public]];
ENDCASE => ERROR EH.InternalError[Rope.Cat["Bad argument (", r, ") to SaffronContextCreateCTImpl.AccessValConst"]];
};

NullAccessVal: PUBLIC PROC [ ] RETURNS [ AccessValNode ] ~ {
RETURN[NIL];
};

FakeCopyAccessVal: PUBLIC PROC [avn: AccessValNode] RETURNS [AccessValNode] ~ {
RETURN[avn];
};


ScopePTreeNode: TYPE ~ REF ScopePTreeNodeBody;
ScopePTreeNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.ScopePTreeNodeBody;
ScopePTreeVal: PUBLIC PROC [ node: AT.ScopeNode ] RETURNS [ ScopePTreeNode ] ~ { RETURN[NEW [ScopePTreeNodeBody _ [node]]] };

ScopeVal: PUBLIC PROC [ box: ScopePTreeNode ] RETURNS [ AT.ScopeNode ] ~ { RETURN[box.node] };
ModulePPTreeNode: TYPE ~ REF ModulePPTreeNodeBody;
ModulePPTreeNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.ModulePPTreeNodeBody;

ModulePPTreeVal: PUBLIC PROC [ node: AT.ModulePNode ]
RETURNS [ ModulePPTreeNode ] ~ 
{RETURN[NEW[ModulePPTreeNodeBody_[node]]]};

ModulePVal: PUBLIC PROC [ node: ModulePPTreeNode ] RETURNS [ AT.ModulePNode ] ~ 
{RETURN[node.node]};



DefBodyPTreeNode: TYPE ~ REF DefBodyPTreeNodeBody;
DefBodyPTreeNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.DefBodyPTreeNodeBody;

DefBodyPTreeVal: PUBLIC PROC [ node: AT.DefBodyNode ]
RETURNS [ DefBodyPTreeNode ] ~ 
{RETURN[NEW[DefBodyPTreeNodeBody_[node]]]};


DefBodyVal: PUBLIC PROC [ node: DefBodyPTreeNode ]
RETURNS [ AT.DefBodyNode ] ~ 
{RETURN[node.node]};
TypeExpPTreeNode: TYPE = REF TypeExpPTreeNodeBody;
TypeExpPTreeNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.TypeExpPTreeNodeBody;

TypeExpPTreeVal: PUBLIC PROC [ node: AT.TypeExpNode ]
RETURNS [ TypeExpPTreeNode ] ~ 
{RETURN[NEW[TypeExpPTreeNodeBody_[node]]]};


TypeExpVal: PUBLIC PROC [ node: TypeExpPTreeNode ]
RETURNS [ AT.TypeExpNode ] ~ 
{RETURN[node.node]};
InitializationPTreeNode: TYPE = REF InitializationPTreeNodeBody;
InitializationPTreeNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.InitializationPTreeNodeBody;

InitializationPTreeVal: PUBLIC PROC [ node: AT.InitializationNode ]
RETURNS [ InitializationPTreeNode ] ~ 
{RETURN[NEW[InitializationPTreeNodeBody_[node]]]};


InitializationVal: PUBLIC PROC [ node: InitializationPTreeNode ]
RETURNS [ AT.InitializationNode ] ~ 
{RETURN[node.node]};
DeclarationPTreeNode: TYPE = REF DeclarationPTreeNodeBody;
DeclarationPTreeNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.DeclarationPTreeNodeBody;

DeclarationPTreeVal: PUBLIC PROC [ node: AT.DeclarationNode ]
RETURNS [ DeclarationPTreeNode ] ~ 
{RETURN[NEW[DeclarationPTreeNodeBody_[node]]]};


DeclarationVal: PUBLIC PROC [ node: DeclarationPTreeNode ]
RETURNS [ AT.DeclarationNode ] ~ 
{RETURN[node.node]};
NameSequenceNode: TYPE = REF NameSequenceNodeBody;
NameSequenceNodeBody: PUBLIC TYPE = SaffronContextPrivateTypes.NameSequenceNodeBody;

EmptyNameSequence: PUBLIC PROC RETURNS[NameSequenceNode] =
{RETURN[NEW[NameSequenceNodeBody _ NIL]]};

InsertNameOnNameSequence: PUBLIC PROC[name: GEN.IdNode, ns: NameSequenceNode] RETURNS[NameSequenceNode] =
{RETURN[NEW[NameSequenceNodeBody _ CONS[name, ns^]]]};
ErrorSignal: PUBLIC ERROR ~ CODE;
FrozenFieldListNode: TYPE = REF FrozenFieldListNodeBody;
FrozenFieldListNodeBody: PUBLIC TYPE = PT.FrozenFieldListNodeBody;

FieldListNode: TYPE = REF FieldListNodeBody;
FieldListNodeBody: PUBLIC TYPE = PT.FieldListNodeBody;

FieldListCell: TYPE = REF FieldListCellBody;
FieldListCellBody: PUBLIC TYPE = PT.FieldListCellBody;

FieldNode: TYPE = REF FieldNodeBody;
FieldNodeBody: PUBLIC TYPE = PT.FieldNodeBody;
CreateEmptyFieldList: PUBLIC PROC RETURNS [FieldListNode] ~ {
 RETURN[NEW [FieldListNodeBody _ [FALSE, FALSE, NIL, NIL]]] };

FakeDamageFieldList: PUBLIC PROC [fl: FieldListNode] RETURNS [FieldListNode] ~ {
 RETURN[fl] };

AnyFieldList: PUBLIC PROC RETURNS [ fl: FieldListNode ] ~ { RETURN[NEW [FieldListNodeBody _ [FALSE, TRUE, NIL, NIL]]] };

AppendFieldToFieldList: PUBLIC PROC [fl: FieldListNode, f: FieldNode] RETURNS [flp: FieldListNode] = BEGIN
newCell: FieldListCell _ NEW [FieldListCellBody _ [f, NIL]];
IF (f.name # NIL) THEN FOR cell: FieldListCell _ fl.first, cell.next WHILE (cell # NIL) DO
IF Rope.Equal[cell.node.name.text, newCell.node.name.text] THEN {
SIGNAL EH.Error[newCell.node.name.position, IO.PutFR["%g is multiply defined", IO.rope[newCell.node.name.text]]];
RETURN [fl];
};
ENDLOOP;
IF fl.last = NIL
THEN fl.first _ newCell
ELSE fl.last.next _ newCell;
fl.last _ newCell;
RETURN [fl];
END;

FreezeFieldList: PUBLIC PROC [fl: FieldListNode] RETURNS [ffl: FrozenFieldListNode] = BEGIN
n: INT _ 0;
FOR cell: FieldListCell _ fl.first, cell.next WHILE (cell # NIL) DO n _ n + 1; ENDLOOP;
ffl _ NEW[FrozenFieldListNodeBody _ [FALSE, n, fl]];
END;

CreateNamedTypeField: PUBLIC PROC [name: GEN.IdNode, position: PositionValNode, access: AccessValNode, namedType: TypeGraphNodeNode, parseTree: TypeExpPTreeNode] RETURNS [FieldNode] = BEGIN
pt: AT.TypeExpNode _ IF parseTree = NIL THEN NIL ELSE parseTree.node;
RETURN[NEW[FieldNodeBody _ [name, position, typeDecl[access, namedType, pt]]]];
END;

CreateModuleField: PUBLIC PROC [name: GEN.IdNode, position: PositionValNode, tgn: TypeGraphNodeNode] RETURNS [FieldNode] = BEGIN
RETURN[NEW[FieldNodeBody _ [name, position, module[tgn]]]];
END;

CreateConstantField: PUBLIC PROC [name: GEN.IdNode, position: PositionValNode, declaration: DeclarationPTreeNode, access: AccessValNode, tgn: TypeGraphNodeNode, initialization: InitializationPTreeNode] RETURNS [FieldNode] = BEGIN
value: ValueNode _ initialization.procs.GetInitialValue[initialization.node];
RETURN[NEW[FieldNodeBody _ [name, position, constant[access, tgn, initialization, value, declaration]]]];
END;

CreateVariableField: PUBLIC PROC [name: GEN.IdNode, position: PositionValNode, declaration: DeclarationPTreeNode, access: AccessValNode, tgn: TypeGraphNodeNode, initialization: InitializationPTreeNode] RETURNS [FieldNode] = BEGIN
RETURN[NEW[FieldNodeBody _ [name, position, variable[access, tgn, initialization, declaration]]]];
END;

CreateNamedField: PUBLIC PROC [name: GEN.IdNode, position: PositionValNode, access: AccessValNode, tgn: TypeGraphNodeNode, default: DefaultExpNode] RETURNS [FieldNode] = BEGIN
RETURN[NEW[FieldNodeBody _ [name, position, recordField[access, tgn, default]]]];
END;

CreateUnnamedField: PUBLIC PROC [tgn: TypeGraphNodeNode, default: DefaultExpNode] RETURNS [FieldNode] = BEGIN
RETURN[NEW[FieldNodeBody _ [NIL, NIL, recordField[NIL, tgn, default]]]];
END;

DemandTypeDeclarationField: PUBLIC PROC [f: FieldNode] RETURNS [AccessValNode, TypeGraphNodeNode] = BEGIN
WITH f SELECT FROM
ff: REF typeDecl FieldNodeBody => RETURN[ff.access, ff.type];
ENDCASE => ERROR EH.FatalError[f.name.position, IO.PutFR["%g does not name a type", IO.rope[f.name.text]]];
END;

DemandConstantField: PUBLIC PROC [f: FieldNode] RETURNS [AccessValNode, TypeGraphNodeNode, InitializationPTreeNode, ValueNode] = BEGIN
WITH f SELECT FROM
ff: REF constant FieldNodeBody => RETURN[ff.access, ff.type, ff.initialization, ff.value];
ENDCASE => ERROR EH.FatalError[f.name.position, IO.PutFR["%g does not name a constant", IO.rope[f.name.text]]];
END;

DemandConstantOrVariableField: PUBLIC PROC [f: FieldNode] RETURNS [AccessValNode, TypeGraphNodeNode, InitializationPTreeNode, BOOLEAN] = BEGIN
WITH f SELECT FROM
ff: REF constant FieldNodeBody => RETURN[ff.access, ff.type, ff.initialization, TRUE];
ff: REF variable FieldNodeBody => RETURN[ff.access, ff.type, ff.initialization, FALSE];
ENDCASE => ERROR EH.FatalError[f.name.position, IO.PutFR["%g does not name a constant or variable", IO.rope[f.name.text]]];
END;

FieldExists: PUBLIC PROC [f: FieldNode] RETURNS [BOOLEAN] = BEGIN
RETURN [f # NIL];
END;

FieldType: PUBLIC PROC [field: FieldNode] RETURNS [TypeGraphNodeNode] = BEGIN
RETURN [WITH field SELECT FROM
f: REF typeDecl FieldNodeBody	=> f.type,
f: REF module FieldNodeBody		=> f.type,
f: REF constant FieldNodeBody	=> f.type,
f: REF variable FieldNodeBody	=> f.type,
f: REF recordField FieldNodeBody	=> f.type,
ENDCASE								=> ERROR
];
END;


LookupNameInFieldList: PUBLIC PROC [fields: FieldListNode, name: GEN.IdNode] RETURNS [FieldNode] = BEGIN
FOR cell: FieldListCell _ fields.first, cell.next WHILE cell # NIL DO
IF Rope.Equal[cell.node.name.text, name.text] THEN RETURN [cell.node];
ENDLOOP;
RETURN [NIL];
END;

LookupNameInContextRib: PUBLIC PROC [name: GEN.IdNode, rib: ContextRibNode] RETURNS [FieldNode] = BEGIN
WHILE (rib # NIL) DO
ffl: FrozenFieldListNode _ ContextRibLocalFrozenFieldList[rib];
field: FieldNode _ LookupNameInFieldList[ffl.cells, name];
IF field # NIL THEN RETURN [field];
rib _ rib.lc.parentRib;
ENDLOOP;
RETURN [NIL];
END;

ContextRibLocalFrozenFieldList: PUBLIC PROC [rib: ContextRibNode] RETURNS [FrozenFieldListNode] = BEGIN
RETURN[
WITH rib.lc.contents SELECT FROM
c: REF unfrozen LocalContextContentsBody => 
ERROR EH.InternalError["Rib containing unfrozen local context detected during lookup"],
c: REF frozen LocalContextContentsBody =>
WITH c.block.body SELECT FROM
block: REF PT.BlockTGNBody			=> block.ffl,
module: REF PT.ModuleTGNBody		=> module.ffl,
ic: REF PT.InterfaceContentsTGNBody	=> ic.ffl,
ENDCASE									=> 
ERROR EH.InternalError["Illegal contents in local context"],
ENDCASE => ERROR
];
END;

ParameterizedFieldDescriptorNode: TYPE = REF ParameterizedFieldDescriptorNodeBody;
ParameterizedFieldDescriptorNodeBody: PUBLIC TYPE = PG.ParameterizedFieldDescriptorNodeBody;

GetPathToName: PUBLIC PROC [ct: ContextTreeNode, name: GEN.IdNode] RETURNS [pfd: ParameterizedFieldDescriptorNode, tgn: TypeGraphNodeNode] = BEGIN
lc: LocalContextNode _ ct.rib.lc; -- look for bugs in this proc!!
field: FieldNode _ LookupNameInContextRib[name, ct.rib];
pfd _ PGD.EmptyPFD[];
tgn _ IF field = NIL 
THEN ERROR EH.FatalError[name.position, IO.PutFR["%g is undefined", IO.rope[name.text]]]
ELSE WITH field SELECT FROM
f: REF constant FieldNodeBody => f.type,
f: REF variable FieldNodeBody => f.type,
ENDCASE	=> ERROR;
WHILE TRUE DO
ffl: FrozenFieldListNode _ ContextRibLocalFrozenFieldList[ct.rib];
res: FieldNode _ LookupNameInFieldList[ffl.cells, name];
IF res = NIL 
THEN IF lc.parentRib = NIL
THEN ERROR EH.FatalError[name.position, IO.PutFR["%g is undeclared", IO.rope[name.text]]]
ELSE pfd _ PGD.AddNestedCellToPFD[pfd]
ELSE {
pfd _ PGD.AddVarsCellToPFD[pfd, name.text];
EXIT;
};
lc _ lc.parentRib.lc;
ENDLOOP;
END;




CompileLValueIntoRValue: PUBLIC PROC [pfd: ParameterizedFieldDescriptorNode, ct: ContextTreeNode] RETURNS [value: ValueNode] = BEGIN
cell: PG.ParameterizedFieldDescriptorCell _ pfd.firstCell;
local: BOOLEAN _ TRUE;
rib: ContextRibNode _ ct.rib;
WHILE (cell # NIL) AND (cell.kind = nested) DO 
rib _ rib.lc.parentRib;
cell _ cell.next;
local _ FALSE;
ENDLOOP;
BEGIN
c: REF vars PG.ParameterizedFieldDescriptorCellBody _ NARROW[cell];
field: FieldNode _ LookupNameInContextRib[IdNodeFromRope[c.name], rib];
IF field = NIL THEN ERROR EH.InternalError["Blat"];
WITH field SELECT FROM
ff: REF constant FieldNodeBody =>
SELECT TRUE FROM
(ff.value.kind = static)	=> value _ ff.value;
local						=> {
code: BD.ProgramFragmentNode _ PGD.MakePGLoadLocal[pfd];
RETURN[NEW[ValueNodeBody _ [runtime[code, ff.type]]]];
};
ENDCASE					=> {
code: BD.ProgramFragmentNode _ PGD.MakePGLoadIndirect[pfd];
RETURN[NEW[ValueNodeBody _ [runtime[code, ff.type]]]];
};
ff: REF variable FieldNodeBody =>
SELECT TRUE FROM
local						=> {
code: BD.ProgramFragmentNode _ PGD.MakePGLoadLocal[pfd];
RETURN[NEW[ValueNodeBody _ [runtime[code, ff.type]]]];
};
ENDCASE					=> {
code: BD.ProgramFragmentNode _ PGD.MakePGLoadIndirect[pfd];
RETURN[NEW[ValueNodeBody _ [runtime[code, ff.type]]]];
};
ENDCASE => ERROR EH.InternalError["Blort"];
END;
END;

FindAFieldCorrespondingToDeclaration: PUBLIC PROC [ct: ContextTreeNode, declaration: DeclarationPTreeNode] RETURNS [FieldNode] = BEGIN
FOR cell: FieldListCell _ ContextRibLocalFrozenFieldList[ct.rib].cells.first, cell.next WHILE (cell # NIL) DO
WITH cell.node SELECT FROM
f: REF typeDecl FieldNodeBody => NULL;
f: REF module FieldNodeBody => ERROR EH.InternalError["69 foo"];
f: REF constant FieldNodeBody => IF f.declaration.node = declaration.node THEN RETURN[cell.node];
f: REF variable FieldNodeBody => IF f.declaration.node = declaration.node THEN RETURN[cell.node];
f: REF recordField FieldNodeBody => ERROR EH.InternalError["69 bar"];
ENDCASE => ERROR;
ENDLOOP;
ERROR EH.InternalError["69 baz"];
END;


IdNodeFromRope: PROC [r: Rope.ROPE] RETURNS [GEN.IdNode] = INLINE BEGIN
RETURN [NEW[GEN.IdNodeBody _ [r, 0, 0]]];
END;

END.

��{2��SaffronContextCreateCTImpl.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:53:31 pm PDT
Lucy Hederman August 17, 1987 6:32:17 pm PDT
James Rauen, June 27, 1988 1:04:12 pm PDT
Last edited by: James Rauen August 25, 1988 4:29:38 pm PDT
This module contains the code to create context trees and type graphs, but it performs no analysis, nor does it contain any print routines.

This module contains the code to create the context tree and type graph, but it performs no analysis, nor does it contain any print routines
Module Stuff
The need for delving into the root data structure is a hack.  Since the parser returns a TopNode, the recursive function body that calls theis procedure should have been prepared to get a (boxed) TopNode, rather than a (boxed) ModulePNode.
tries working directory then release.  Adopts some code from Bill Jackson.
If the working directory succeeds, then returns a file name without any directory prefix.
If had to try the release, then returns a file name with directory prefix.
Environments
damages env and ifc
... look up in context ...
LookupInterfaceInEnv: PUBLIC PROC [env: EnvironmentNode, fileName: Rope.ROPE, interfaceName: Rope.ROPE] RETURNS [res: TypeGraphNodeNode] = BEGIN
contextTree: ContextTreeNode _ LookupCompiledFileInEnv[env, fileName];
IF contextTree = NIL THEN RETURN [NIL];
res _ LookupLocalName[contextTree.rib.lc, IdNodeFromRope[interfaceName]];

END;

declare as damaging env
Interfaces

this procedure must be called after forming the context tree that contains the body of the definitions file.  i.e., the names occurring in the locally visible names must be the names one expects to see in the interface
It is a little bit of a crock at the moment, because I do not have the data structures quite like I would like them.

Note: Context trees have no modifiable data structures.  Hence, this does not have to damage the context tree, nor share with the result.
CreateInterfaceFromContextTree: PUBLIC PROC [ct: ContextTreeNode, ns: NameSequenceNode]
RETURNS [in: InterfaceValNode] ~ {
entries: VisibleNames _ CreateEmptyVisibleNames[];
typeNames: VisibleNames _ ct.rib.lc.localNames; -- herein lies the crock
EnterOneName: PROC [name: GEN.IdNode, access: AccessValNode, value: REF ANY] ~ {
tgn: TypeGraphNodeNode _ NARROW[value]; -- check
RecordVisibleTypeName[entries, name, access, tgn];
};
GenVisibleNames[typeNames, EnterOneName];
RETURN[NEW [InterfaceValNodeBody _ [ns, entries, ct]]];
};
used to create an interfaceTGN whole hog
GenInterfaceEntries: PROC [in: InterfaceValNode,
for: PROC [GEN.IdNode, AccessValNode, TypeGraphNodeNode] ] ~ {
SeeOne: PROC [name: GEN.IdNode, access: AccessValNode, value: REF ANY] ~ {
for[name, access, NARROW[value]];
};
GenVisibleNames[in.entries, SeeOne];
};
LookupInterfaceEntry: PUBLIC PROC [in: InterfaceValNode, name: GEN.IdNode]
RETURNS [access: AccessValNode, tgn: TypeGraphNodeNode] ~ {
value: REF ANY;
[access, value] _ LookupVisibleTypeName[in.entries, name];
RETURN[access, NARROW[value]];
};

Context Trees
ERROR: There needs to be a form of frozen context tree.  In any case, the comment on CreateInterfaceFromContextTree is wrong.  Either there is a way of freezing context trees, and it will be used on the way to forming an interface, so as to avoid the declaration of sharing, or we build up a list of context trees, and then form then at one blow.  I prefer the latter.  So, we need a new concept: ContextTreeSeq, the following ops: EmptyContextTree, FakeDamageContextTree, AddContextTree, and finally, FormContextTree which takes a ContextTreeSeq.
(declared as damages ctn)
(damages ctn)
Context Ribs
Local Contexts
		  Name		Signed?	nBits	nUnusedBits	
AddIntegerBaseType[lc, fl, "CARD",		?	?	?]; 
AddIntegerBaseType[lc, fl, "DCARD",		?	?	?]; 
AddIntegerBaseType[lc, fl, "DINT",		?	?	?];
Type Graph Nodes
( FIX: This should be a procedure to be applied to a RIB,
we will change as soon as we get ribs )
FindBottomTGN: PUBLIC PROC [ lc: LocalContextNode ]
RETURNS [ tgn: TypeGraphNodeNode ] ~ {
RETURN[lc.bottom];
};
( FIX: This should be a procedure to be applied to a RIB,
we will change as soon as we get ribs )
FindTopTGN: PUBLIC PROC [ lc: LocalContextNode ]
RETURNS [ tgn: TypeGraphNodeNode ] ~ {
RETURN[lc.top];
};
( Upon reaching top level context,
then looks up names of frames and interfaces, then root context.
Must add this later. )
FindLocallyVisibleTGN: PUBLIC PROC [ lc: LocalContextNode, name: GEN.IdNode ]
RETURNS [ TypeGraphNodeNode ] ~ {
FOR lcx: LocalContextNode _ lc, lcx.rib.lc WHILE ( lcx # NIL ) DO
tgn: TypeGraphNodeNode _ NARROW[LookupVisibleTypeName[lcx.localNames, name].value];
IF tgn # NIL THEN RETURN[tgn];
IF lcx.rib = NIL THEN EXIT;
ENDLOOP;
ERROR EH.InternalError["Nothing found in SaffronContextCreateCTImpl.FindLocallyVisibleTGN"];
};
Locally Visible Names
Very simple for now, just a chained list of IdNodes
Values
Specific Types and Values
Array
Atom
Block
Bottom
This is only created once per compilation, by CreateRootContextRib.
Condition **
Descriptor **
Element
...fix the bounds!! -- right now, nothing distinguishes () from [], etc....
one of elementName or rep can be NIL
"Frame"
FindFrameTGN: PUBLIC PROC [ lc: LocalContextNode, id: GEN.IdNode ]
RETURNS [ tgn: TypeGraphNodeNode ] ~ {
tgn _ FindLocallyVisibleTGN[lc, id];
WITH tgn.body SELECT FROM
ftgn: FrameTGN => RETURN[tgn];
ENDCASE => ERROR;
};
Identifier
Implementation
Interface
InterfaceContents
Link
List
Long
Monitorlock
Module
SetModuleLocalContextContents: PUBLIC PROC [lc: LocalContextNode, tgn: TypeGraphNodeNode, ffl: FrozenFieldListNode] RETURNS [LocalContextNode] = BEGIN
two things: stuff fl into tgn, stuff tgn into lc.
moduleTGN: PT.ModuleTGN _ NARROW[tgn.body];
moduleTGN.ffl _ ffl;
lc.contents _ NEW[PT.LocalContextContentsBody _ [frozen[tgn]]];
RETURN [lc];
END;
Named
Creates a named type graph node AND adds a field to lc's field list.
Right now, I'm using the same arguments for the field's position/access and the namedtgn's position/access.  This should be fixed.  No, I don't know how.
CreateNamedTGN: PUBLIC PROC [lc: LocalContextNode, name: GEN.IdNode, position: PositionValNode, access: AccessValNode, type: TypeGraphNodeNode, default: DefaultExpNode] RETURNS [LocalContextNode, TypeGraphNodeNode] = BEGIN
Creates a named type graph node AND adds a field to lc's field list.
body: PT.NamedTGN _ NEW[PT.NamedTGNBody _ [name, access, type, default]];
tgn: TypeGraphNodeNode _ CreateTGN[lc, body];
Right now, I'm using the same arguments for the field's position/access and the namedtgn's position/access.  This should be fixed.  No, I don't know how.
field: FieldNode _ CreateNamedTypeField[name, position, access, tgn];
[] _ AppendFieldToFieldList[LocalContextFields[lc], field];
SIGNAL EH.Message[Rope.Cat["Creating locally visible TGN named ", BD.RopeFromId[name]]];
RETURN[lc, tgn];
END;



CreateLocallyVisibleTGN:  PUBLIC PROC [ lc: LocalContextNode, name: GEN.IdNode, access: AccessValNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: NamedTGN _ NEW [NamedTGNBody _ [name: name]];
SIGNAL EH.Message[Rope.Cat["Creating locally visible TGN named ", BD.RopeFromId[name]]];
tgn _ CreateTGN[lc, body];
RecordVisibleTypeName[lc.localNames, name, access, tgn];
RETURN[lc, tgn];
};

Requires:  tgn is named tgn, tgn.body.type is interface tgn.
write me!! --
Opaque
There is no parse tree for opaque types, but we need something to stuff into an opaque type's FieldNode.parseTree slot.
Pointer
Real
Record
Ref
Referent
Relative
Sequence
Specianated TGN
(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)

(This one might be the selection of a type from an interface)
WITH underlyingType.body SELECT FROM
iftgn: InterfaceTGN => {
RETURN[lc, LookupTypeNameInInterfaceTGN[lc, id, underlyingType].tgn];
probably should be doing an access check here
};
ENDCASE => {
body: PT.SpecianatedTGN _ NEW [PT.SpecianatedTGNBody _ [NIL, id, underlyingType]];
RETURN[lc, CreateTGN[lc, body]];
};

(this one can not be the selection of a type from an interface)
String
Transfer
Top
This is only created once per compilation, by CreateRootContextRib.
Unspecified
Var
Variant Part and Union List
damages ul
damages ul, used internally
Zone
Top and Bottom
CreateTopAndBottom: PROC [ lc: LocalContextNode ] RETURNS [ top, bottom: TypeGraphNodeNode ] ~ {
topBody: SpecialTGN _ NEW [SpecialTGNBody _ [top]];
bottomBody: SpecialTGN _ NEW [SpecialTGNBody _ [bottom]];
top _ CreateTGN[lc, topBody];
bottom _ CreateTGN[lc, bottomBody];
};
Named nodes (i.e., locally visible)
AddVariableName:  PUBLIC PROC [ lc: LocalContextNode, name: GEN.IdNode, access: AccessValNode, constant: BOOLEAN ] RETURNS [ lcp: LocalContextNode ] ~ {
Adds a variable name to the local context.
body: NamedTGN _ NEW [NamedTGNBody _ [name: name]];
SIGNAL EH.Message[Rope.Cat["Adding variable named ", BD.RopeFromId[name]]];
RecordVisibleVariableName[lc.localNames, name, access, constant];
RETURN[lc];
};

AddArcFromLVTGNToTGN: PUBLIC PROC [ lc: LocalContextNode, lvTgn: TypeGraphNodeNode, access: AccessValNode, tgn: TypeGraphNodeNode, default: DefaultExpNode ] RETURNS [ lcp: LocalContextNode ] ~ {
namedNode: NamedTGN _ NARROW[lvTgn.body];
namedNode.access _ access;
namedNode.type _ tgn;
namedNode.default _ default;
RETURN[lc];
};
AddArcFromLocalNameToInstance: PUBLIC PROC [ lc: LocalContextNode, id: GEN.IdNode, access: AccessValNode, instance: BD.InstanceNode ] RETURNS [ lcp: LocalContextNode ] ~ {
cell: VNCell _ LookupLocalName[lc.localNames, id];
WITH cell SELECT FROM
c: REF type VNCellBody		=> ERROR;
c: REF constant VNCellBody	=> c.value _ instance;
c: REF variable VNCellBody	=> c.value _ instance;
ENDCASE;
RETURN[lc];
};
This routine should be checking access as it spins deeper
pointer type nodes
base and pointer must both be pointerTGNs, base must have base = true

refs point to encapsulated types

List nodes
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

EnumeratedType Nodes
CreateEmptyEnumTypeTGN: PUBLIC PROC [ lc: LocalContextNode, machineDependent: BOOLEAN ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: EnumTGN _ NEW [EnumTGNBody _ [machineDependent, GetUniquePaint[lc].p, NIL, NIL]];
RETURN[lc, CreateTGN[lc, body]];
};

one of elementName or rep can be NIL
AppendElementToEnumTypeTGN: PUBLIC PROC [ lc: LocalContextNode, tgn: TypeGraphNodeNode, elementName: GEN.IdNode, rep: ExpPTreeNode ] RETURNS [ lcp: LocalContextNode ] ~ {
body: EnumTGN _ NARROW[tgn.body];
cell: EnumElementCell _ NEW [EnumElementCellBody _ [elementName, rep, NIL]];
IF body.lastElement = NIL
THEN body.firstElement _ cell
ELSE body.lastElement.next _ cell;
body.lastElement _ cell;
RETURN[lc];
};
Field lists and frozen field lists
FieldNode: TYPE ~ REF FieldNodeBody;
FieldNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.FieldNodeBody;

FieldListNode: TYPE ~ REF FieldListNodeBody;
FieldListNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.FieldListNodeBody;

FrozenFieldListNode: TYPE ~ REF FrozenFieldListNodeBody;
FrozenFieldListNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.FrozenFieldListNodeBody;

FieldListCell: TYPE ~ SaffronContextPrivateTypes.FieldListCell;

CreateNamedField: PUBLIC PROC [ n: GEN.IdNode, pvn: PositionValNode, avn: AccessValNode, tgn: TypeGraphNodeNode, default: DefaultExpNode ] RETURNS [ f: FieldNode ] ~ { RETURN[NEW [FieldNodeBody _ [n, pvn, avn, tgn, default]]] };

CreateUnnamedField: PUBLIC PROC [ tgn: TypeGraphNodeNode, default: DefaultExpNode ] RETURNS [ f: FieldNode ] ~ { RETURN[NEW [FieldNodeBody _ [NIL, NIL, NIL, tgn, default]]] };

CreateEmptyFieldList: PUBLIC PROC RETURNS [ fl: FieldListNode ] ~ { RETURN[NEW [FieldListNodeBody _ [FALSE, 0, 0, NIL, NIL]]] };

AnyFieldList: PUBLIC PROC RETURNS [ fl: FieldListNode ] ~ { RETURN[NEW [FieldListNodeBody _ [TRUE, 0, 0, NIL, NIL]]] };

PrependCellToFieldList: PROC [ nFields: INT, cell: FieldListCell, fl: FieldListNode ] RETURNS [ flp: FieldListNode ] ~ {
IF fl.any THEN ERROR;
cell.next _ fl.firstCell;
fl.firstCell _ cell;
IF fl.lastCell = NIL THEN fl.lastCell _ cell;
fl.nFields _ fl.nFields + nFields;
fl.nCells _ fl.nCells + 1;
RETURN[fl];
};

AppendCellToFieldList: PROC [ fl: FieldListNode, nFields: INT, cell: FieldListCell ] RETURNS [ flp: FieldListNode ] ~ {
IF fl.any THEN ERROR;
IF fl.lastCell = NIL THEN fl.firstCell _ cell ELSE fl.lastCell.next _ cell;
fl.lastCell _ cell;
fl.nFields _ fl.nFields + nFields;
fl.nCells _ fl.nCells + 1;
RETURN[fl];
};

PrependFieldToFieldList: PUBLIC PROC [ f: FieldNode, fl: FieldListNode ] RETURNS [ flp: FieldListNode ] ~ {
cell: FieldListCell _ NEW [FieldListCellBody _ [f, NIL]];
RETURN[PrependCellToFieldList[1, cell, fl]];
};

AppendFieldToFieldList: PUBLIC PROC [ fl: FieldListNode, f: FieldNode ] RETURNS [ flp: FieldListNode ] ~ {
cell: FieldListCell _ NEW [FieldListCellBody _ [f, NIL]];
RETURN[AppendCellToFieldList[fl, 1, cell]];
};

PrependFFLToFieldList: PUBLIC PROC [ ffl: FrozenFieldListNode, fl: FieldListNode ] RETURNS [ flp: FieldListNode ] ~ {
cell: FieldListCell _ NEW [FieldListCellBody _ [ffl, NIL]];
RETURN[PrependCellToFieldList[ffl.nFields, cell, fl]];
};

AppendFFLToFieldList: PUBLIC PROC [ fl: FieldListNode, ffl: FrozenFieldListNode ] RETURNS [ flp: FieldListNode ] ~ {
cell: FieldListCell _ NEW [FieldListCellBody _ [ffl, NIL]];
RETURN[AppendCellToFieldList[fl, ffl.nFields, cell]];
};

ConcatFieldLists: PUBLIC PROC [ fl1, fl2: FieldListNode ] RETURNS [ fl: FieldListNode ] ~ {
IF fl1.any OR fl2.any THEN ERROR;
IF fl1.firstCell = NIL THEN RETURN[fl2];
IF fl2.firstCell = NIL THEN RETURN[fl1];
fl1.lastCell.next _ fl2.firstCell;
fl1.lastCell _ fl2.lastCell;
fl1.nFields _ fl1.nFields + fl2.nFields;
fl1.nCells _ fl1.nCells + fl2.nCells;
RETURN[fl1];
};

FreezeFieldList: PUBLIC PROC [ lc: LocalContextNode, fl: FieldListNode ] RETURNS [ lcp: LocalContextNode, ffl: FrozenFieldListNode ] ~ {
cell: FieldListCell _ fl.firstCell;
ffl _ NEW [FrozenFieldListNodeBody[fl.nCells]];
ffl.any _ fl.any;
ffl.nFields _ fl.nFields;
ffl.next _ lc.fieldLists;
lc.fieldLists _ ffl;
FOR I: CARDINAL IN [0..CARDINAL[fl.nCells]) DO
ffl[I] _ WITH cell.item SELECT FROM
f: FieldNode => [field, f.name, f.pvn, f.avn, f.tgn, f.default, NIL],
fflist: FrozenFieldListNode => [ffl, NIL, NIL, NIL, NIL, NIL, fflist],
ENDCASE => ERROR;
cell _ cell.next;
ENDLOOP;
FOR I: CARDINAL IN [0..ffl.nFields) DO
SELECT ffl[I].case FROM
field => IF IsVariantPartTGN[ffl[I].tgn] THEN {
IF I = (CARDINAL[ffl.nFields]-1) THEN ffl.variant _ TRUE
ELSE ERROR; -- variation allowed only in last field
};
ffl => IF ffl[I].ffl.variant THEN {
IF I = (CARDINAL[ffl.nFields]-1) THEN ffl.variant _ TRUE
ELSE ERROR; -- variation allowed only in last field
};
ENDCASE => ERROR;
ENDLOOP;
RETURN[lc, ffl];
};
Variant Flavors
Sequence TGNs
Descriptor TGN
Transfer TGN
Long TGN
Interface TGN
There are several ways to create interfaceTGNs.  One is directly from an interface, using all the entries.  (Corresponds to directory line without out a Using clause).  Another is by putting the names in one at a time.  (Used to implement a directory line with a Using clause.),  The third is by a "renaming" Open clause entry.

When creating the first interfaceTGN within one module tot points to a particular second module, be sure to use the Link tgns inbetween.  For a directory line without a Using clause, this is done by CreateInterfaceTGNFromInterface, but when a Using clause is involved, the recursive function is responsible.
CreateEmptyInterfaceTGN: PUBLIC PROC [ lc: LocalContextNode ] RETURNS [ lcp: LocalContextNode, tgn: TypeGraphNodeNode ] ~ {
body: InterfaceTGN _ NEW [InterfaceTGNBody _ [FALSE, CreateEmptyVisibleNames[]]];
RETURN[lc, CreateTGN[lc, body]];
};

damages lc
AddTGNToInterfaceTGN: PUBLIC PROC [lc: LocalContextNode, if: TypeGraphNodeNode, name: GEN.IdNode, access: AccessValNode, entryTgn: TypeGraphNodeNode]
RETURNS [lcp: LocalContextNode] ~ {
iftgn: InterfaceTGN _ NARROW[if.body];
IF entryTgn # NIL THEN RecordVisibleTypeName[iftgn.typeNames, name, access, entryTgn];
if entryTgn = NIL then we are in a Using clause and processing an entry point name rather than a type name, we should do nothing here, and later this case will go away when we correctly handle entry points.
RETURN[lc];
};
CreateInterfaceTGNFromInterface: PUBLIC PROC [lc: LocalContextNode, if: InterfaceValNode] RETURNS [lcp: LocalContextNode, ifTgn: TypeGraphNodeNode] ~ {
AddOne: PROC [name: GEN.IdNode, access: AccessValNode, entryTGN: TypeGraphNodeNode] ~ {
[] _ AddTGNToInterfaceTGN[lc, ifTgn, name, access, CreateLinkTGN[lc, entryTGN, if, name].ltgn];
};
ifTgn _ CreateEmptyInterfaceTGN[lc].tgn;
GenInterfaceEntries[if, AddOne];
RETURN[lc, ifTgn];
};
ExportLocallyVisibleTGN: PUBLIC PROC[lc: LocalContextNode, name: GEN.IdNode] RETURNS[AccessValNode, TypeGraphNodeNode] =
BEGIN
ratgn: REF ANY;
access: AccessValNode;
[access, ratgn] _ LookupVisibleName[lc.lvtn, name];
IF ratgn # NIL THEN RETURN[access, NARROW[ratgn]];
ErrorSignal[];
END;
LookupTypeNameInInterfaceTGN: PUBLIC PROC [ lc: LocalContextNode, id: GEN.IdNode, if: TypeGraphNodeNode ] RETURNS [ tgn: TypeGraphNodeNode ] ~ {
iftgn: InterfaceTGN _ NARROW[if.body];
refAnyTgn: REF ANY;
access: AccessValNode;
[access, refAnyTgn] _ LookupVisibleTypeName[iftgn.typeNames, id];
IF access^ = public OR (access^ = private AND iftgn.sharedAccess) THEN RETURN[NARROW[refAnyTgn]];
ERROR EH.InternalError[ "SaffronContextCreateCTImpl.LookupTypeNameInInterfaceTGN"];
};

GenPublicTypeNamesFromInterfaceTGN: PROC [ if: TypeGraphNodeNode,
for: PROC [ GEN.IdNode, TypeGraphNodeNode ] ] ~ {
iftgn: InterfaceTGN _ NARROW[if.body];
localFor: PROC [name: GEN.IdNode, access: AccessValNode, value: REF ANY] ~ 
BEGIN
IF access^ = public OR (access^ = private AND iftgn.sharedAccess) THEN for[name, NARROW[value]] 
END;
GenVisibleNames[iftgn.typeNames, localFor];
};

(following two operations correspond to entries in an OPEN clause)

(OPEN name: interface)
RenameInterface: PUBLIC PROC [lc: LocalContextNode, name: GEN.IdNode, interface: TypeGraphNodeNode] RETURNS [lcp: LocalContextNode] ~ {
newTGN: TypeGraphNodeNode _ CreateLocallyVisibleTGN[lc, name, AccessValConst["private"]].tgn;
WITH interface.body SELECT FROM
itgn: InterfaceTGN => NULL;
ENDCASE => ERROR;
[] _ AddArcFromLVTGNToTGN[lc, newTGN, AccessValConst["private"], interface, DefaultExpVal["", SaffronInstance.MakeDummy["hi there"]]];
RETURN[lc];
};

(OPEN interface)
OpenInterface: PUBLIC PROC [ lc: LocalContextNode, interfaceTGN: TypeGraphNodeNode ] RETURNS [ lcp: LocalContextNode ] ~ {
OpenOneInterfaceTypeName: PROC [ name: GEN.IdNode, tgn: TypeGraphNodeNode ] ~ {
newTGN: TypeGraphNodeNode _ CreateLocallyVisibleTGN[lc, name, NEW[AccessValNodeBody_NotSureWhatItShouldBe]].tgn;
[] _ AddArcFromLVTGNToTGN[lc, newTGN, NEW[AccessValNodeBody_NotSureWhatItShouldBe], tgn, DefaultExpVal["", SaffronInstance.MakeDummy["hello"]]];
};
GenPublicTypeNamesFromInterfaceTGN[ResolveNamedNodes[interfaceTGN], OpenOneInterfaceTypeName];
RETURN[lc];
};
LinkTGN
damages lc
(currently might be called with NIL tgn, when in a Using clause and refering to a entry point, rather than a type)
CreateLinkTGN: PUBLIC PROC[lc: LocalContextNode, tgn: TypeGraphNodeNode, if: InterfaceValNode, itemName: GEN.IdNode] RETURNS[lcp: LocalContextNode, ltgn: TypeGraphNodeNode] =
BEGIN
IF tgn = NIL THEN RETURN[lc, NIL]; -- was a standin for an entry point
RETURN[lc, CreateTGN[lc, NEW[LinkTGNBody_[tgn, if, itemName]]]];
END;
Opaque TGNs
Paint nodes

Locally Visible Names
VisibleNames: TYPE = SaffronContextPrivateTypes.VisibleNames;

CreateEmptyVisibleNames: PROC RETURNS [ vn: VisibleNames ] ~ {
vn _ NEW [VisibleNamesBody _ [NIL]];
RETURN[vn];
};

RecordVisibleTypeName: PROC [ vn: VisibleNames, name: GEN.IdNode, access: AccessValNode,
value: TypeGraphNodeNode ] ~ {
edited by jrr June 21, 1988 3:22:46 pm PDT
newCell: VNCell;
IF IsNameAlreadyUsed[vn, name] THEN
EH.ErrorFatalError[222, IO.PutFR["%g is multiply defined", IO.rope[BD.RopeFromId[name]]]];
newCell _ NEW[VNCellBody _ [name, access, vn.first, type[value]]];
vn.first _ newCell;
};

RecordVisibleVariableName: PROC [ vn: VisibleNames, name: GEN.IdNode, access: AccessValNode, constant: BOOLEAN ] ~ {
newCell: VNCell;
IF IsNameAlreadyUsed[vn, name] THEN
EH.ErrorFatalError[222, IO.PutFR["%g is multiply defined", IO.rope[BD.RopeFromId[name]]]];
IF constant
THEN newCell _ NEW[VNCellBody _ [name, access, vn.first, variable[NIL]]]
ELSE newCell _ NEW[VNCellBody _ [name, access, vn.first, constant[NIL]]];
vn.first _ newCell;
};

IsNameAlreadyUsed: PROC [vn: VisibleNames, name: GEN.IdNode] RETURNS [BOOLEAN] ~ BEGIN
Return TRUE if name is already used in vn, FALSE otherwise.
cell: VNCell _ vn.first;
WHILE ( cell # NIL ) DO
IF Rope.Equal[BD.RopeFromId[cell.id], BD.RopeFromId[name]] THEN RETURN[TRUE];
cell _ cell.next;
ENDLOOP;
RETURN[FALSE];
END;

LookupVisibleTypeName: PROC [vn: VisibleNames, name: GEN.IdNode] RETURNS [access: AccessValNode, value: TypeGraphNodeNode] ~ BEGIN
Look up name in vn.  If name names a type, return its AccessValNode and type graph node.  If name names a variable, raise a fatal error.  If name does not appear in vn, return [NIL, NIL].
cell: VNCell _ vn.first;
WHILE ( cell # NIL ) DO
IF Rope.Equal[BD.RopeFromId[cell.id], BD.RopeFromId[name]] THEN 
WITH cell SELECT FROM 
foo: REF type VNCellBody => 
RETURN[cell.access, foo.type];
foo: REF variable VNCellBody => 
EH.ErrorFatalError[0, IO.PutFR["%g does not name a type", IO.rope[BD.RopeFromId[name]]]];
ENDCASE;
cell _ cell.next;
ENDLOOP;
RETURN[NIL, NIL];
END;

LookupVisibleVariableName: PROC [vn: VisibleNames, name: GEN.IdNode] RETURNS [access: AccessValNode, value: TypeGraphNodeNode] ~ BEGIN
Look up name in vn.  If name names a type, return its AccessValNode and type graph node.  If name names a variable, raise a fatal error.  If name does not appear in vn, return [NIL, NIL].
cell: VNCell _ vn.first;
WHILE ( cell # NIL ) DO
IF Rope.Equal[BD.RopeFromId[cell.id], BD.RopeFromId[name]] THEN 
WITH cell SELECT FROM 
foo: REF type VNCellBody => 
RETURN[cell.access, foo.type];
foo: REF variable VNCellBody => 
EH.ErrorFatalError[0, IO.PutFR["%g does not name a type", IO.rope[BD.RopeFromId[name]]]];
ENDCASE;
cell _ cell.next;
ENDLOOP;
RETURN[NIL, NIL];
END;

LookupLocalName: PROC [vn: VisibleNames, name: GEN.IdNode] RETURNS [VNCell] ~ {
cell: VNCell _ vn.first;
WHILE ( cell # NIL ) DO
IF Rope.Equal[BD.RopeFromId[cell.id], BD.RopeFromId[name]] THEN RETURN[cell];
cell _ cell.next;
ENDLOOP;
ERROR EH.InternalError[IO.PutFR["Could not find locally visible name %g", IO.rope[BD.RopeFromId[name]]]];
};

GenVisibleNames: PUBLIC PROC [vn: VisibleNames,
for: PROC [name: GEN.IdNode, access: AccessValNode, value: REF ANY] ] ~ {
cell: VNCell _ vn.first;
WHILE ( cell # NIL ) DO
WITH cell SELECT FROM
foo: REF type VNCellBody	=> for[cell.id, cell.access, foo.type];
foo: REF variable VNCellBody	=> NULL;
ENDCASE;
cell _ cell.next;
ENDLOOP;
};

MapOntoLocalNames: PUBLIC PROC [vn: VisibleNames, typeProc: TypeProc, constantProc: ConstantProc, varProc: VarProc] ~ BEGIN
cell: VNCell _ vn.first;
WHILE ( cell # NIL ) DO
WITH cell SELECT FROM
foo: REF type VNCellBody	=> typeProc[cell.id, cell.access, foo.type];
foo: REF constant VNCellBody	=> constantProc[cell.id, cell.access, foo.value];
foo: REF variable VNCellBody	=> varProc[cell.id, cell.access, foo.value];
ENDCASE;
cell _ cell.next;
ENDLOOP;
END;

MapOntoAllVisibleNames: PUBLIC PROC [vn: VisibleNames, typeProc: TypeProc, constantProc: ConstantProc, varProc: VarProc] ~ BEGIN
cell: VNCell _ vn.first;
WHILE ( cell # NIL ) DO
WITH cell SELECT FROM
foo: REF type VNCellBody	=> typeProc[cell.id, cell.access, foo.type];
foo: REF constant VNCellBody	=> constantProc[cell.id, cell.access, foo.value];
foo: REF variable VNCellBody	=> varProc[cell.id, cell.access, foo.value];
ENDCASE;
cell _ cell.next;
ENDLOOP;
END;
Default Exp Nodes
DefaultExpVal: PUBLIC PROC [ case: Rope.ROPE, exp: ExpPTreeNode ]
RETURNS [ DefaultExpNode ] ~ {
RETURN[NEW [DefaultExpNodeBody _ [
SELECT TRUE FROM
Rope.Equal[case, ""] => c1,
Rope.Equal[case, "_"] => c2,
Rope.Equal[case, "_e"] => c3,
Rope.Equal[case, "_TRASH"] => c4,
Rope.Equal[case, "_e|TRASH"] => c5,
ENDCASE => ERROR,
exp]]];
};
position val nodes
bounds val nodes
access val nodes
Rope.Equal[r, "empty"] => RETURN[NEW [AccessValNodeBody _ empty]];
ExpPTree
ExpPTreeNode: TYPE ~ REF ExpPTreeNodeBody;
ExpPTreeNodeBody: PUBLIC TYPE ~ SaffronContextPrivateTypes.ExpPTreeNodeBody;

I can't remember why these boxes are needed (ExpPTree, ScopePTree, ...).  Perhaps it is a flaw in the current version of ThreeCasabaFour.
exported to SaffronATDef??

ExpPTreeVal: PUBLIC PROC [ node: AT.ExpNode ] RETURNS [ ValueNode ] ~ {
RETURN[NEW [ValueNodeBody _ [unparsed[node]]]];
replaced by MakeUnparsedValue
};

NullExpPTree: PUBLIC PROC RETURNS [ ExpPTreeNode ] ~ { RETURN[NIL] };
replaced by MakeUnparsedNullValue
ScopePTree

exported to SaffronATDef??

ModulePPTreeNode
DefBodyPTreeNode 
TypeExpPTreeNode 
InitializationPTreeNode 
DeclarationPTreeNode 
NameSequence
RopeNames
RopeNames: TYPE  = REF RopeNamesBody;
RopeNamesBody: TYPE = SaffronContextPrivateTypes.RopeNamesBody;

RNCell: TYPE = REF RNCellBody; RNCellBody: TYPE = SaffronContextPrivateTypes.RNCellBody;

CreateEmptyRopeNames: PROC RETURNS[rns: RopeNames] =
BEGIN
rns _ NEW[RopeNamesBody _ [NIL]];
RETURN[rns];
END;

RecordRopeName: PROC[rns: RopeNames, name: Rope.ROPE, val: REF ANY] =
BEGIN
newCell: RNCell _ NEW[RNCellBody_[name, val, rns.first]];
IF (LookupRopeName[rns, name] # NIL) THEN ERROR EH.InternalError["SaffronContextCreateCTImpl.RecordRopeName"];
rns.first _ newCell;
END;

LookupRopeName: PROC[rns: RopeNames, name: Rope.ROPE] RETURNS[REF ANY] =
BEGIN
cell: RNCell _ rns.first;
WHILE cell # NIL DO
IF Rope.Equal[cell.name, name] THEN RETURN[cell.value];
cell _ cell.next;
ENDLOOP;
RETURN[NIL];
END;

GenRopeNames: PUBLIC PROC[rns: RopeNames, for: PROC[Rope.ROPE, REF ANY]] =
BEGIN
cell: RNCell _ rns.first;
WHILE cell # NIL DO
for[cell.name, cell.value];
cell _ cell.next;
ENDLOOP;
END;
following are exported to SaffronContext
Field Lists
Useful Types
Field List Constructors
Field Constructors
Here are the different kinds of fields which can occur within a field list:
(1) Named types.  For example, "Foo: TYPE = INT _ 3".  These can only appear in the field lists of block tgn's.
(2) Constants.  For example, "x: INT = 4".  These can only appear in the field lists of block tgn's.
(3) Named fields.  For example, "y: INT" or "z: INT _ 5".  These can appear in the field lists of block tgn's or record tgn's.
(4) Unnamed fields.  For example, "INT" or "INT _ 4".  These can only appear in the field lists of record tgn's.
should have an access!!!!!!!!!!!!!!
Operations on Fields
Looking Up Names
Return the frozen field list for the most deeply nested local context of rib.
Locally
LookupLocalName: PROC [lc: LocalContextNode, name: GEN.IdNode] RETURNS [FieldNode] = BEGIN
RETURN [LookupNameInFieldList[LocalContextFields[lc], name]];
END;

LookupNameInFieldList: PUBLIC PROC [fields: FieldListNode, name: GEN.IdNode] RETURNS [FieldNode] = BEGIN
FOR cell: FieldListCell _ fields.first, cell.next WHILE cell # NIL DO
IF Rope.Equal[cell.node.name.text, name.text] THEN RETURN [cell.node];
ENDLOOP;
RETURN [NIL];
END;

LocalContextFields: PROC [lc: LocalContextNode] RETURNS [FieldListNode] = BEGIN
WITH lc.contents SELECT FROM
c: REF unfrozen PT.LocalContextContentsBody => {
SIGNAL EH.Warning[0, "Tried to look up in an unfrozen l.c."];
RETURN [CreateEmptyFieldList[]];
this is crocked.  it should be fixed!!
};
c: REF frozen PT.LocalContextContentsBody => 
WITH c.block.body SELECT FROM
block: REF PT.BlockTGNBody			=> RETURN[block.ffl.cells];
module: REF PT.ModuleTGNBody		=> RETURN[module.ffl.cells];
ic: REF PT.InterfaceContentsTGNBody	=> RETURN[ic.ffl.cells];
ENDCASE									=> ERROR;
ENDCASE => ERROR;
END;
Anywhere Visible
LookupName: PROC [lc: LocalContextNode, name: GEN.IdNode] RETURNS [FieldNode] = BEGIN
WHILE TRUE DO
res: FieldNode _ LookupLocalName[lc, name];
IF (res # NIL) OR (lc.parentRib = NIL) THEN RETURN[res];
this needs to also look in "open" lists, not just the field lists
lc _ lc.parentRib.lc;
ENDLOOP;
ERROR; -- just to make the compiler happy; we never get here...
END;

man, this is braindamaged. we really want something to walk the path after we build it!!
LookupTypeNameInLocalContext: PUBLIC PROC [lc: LocalContextNode, id: GEN.IdNode] RETURNS [TypeGraphNodeNode] = BEGIN
f: FieldNode _ LookupName[lc, id];
SELECT TRUE FROM
f = NIL => {
ERROR EH.FatalError[id.position, IO.PutFR["Undeclared type name %g", IO.rope[id.text]]];
maybe dummy something up so we can proceed?
};
NOT ISTYPE[f, REF typeDecl FieldNodeBody] => {
ERROR EH.FatalError[id.position, IO.PutFR["%g does not name a type", IO.rope[id.text]]];
maybe dummy something up so we can proceed?
};
ENDCASE => NULL;
RETURN [NARROW[f, REF typeDecl FieldNodeBody].type];
END;

LookupTypeNameInContextTree: PUBLIC PROC [ct: ContextTreeNode, id: GEN.IdNode] RETURNS [TypeGraphNodeNode] = BEGIN
RETURN [LookupTypeNameInLocalContext[ct.rib.lc, id]];
END;

LookupVariableOrConstantName: PUBLIC PROC [lc: LocalContextNode, id: GEN.IdNode] RETURNS [ValueNode] = BEGIN
This will have to assemble stack lookup code, and use this code to synthesize the returned value.  In the meantime, we'll just return trash unless it's a static constant.
Naw, let's bogus up some code for now...
f: FieldNode _ LookupName[lc, id];
IF f = NIL
THEN {
ERROR EH.FatalError[id.position, IO.PutFR["Undeclared variable name %g", IO.rope[id.text]]];
maybe dummy something up so we can proceed?
}
ELSE WITH f SELECT FROM
ff: REF typeDecl FieldNodeBody => {
ERROR EH.FatalError[id.position, IO.PutFR["%g does not name a variable", IO.rope[id.text]]];
maybe dummy something up so we can proceed?
};
ff: REF constant FieldNodeBody => {
IF ff.value.kind = static
THEN RETURN[ff.value]
ELSE {
pfd: ParameterizedFieldDescriptorNode _ GetPathToName[lc, id].pfd;
code: BD.ProgramGraphNode _ IF PGD.PFDIsLocal[pfd]
THEN PGD.MakePGLoadLocal[pfd]
ELSE PGD.MakePGLoadIndirect[pfd];
RETURN[NEW[ValueNodeBody _ [runtime[code, ff.type]]]];
I think we ultimately want an lvalue-used-as-rvalue lookup function.  ALso think about assignments to a field of a constant record.  
};
};
ff: REF variable FieldNodeBody => {
pfd: ParameterizedFieldDescriptorNode _ GetPathToName[lc, id].pfd;
code: BD.ProgramGraphNode _ IF PGD.PFDIsLocal[pfd]
THEN PGD.MakePGLoadLocal[pfd]
ELSE PGD.MakePGLoadIndirect[pfd];
RETURN[NEW[ValueNodeBody _ [runtime[code, ff.type]]]];
};
ENDCASE => ERROR;
END;

loop through fields and indices now.  only if everything is static will we return a static value.  all other cases we return a runtime value.
�‌تK��ک�ڑœ™Jڑœ<™<Jڑœ#دk™&Jڑœ-‌™0Icodeڑœ,™,K™)K™:—Ibodyڑœ‹™‹Jک�ڑ‌	ک	Jک<Jک9Kڑ‌œ‌œ4ک<Kڑ‌œ‌œ‌œک&Kڑœ‌œ‌œ
ک&Kڑœ‌œک)Jڑœ
‌œmکJڑœ‌œپک•Jڑœ‌œک(Jڑœ‌œکKڑœ‌کJڑœ‌œ-کGJڑœ‌œک-Jڑœ
‌œWکiJڑœ ‌œpک•Kڑœ‌œک5Kڑœ‌œک&Kڑœ‌œ,ک<Kڑœ‌œ
ک%—Jک�ڑدnœ‌œ‌ک)Kڑ‌œ
‌œ‌œ‌œ}ک¦Kڑ‌œ0‌ک<ڑ‌œکJڑ‌œکJڑ‌œکJڑ‌œکJڑ‌œکJڑ‌œکJڑ‌œ"ک$Jڑ‌œکJڑ‌œک Jڑ‌œک—J™�JڑœŒ™Œheadڑدz™Jک�ک�K™ï—ڑ
‍œ‌œ‌œ‌œ‌œکNKڑœ‌œکKڑœ‌œ‌œکKڑœ‌œ	کKڑœ,ک,Kڑœ‌œ‌œ$ک;Kڑœ)ک)Kک�ڑ‌œ‌œ‌کKڑ‌œ‌œ<کD—Kڑ‌œ‌œ4ک=Kڑœ‌œ;کHKڑ‌œ
کKڑœ‌œکKڑ‌œ$ک*ڑœکKک�K™JK™YK™J——ڑ‍œ‌œ‌œ
‌œ‌œ‌œ‌œ‌œ‌œ‌œ‌œکvKڑ‌کKڑœ‌œکKڑœFکFKڑœ ک Kک�Kڑ‌œ‌œ‌œک/Kک+Kڑ‌œ‌œ‌œ
‌œ‌œ‌œ‌œک[KڑœIکIڑ‌œ-‌œ‌œ‌ک>Kڑœ‌œک)Kڑœ‌œکKڑœ‌œکKڑœ
‌œکKڑœ‌œکKڑœ‌œک0Kڑœ2ک2Kڑœ‍œک#Kڑ‌œ‌œ‌œ
‌œ‌œ‌œ‌œ	کMKڑ‌œک—Kڑ‌œکKک�—ک�Kک�—Jک�——ڑں™Kڑœ‌œ‌œک0Kڑœ‌œ‌œ‌œک:Kک�Kڑœ‌œ‌œک2ڑœ‌œ‌œ‌œک<Kک�—ڑ‍œ‌œ‌œ‌œکAKڑœ‌œ‌œ‌œک=Kڑ‌œکKڑœکKک�—Kڑœ™ڑ
‍'œ‌œ‌œ'‌œ‌œک“ڑœ%‌œک@Kڑœ‌œک$—ڑ‌œ‌œکKڑ‌œ)ک-Kڑ‌œ.ک2—Kڑœ(ک(Kڑ‌œکKکKک�—ڑ‍*œ‌œ‌œ'‌œ‌œ‌œک¯ڑœ%‌œک@Kڑœ‌œک)—ڑ‌œ‌œکKڑ‌œ)ک-Kڑ‌œ.ک2—Kڑœ(ک(Kڑ‌œکKکKک�—ڑ
‍œ‌œ‌œ'‌œ‌œکnKڑœ;ک;ڑ‌œ‌œ‌کڑ‌œ0ک2Kڑ‌œ‌œک*Kڑ‌œ*ک.—Kڑ‌œک—Kڑ‌œ‌œکKڑœکKک�—ڑ
‍œ‌œ‌œ'‌œ‌œ	‌œ‌کŒKڑœFکFKڑ
‌œ‌œ‌œ‌œ‌œ5کWK™Kڑ‌œDکJKڑ‌œکKک�Kک�—ڑ
‍œ‌œ‌œ'‌œ‌œ‌œ‌™گKڑœF™FKڑ
‌œ‌œ‌œ‌œ‌œ™'KڑœI™IK™�Kڑ‌œ™K™�—ڑ‍œ‌œ‌œ'‌œ‌œ‌œکbKڑ‌œ*‌œک5Kڑœک—ک�K™—Kڑ
ذbnœ‌œ‌œ‌œ‌œکdKک�ڑں
™
K™�Kک�Kڑœ‌œ‌œک*Kڑœ‌œ‌œ‌œک4ک�Kڑœع™عKڑœt™tK™�Kڑ‍œ…™‰—ڑ‍œ‌œ‌œ-‌œ™zK™2Kڑœ0دc™Hڑ
‍œ‌œ‌œ&‌œ‌œ™PKڑœ‌œ	،™0K™2K™—K™)Kڑ‌œ‌œ-™7K™—Kک�ک�Kڑœ(™(—ڑ‍œ‌œ‌œ‌œ/™oڑ
‍œ‌œ‌œ&‌œ‌œ™JKڑœ‌œ	™!Kڑœ™—Kڑœ$™$K™—Kک�ڑ
‍œ‌œ‌œ‌œ‌œ4™†Kڑœ‌œ‌œ™K™:Kڑ‌œ	‌œ	™K™—Kک�K™�Kک�Kک�—Kک�ڑں
™
Jڑœ‌œ‌œک0Jڑœ‌œ‌œ‌œک:Jک�Jڑœ‌œ‌œکJڑœ‌œ‌œ‌œک(Jک�Jک�Jڑذbkœ‍™£Kک�Kڑ‍œ‌œ‌œ‌œ‌œ‌œ‌œ‌œکŒک�Kڑœ™—ڑ
‍œ‌œ‌œ‌œ‌œکpKک�Kڑœ
™
—ڑ‍œ‌œ‌œ3‌œکvKڑœ‌œ‌œک.ڑ‌œ#‌œک*Kڑ‌œ‌œVک^—Kڑ‌œ‌œ‌œ‌œکXKکKڑ‌œکKکKک�—ڑ‍œ‌œ‌œ‌œکDKڑ‌œکKک——ڑں™Jڑœ‌œ‌œک.Jڑœ‌œ‌œ1کPJک�Jڑœ‌œ‌œک/Jک�ڑ‍œ‌œ‌œ7‌œکyKڑœ‌œ‌œ0کDKڑ‌œ‌œک(Kک——ڑں™Jڑœ‌œ‌œک2Jڑœ‌œ‌œ‌œک<Jک�Jڑœ‌œ‌œک:Jڑœ‌œ‌œک=Kک�ڑ
‍œ‌œ‌œ'‌œ‌œکoڑœ‌œک4Kڑœکڑœکڑ‌œ‌œ‌œ
ک!Kڑ‌œکKڑ‌œ&ک*——Kڑœ
‌œ‌œ)ک9Kک—ڑœ‌œ
‌œک'Kڑ‌œکKڑ‌œک!—Kڑ‌œکKکKک�—ڑ	‍	œ‌œ‌œ‌œ‌کNKڑ‌œکKڑ‌œک—Kک�ڑ‍œ‌œ‌œ‌œ&کcKک�—ڑ	‍œ‌œ‌œ‌œD‌کژKک�Kڑœ‌œکKڑœ‌œکKڑœ‌œکKک�Kڑœ*‌œ‌œک5Kک�Kک+Kک�Kڑœ‌œ‌œ‌œک1Kڑœدsœ‌œ‌œ&کHKڑœ£œ‌œ‌œ&کJKڑœ£œ‌œ‌œ(کJKڑœ£	œ‌œ‌œ(کNKڑœ£	œ‌œ‌œک;Kڑœ£œ‌œ‌œک?Kڑœ£œ‌œ‌œک5Kڑœ£œ‌œ‌œک=Kک�Kڑœ$™$Kڑœ£œ‌œک7Kڑœ£œ‌œ
ک5Kڑœ£œ‌œ
ک5Kڑœ£œ‌œ
ک5Kڑœ£œ‌œ™,Kڑœ£œ‌œ™-Kک�Kڑœ£œ‌œک4Kڑœ£œ‌œک7Kڑœ£œ‌œ
ک4Kڑœ£œ‌œ
ک4Kڑœ£œ‌œ
ک4Kک�Kڑœ£œ‌œ
ک4Kڑœ£œ‌œک6Kڑœ£œ‌œ
ک3Kڑœ£œ‌œ
ک3Kڑœ£œ‌œ
ک3Kڑœ£œ™+Kک�Kڑœ£œ‌œ	ک1Kڑœ£œ‌œ	ک2Kڑœ£œ‌œ
ک3Kک�ڑ‌کKڑœ/ک/Kڑœ7ک7KکKک#Kڑœ/ک/Kڑ‌œکKک�—Kڑ‌œکKک�—ڑ‍œ‌œ6‌œ‌œ‌œ‌کcKڑœ‌œ
‌œ‌œک?Kڑœ‌œک Kک1Kک-ڑœ,‌œ‌œکCKکKک!Kک
Kڑœ	‌œ،ک Kک—KڑœR‌œکWKک'Kڑ‌œکKک�—ڑ
‍œ‌œ6‌œ
‌œ	‌œ‌œ‌ک”ڑœ‌œ‌œ‌œک.Kڑœ/ک/—Kڑœ ک Kڑ‌œکKک�—Kک�Kک�——ڑں™Jڑœ‌œ‌œک<Jڑœ‌œ‌œ8ک^Jک�Jڑœ‌œ‌œک4Jڑœ‌œ‌œ4کVKک�ڑ
‍	œ‌œ‌œ‌œ‌œک^ڑœ‌œک$Kڑœ‌œک
KکKکKکKک—KکKکKکKک�—ڑ	‍œ‌œ‌œ‌œ‌کaKڑ‌œک
Kڑ‌œک—Kک�Kڑœ‌œ0‌œ)™aڑ‍
œ‌œ‌œ‌œ™ZKڑ‌œ™Kڑœ™—Kک�Kڑœ‌œ0‌œ)™aڑ‍
œ‌œ‌œ‌œ™WKڑ‌œ	™Kڑœ™—ک�Kڑœz™z—ڑ
‍œ‌œ‌œ‌œ	‌œ™oڑ‌œ(‌œ	‌œ‌™AKڑœ‌œ4™SKڑ‌œ‌œ‌œ‌œ™Kڑ‌œ‌œ‌œ‌œ™Kڑ‌œ™—Kڑ‌œ‌œT™\K™—ڑں™Jڑœ3™3——ڑں™Jڑœ‌œ‌œک$Jڑœ‌œ‌œک.Jک�ڑ
‍œ‌œ‌œ	‌œ
‌œکMKڑ‌œ‌œ%ک/KڑœکKک�—ڑ	‍œ‌œ‌œ‌œ‌ک@Kڑ‌œ‌œ‌œک.Kڑ‌œکKک�—ڑ‍	œ‌œ‌œ
‌œ‌œ‌کAKڑ‌œ‌œک)Kڑ‌œکKک�——ڑں™ڑں™ڑ
‍œ‌œ‌œ!‌œ>‌œ6ک¾Kڑœ‌œ‌œ‌œ/کJKڑ‌œک Kک——Mڑں™ڑں™ڑ‍œ‌œ‌œ9‌œ6ک‘Kڑœ‌œ‌œ‌œک7Kڑ‌œک Kک——ڑں™ڑ‍œ‌œ‌œ4کpK™CKڑœ‌œ
‌œ‌œک,Kڑ‌œک Kک——Mڑں™ڑں
™
ڑ
‍œ‌œ‌œ#‌œ ‌œ6ک§Kڑœ‌œ‌œ‌œ+کKKڑ‌œک Kک——ڑں™ڑ	‍œ‌œ‌œP‌œ5‌ک¯Kڑœ‌œ‌œ‌œGکdK™KKڑ‌œک Kڑ‌œکKک�—ڑ
‍œ‌œ‌œ+‌œ‌œ6ک•ڑœ‌œ‌œ‌œک/Kڑœ:‌œکH—Kڑ‌œک Kک—ک�Kڑœ!‌™$—ڑ
‍œ‌œ‌œ>‌œ‌œک§Kڑœ‌œ‌œ‌œک?Kڑ	œ‌œ‌œ‌œ*‌œکRڑ‌œ‌کKڑ‌œک"Kڑ‌œ#ک'—KڑœکKڑ‌œکKکKک�—ڑ	‍œ‌œ‌œ‌œ‌کGڑ‌œ‌œ‌œ‌ک&Kڑœ‌œ‌œک)Kڑ‌œک—ڑ‌œ
‌œ‌کڑœ‌œ
‌œک$Kڑ‌œک—ڑœ‌œ‌œک(Kڑ‌œ‌œ‌œک*—ڑœ‌œ‌œک+Kڑ‌œ‌œک)—ڑœ‌œ‌œک+Kڑ‌œ‌œ9کA—ڑœ‌œ‌œک*Kڑœ"‌œ‌œکMک*Kڑ‌œ@کDKڑ‌œک!—Kڑ‌œ‌œ"ک+Kک—ڑ‌œکKڑ‌œ‌œ&ک/Kڑ‌œ‌œکKک——ڑ‌œکKک�——ڑ	‍œ‌œ‌œ‌œ‌کFڑ‌œ‌œ‌œ‌ک&Kڑœ‌œ‌œک)Kڑ‌œک—ڑ‌œ
‌œ‌کڑœ‌œ
‌œک$Kڑ‌œک—ڑœ‌œ‌œک(Kڑ‌œ‌œ‌œک)—ڑœ‌œ‌œک*Kڑ‌œ‌œ!ک+—ڑœ‌œ‌œک+Kڑ‌œ‌œ8ک@—ڑœ‌œ‌œک*Kڑœ"‌œ‌œکMڑœ5ک5ڑœکKڑœکKڑœک—Kک—Kڑ‌œ‌œ"ک+Kک—ڑ‌œکKڑ‌œ‌œ%ک.Kڑ‌œ‌œکKک——ڑ‌œکKک�——Kک�—ڑں™ڑ‍œ‌œ‌œ‌œ
‌œ‌کmKڑ‌œ‌œ0ک8Kڑ‌œکKک�—ڑ
‍œ‌œ‌œ‌œ	‌œ™iK™$ڑ‌œ
‌œ‌™Kڑœ‌œ™Kڑ‌œ‌œ™—K™——ڑں
™
ڑ
‍œ‌œ‌œ‌œ
‌œ6ک‡Kڑœ‌œ‌œ‌œک;Kڑ‌œک Kک——ڑں™ڑ‍œ‌œ‌œ ‌œI‌œ‌œ6کطڑœ‌œ‌œ‌œک=KڑœAکA—Kڑ‌œک Kک——ڑں	™	ڑ‍œ‌œ‌œ ‌œ‌œ‌œ6ک©ڑœ‌œ‌œ‌œک3Kڑœ!ک!—Kڑ‌œک Kک——ڑں™ڑ‍œ‌œ‌œ9‌œ6ک‌Kڑœ‌œ‌œ‌œ(کOKڑ‌œک Kک——Mڑں™ڑں™ڑ
‍
œ‌œ‌œ#‌œ ‌œ6ک،Kڑœ‌œ‌œ‌œ%ک?Kڑ‌œک Kک——ڑں™ڑ‍
œ‌œ‌œ=‌œ6ک”Kڑœ‌œ‌œ‌œ!ک;Kڑ‌œک Kڑœک——Mڑں™ڑں™ڑ	‍œ‌œ‌œ7‌œ)‌کˆKڑœ‌œ
‌œ‌œک9Kڑ‌œک Kڑ‌œکKک�—ڑ	‍œ‌œ‌œJ‌œ‌™–K™1Kڑœ‌œ
‌œ™+Kڑœ™Kڑœ‌œ‌œ+™?Kڑ‌œ™Kڑ‌œ™——ڑں™ڑ‍œ‌œ‌œ‌œm‌œ)‌کقK™DKڑœ‌œ‌œ‌œ/کIKڑœ-ک-K™™Kڑ‌œ
کKڑ‌œکKک�Kک�—ڑ‍œ‌œ‌œ‌œm‌œ)‌™قK™DKڑœ‌œ‌œ‌œ/™IKڑœ-™-K™™K™EKڑœ;™;Kڑ‌œ‌œ9‌œ™XKڑ‌œ
™Kڑ‌œ™K™�K™�—K™�ڑ
‍œ‌œ‌œ‌œ ‌œ6™¥Kڑœ‌œ™3Kڑ‌œ‌œ‍œ(‌œ™XK™K™8Kڑ‌œ
™™K™�——ڑ‍œ‌œ‌œ‌œ!‌œ‌کpKڑœ
‌œ‌œک)Kڑœ‌œک7Kڑ‌œک
Kڑ‌œکKک�—ڑ	‍œ‌œ‌œ‌œ‌کdK™<Kڑ	œ‌œ‌œ‌œ‌œکMKڑœ
™
Kڑ‌œکKڑ‌œکKک�Kک�——ڑں™ڑ	‍œ‌œ‌œ‌œ‌کAK™wKڑ‌œ‌œک
Kڑ‌œک——ڑں™ڑ‍œ‌œ‌œ(‌œ#‌œ!‌œ6کشKڑœ‌œ‌œ‌œ@ک]Kڑ‌œک KکKک�—Jک�—Mڑں™ڑں™ڑ
‍œ‌œ‌œN‌œ‌œ6کثڑœ‌œ
‌œ‌œک.Kڑœ0ک0—Kڑ‌œک Kک——ڑں™ڑ
‍œ‌œ‌œ+‌œ#‌œ6ک«Kڑœ
‌œ‌œ‌œ"کDKڑœ‌œ
‌œ‌œ;کTKڑ‌œک KکKک�——Mڑں™ڑں™ڑ‍œ‌œ‌œ<‌œ6ک—Kڑœ‌œ‌œ‌œ$کBKڑ‌œک Kک——Mڑں™ڑںذkz™K™¤Kڑœo™oK™�Kڑœ‹‌œ™گKڑœ‌œa™™�K™6K™�K™=—ڑ
‍œ‌œ‌œ@‌œ	‌œ6ک²ڑ‌œ‌œ‌™$ڑœ™ڑ‌œ?™EK™-—Kڑœ™—ڑ‌œ™Kڑ	œ‌œ‌œ‌œ‌œ™RKڑ‌œ™ Kڑœ™——Kڑ	œ‌œ‌œ‌œ‌œکRKڑ‌œک Kڑœک—™�K™?—ڑ‍œ‌œ‌œS‌œ6ک¹Kڑ	œ‌œ‌œ‌œ"‌œکYKڑ‌œک Kڑœک——Mڑں™ڑں™ڑ‍œ‌œ‌œ‌œ‌œ,‌œ6کآڑœ‌œ‌œ‌œ‌ک(Kک%Kک%Kک)Kک'Kک+Kک+Kڑ‌œ‌œک—Kڑœ‌œ‌œ‌œ5کSKڑ‌œک Kک——ڑں™ڑ‍œ‌œ‌œ4کmK™CKڑœ‌œ
‌œ‌œ
ک&Kڑ‌œک Kک——Mڑں™ڑں™ڑ‍œ‌œ‌œ8‌œ6کژKڑœ‌œ
‌œ‌œک4Kڑ‌œک Kک——ڑں™Jڑœ‌œ‌œک,Jڑœ‌œ‌œ‌œک6Jک�ڑ‍œ‌œ‌œg‌œ6کإڑœ‌œ‌œ‌œک8KکKکKک—Kڑ‌œک Kڑœک—Kک�ڑ‍œ‌œ‌œ‌œکIڑ‌œ
‌œ‌کKڑœ‌œ‌œ‌œک)Kڑ‌œ‌œ‌œک—Kڑœک—Kک�ڑ‍œ‌œ‌œ‌œکYڑ‌œ
‌œ‌کKڑœ‌œ‌œک0Kڑ‌œ‌œک—Kڑœک—Kک�ڑ‍œ‌œ‌œ‌œک?Kڑ‌œ‌œ‌œ‌œک0Kڑœک—ک�K™
—ڑ
‍œ‌œ‌œ‌œ#‌œک‚Kڑ	œ	‌œ‌œ‌œ‌œکHKڑ‌œ‌œ‌œ‌œکJKکKکKڑ‌œکKڑœک—ک�K™—ڑ‍œ‌œ‌œ‌œکKKڑœ‌œ‌œ‌œ!کBKڑœ‌œک"ڑ‌œ‌œ‌œ‌ک%Kڑœ ک KکKڑ‌œک—Kڑ‌œکKڑœک——ڑں™ڑ
‍
œ‌œ‌œ$‌œ‌œ6ک…Kڑœ‌œ‌œ‌œک6Kڑ‌œک Kڑœک——ڑں™ڑ‍œ‌œ‌œ'™`Kڑœ‌œ™3Kڑœ‌œ™9K™K™#K™——ڑں#™#ڑ‍œ‌œ‌œ‌œ)‌œ‌œ™کK™*Kڑœ‌œ™3Kڑ‌œ‌œ‍œ‌œ™KK™AKڑ‌œ™™K™�——ڑ‍œ‌œ‌œ|‌œ™آKڑœ‌œ
™)K™K™K™Kڑ‌œ™K™—Kک�ڑدbœ‌œ‌œ‌œ)‌œ‌œ™«K™2ڑ‌œ‌œ‌™Kڑœ‌œ‌œ™!Kڑœ‌œ+™1Kڑœ‌œ+™1Kڑ‌œ™—Kڑ‌œ™K™—ک�K™9—ڑ‍œ‌œ‌œکLKڑ‌کKڑœکڑ‌œ‌œ‌ک
ڑ‌œ‌œ‌کKڑœ‌œ ک-Kڑ‌œ‌œک—Kڑ‌œک—Kڑ‌œکKڑ‌œک——ڑں™KڑœE™EK™�Kڑœ ™ K™�—ڑں
™
Kڑœ²™²K™�—ڑں™ڑ
‍œ‌œ‌œ+‌œ‌œ6™•Kڑœ‌œ9‌œ‌œ™WKڑ‌œ™ K™—™�Kڑœ!‌™$—ڑ
‍œ‌œ‌œ>‌œ‌œ™ھKڑœ‌œ™!Kڑœ‌œ+‌œ™Lڑ‌œ‌™Kڑ‌œ™Kڑ‌œ™"—K™Kڑ‌œ™K™——ڑں"™"Kڑœ‌œ‌œ™$ڑœ‌œ‌œ,™FK™�—Kڑœ‌œ‌œ™,Kڑœ‌œ‌œ0™NK™�Kڑœ‌œ‌œ™8Kڑœ‌œ‌œ6™ZK™�Kڑœ‌œ,™?K™�ڑ‍œ‌œ‌œ‌œd‌œ‌œ‌œ2™نK™�—ڑ‍œ‌œ‌œ5‌œ‌œ‌œ‌œ‌œ‌œ™¯K™�—Kڑ‍œ‌œ‌œ‌œ‌œ‌œ‌œ‌œ‌œ™€K™�Kڑ‍œ‌œ‌œ‌œ‌œ‌œ‌œ‌œ‌œ™wK™�ڑ‍œ‌œ‌œ+‌œ™xKڑ‌œ‌œ‌œ™K™K™Kڑ‌œ‌œ‌œ™-K™"K™Kڑ‌œ™K™—K™�ڑ‍œ‌œ‌œ‌œ™wKڑ‌œ‌œ‌œ™Kڑ‌œ‌œ‌œ‌œ™KK™K™"K™Kڑ‌œ™K™—K™�ڑ‍œ‌œ‌œ%‌œ™kKڑœ‌œ‌œ™9Kڑ‌œ&™,K™—K™�ڑ‍œ‌œ‌œ%‌œ™jKڑœ‌œ‌œ™9Kڑ‌œ%™+K™K™�—ڑ‍œ‌œ‌œ1‌œ™uKڑœ‌œ‌œ™;Kڑ‌œ0™6Kڑœ™K™�—ڑ‍œ‌œ‌œ1‌œ™tKڑœ‌œ‌œ™;Kڑ‌œ/™5K™—K™�ڑ‍œ‌œ‌œ‌œ™[Kڑ‌œ	‌œ	‌œ‌œ™!Kڑ‌œ‌œ‌œ‌œ™(Kڑ‌œ‌œ‌œ‌œ™(K™"K™K™(K™%Kڑ‌œ™K™K™�—ڑ‍œ‌œ‌œ-‌œ8™ˆK™#Kڑœ‌œ&™/K™K™K™K™ڑ‌œ‍œ‌œ‌œ‌œ
‌™.ڑœ	‌œ‌œ‌™#Kڑœ@‌œ™EKڑœ%‌œ‌œ‌œ‌œ‌œ
™FKڑ‌œ‌œ™—K™Kڑ‌œ™—ڑ	‌œ‍œ‌œ‌œ‌™&ڑ‌œ
‌™ڑœ	‌œ‌œ™/ڑ‌œ‌œ‌œ‌™8Kڑ‌œ‌œ،'™3—K™—ڑœ‌œ‌œ™#ڑ‌œ‌œ‌œ‌™8Kڑ‌œ‌œ،'™3—K™—Kڑ‌œ‌œ™—Kڑ‌œ™—Kڑ‌œ
™K™——ڑں™Jڑœ‌œ‌œک4Jڑœ‌œ‌œ4کVKک�ڑ‍œ‌œ‌œ‌œ‌œ‌œ4کˆKک�—Kڑ‍œ‌œ‌œ‌œ‌œ‌œ4کˆKک�Kڑ‍œ‌œ‌œ‌œ;‌œ‌œ‌œFکـ—ڑں
™
Jڑœ
‌œ‌œک(Jڑœ‌œ‌œ.کJJک�ڑ‍œ‌œ‌œ!‌œ‌œp‌œ6ک‎Kڑœ‌œCکZKڑ‌œک Kڑœک——Mڑں¤™Mڑں	¤™Mڑں¤™ڑں
¤™
Kڑœا™اK™�Kڑœ³™³Kک�ڑ‍œ‌œ‌œ‌œ6™{Kڑœ‌œ‌œ™QKڑ‌œ™ Kڑœ™K™�Kڑœ
™
—ڑ
‍œ‌œ‌œ5‌œ<‌œ™¹Kڑœ‌œ
™&ڑ‌œ‌œ‌œ@™VKڑœ‌œ½™خ—Kڑ‌œ™K™—Kک�ڑ‍œ‌œ‌œ.‌œ6™—ڑ‍œ‌œ‌œ?™WKڑœ_™_Kڑœ™—Kڑœ(™(K™ Kڑ‌œ™K™—Kک�ڑ
‍œ‌œ‌œ‌œ‌œ$™xJڑ‌™Jڑœ‌œ‌œ™Jڑœ™Jڑœ3™3Jڑ
‌œ	‌œ‌œ‌œ	‌œ	™2J™Jڑ‌œ™—Kک�Kک�Kک�ڑ
‍œ‌œ‌œ‌œ ‌œ™گKڑœ‌œ
™&Kڑœ‌œ‌œ™K™K™AKڑ‌œ‌œ‌œ‌œ‌œ‌œ
™aKڑ‌œ‌œK™SK™—K™�ڑ‍"œ‌œ‌œ‌œ!™sKڑœ‌œ
™&ڑ	œ
‌œ‌œ&‌œ‌œ™KKڑ‌™Kڑ
‌œ‌œ‌œ‌œ‌œ	™`Kڑ‌œ™—K™+K™K™�—Kڑœ6‌œ™BK™�Kڑœ‌œ™Kڑ
‍œ‌œ‌œ‌œ&‌œ(ک“ڑ
‍œ‌œ‌œ‌œ&‌œ™‡K™]ڑ‌œ‌œ‌™Kڑœ‌œ™Kڑ‌œ‌œ™—K™†Kڑ‌œ™K™—™�Kڑœ‌œ™—Kڑ	‍
œ‌œ‌œ;‌œ‍ک†ڑ‍
œ‌œ‌œ;‌œ™zڑ‍œ‌œ	‌œ$™OKڑœ>‌œ/™pKڑœ&‌œg™گK™—Kڑœ^™^Kڑ‌œ™K™—Kک�—ڑں™™
Kڑœ ‌œO™r—ڑ
‍
œ‌œ‌œO‌œ‌œ2™®Kڑ‌™Kڑ‌œ‌œ‌œ‌œ‌œ،#™FKڑ‌œ‌œ$™@Kڑ‌œ™——ڑں™Kڑœ‌œ‌œک$Kڑœ‌œ‌œ,کFKک�ڑ‍œ‌œ‌œ=‌œ2ک’Kڑ‌کKڑœ‌œ!ک6Kڑ‌œک Kڑ‌œک——ڑں™Jڑœ‌œ‌œک$Jڑœ‌œ‌œ,کFKک�ڑ
‍œ‌œ‌œ‌œ‌œکvKک�—Kڑ
‍œ‌œ‌œ‌œ-‌œکŒK™�ڑ‍œ‌œ‌œ‌œ,کhKک"Kڑ‌œ‌œ(ک6Kک——ڑں™Kڑœ‌œ+™=K™�ڑ‍œ‌œ‌œ™>Kڑœ‌œ‌œ™$Kڑ‌œ™Kڑœ™—K™�ڑ‍œ‌œ‌œ=™wK™*Kڑœ™ڑ‌œ‌™#Kڑ‌œ‌œ!‌œ‌œ™Z—Kڑœ
‌œ5™BK™Kڑœ™K™�—ڑ‍œ‌œ‌œ)‌œ™tKڑœ™ڑ‌œ‌™#Kڑ‌œ‌œ!‌œ‌œ™Z—ڑ‌œ	™Kڑ‌œ‌œ0‌œ™HKڑ‌œ‌œ0‌œ™I—K™Kڑœ™—K™�ڑ‍œ‌œ‌œ‌œ‌œ‌™VKڑ	œ‌œ¥œ¥œ‌œ™;K™ڑ‌œ
‌œ‌™Kڑ‌œ‌œ‌œ‌œ‌œ‌œ™MK™Kڑ‌œ™—Kڑ‌œ‌œ™Kڑ‌œ™K™�—ڑ	‍œ‌œ‌œ‌œ5‌™‚Kڑœ¥œ¥œ¥œA¥œ,¥œ¥œ
‌œ‌œ™»K™ڑ‌œ
‌œ‌™ڑ‌œ‌œ‌œ‌œ™@ڑ‌œ‌œ‌œ™ڑœ‌œ™Kڑ‌œ™—ڑœ‌œ™ Kڑ‌œ‌œ"‌œ‌œ™Y—Jڑ‌œ™——K™Kڑ‌œ™—Kڑ‌œ‌œ‌œ™Kڑ‌œ™K™�—ڑ	‍œ‌œ‌œ‌œ5‌™†Kڑœ¥œ¥œ¥œA¥œ,¥œ¥œ
‌œ‌œ™»K™ڑ‌œ
‌œ‌™ڑ‌œ‌œ‌œ‌œ™@ڑ‌œ‌œ‌œ™ڑœ‌œ™Kڑ‌œ™—ڑœ‌œ™ Kڑ‌œ‌œ"‌œ‌œ™Y—Jڑ‌œ™——K™Kڑ‌œ™—Kڑ‌œ‌œ‌œ™Kڑ‌œ™K™�—ڑ‍œ‌œ‌œ‌œ
™OK™ڑ‌œ
‌œ‌™Kڑ
‌œ‌œ‌œ‌œ‌œ™MK™Kڑ‌œ™—Kڑ
‌œ‌œ‌œ1‌œ‌œ™iKڑœ™—K™�ڑ‍œ‌œ‌œ‌œ‌œ&‌œ‌œ™yK™ڑ‌œ
‌œ‌™ڑ‌œ‌œ‌™Kڑœ‌œ8™@Kڑœ‌œ‌œ™%Kڑ‌œ™—K™Kڑ‌œ™—Kڑœ™K™�—ڑ‍œ‌œ‌œX‌™{K™ڑ‌œ
‌œ‌™ڑ‌œ‌œ‌™Kڑœ‌œ=™EKڑœ‌œF™NKڑœ‌œA™IKڑ‌œ™—K™Kڑ‌œ™—Jڑ‌œ™K™�—ڑ‍œ‌œ‌œX‌™€K™ڑ‌œ
‌œ‌™ڑ‌œ‌œ‌™Kڑœ‌œ=™EKڑœ‌œF™NKڑœ‌œA™IKڑ‌œ™—K™Kڑ‌œ™—Kڑ‌œ™——ڑں™Jڑœ‌œ‌œک.Jڑœ‌œ‌œ1کPKک�ڑ
‍
œ‌œ‌œ‌œ‌œ™`ڑ‌œ‌œ™"ڑ‌œ‌œ‌™K™K™K™K™!K™#Kڑ‌œ‌œ™—K™—K™—ڑ
‍
œ‌œ‌œ
‌œ‌œک[ڑ‌œ‌œک"ڑ‌œ‌œ‌کKکKکKکKک!Kک#Kڑ‌œ‌œک—Kک—Kک—Kک�ڑ‍œ‌œ‌œ‌œک:Kڑ‌œ‌œکKڑœک——ڑں™Kڑœ‌œ‌œک0Kڑœ‌œ‌œ2کRKک�ڑ‍œ‌œ‌œ-‌œکgKڑ‌œ‌œ)ک3Kڑœک—Kک�ڑ‍œ‌œ‌œ‌œک9Kڑ‌œ‌œکKڑœک——ڑں™Jڑœ‌œ‌œک,Jڑœ‌œ‌œ0کNKک�ڑ‍œ‌œ‌œ‌œ8‌œ‌œکژKڑœ‌œ1کIڑœ‌œ‌œ‌کKک'Kک%Kڑ‌œ‌œک—ڑœ‌œ‌œ‌کKک(Kک&Kڑ‌œ‌œک—Kڑ‌œکKک—Kک�Kڑ‍
œ‌œ‌œ‌œ‌œ‌œکD—ڑں™Jڑœ‌œ‌œک,Jڑœ‌œ‌œ0کNJک�ڑ
‍œ‌œ‌œ‌œ‌œکJڑ‌œ‌œ‌کJڑœ‌œ‌œ™BJڑœ‌œ‌œ کFJڑœ‌œ‌œکDJڑ‌œ‌œ‌œ`کs—JڑœکJک�—ڑ‍
œ‌œ‌œ‌œک<Jڑ‌œ‌œکJڑœکJک�—ڑ¥œ‌œ‌œ‌œکOJڑ‌œکJڑœک——ڑں™Jڑœ‌œ‌œ™*Jڑœ‌œ‌œ/™LK™�Kڑœ‰™‰Kک�Kڑœ™K™�ڑ
‍œ‌œ‌œ	‌œ
‌œ™GKڑ‌œ‌œ%™/Kڑœ‍™Kڑœ™K™�—Kک�ڑ‍œ‌œ‌œ‌œ‌œ‌œ™EKڑœ‍™!——ڑں
™
Jڑœ‌œ‌œک.Jڑœ‌œ‌œ1کPK™�Kڑœ™Kڑ‍
œ‌œ‌œ	‌œ‌œ‌œ‌œ"ک}Kک�Kڑ‍œ‌œ‌œ‌œ‌œ‌œ
ک^—M™�Mڑں™Kڑœ‌œ‌œک2Jڑœ‌œ‌œ3کTJک�ڑ
‍œ‌œ‌œ	‌œ‌œکUKڑœ‌œ‌œ ک+Kک�—ڑ
‍
œ‌œ‌œ‌œ‌œکPKڑœ‌œ
کKک�—Jک�—ک�ڑںœ™Kڑœ‌œ‌œک2Jڑœ‌œ‌œ3کTKک�ڑ
‍œ‌œ‌œ	‌œ‌œکUKڑœ‌œ‌œ ک+Kک�Kک�—ڑ
‍
œ‌œ‌œ‌œ‌œکPKڑœ‌œ
ک——ڑںœ™Kڑœ‌œ‌œک2Jڑœ‌œ‌œ3کTKک�ڑ	œ‌œ‌œ	‌œ‌œکUKڑœ‌œ‌œ ک+Kک�Kک�—ڑ	œ‌œ‌œ‌œ‌œکPKڑœ‌œ
ک——ڑںœ™Kڑœ‌œ‌œک@Jڑœ‌œ‌œ:کbKک�ڑ	œ‌œ‌œ	‌œ‌œکjKڑœ‌œ‌œ'ک2Kک�Kک�—ڑ	œ‌œ‌œ#‌œ‌œکeKڑœ‌œ
ک——ڑںœ™Kڑœ‌œ‌œک:Jڑœ‌œ‌œ7ک\Kک�ڑ	œ‌œ‌œ	‌œ‌œکaKڑœ‌œ‌œ$ک/Kک�Kک�—ڑ	œ‌œ‌œ ‌œ‌œک\Kڑœ‌œ
ک——ڑں™Kڑœ‌œ‌œک2Kڑœ‌œ‌œ3کTKک�ڑ‍œ‌œ‌œ‌œک:ڑœ‌œ‌œ‌œک*Kک�——ڑ
‍œ‌œ‌œ‌œ‌œکiKڑœ‌œ‌œ‌œک6——ڑں	™	Kڑœ‌œ‌œ™%Kڑœ‌œ,™?J™�Jڑœ‌œ‌œ‌œ)™XK™�ڑ‍œ‌œ‌œ™4Kڑ‌™Jڑœ‌œ‌œ™!Jڑ‌œ™Jڑ‌œ™—K™�ڑ
‍œ‌œ‌œ‌œ‌œ™EKڑ‌™Jڑœ‌œ$™9Jڑ
‌œ‌œ‌œ‌œ‌œ<™nJ™Jڑ‌œ™—K™�ڑ‍œ‌œ‌œ‌œ‌œ‌œ™HKڑ‌™J™ڑ‌œ‌œ‌™Jڑ‌œ‌œ‌œ
™7J™Jڑ‌œ™—Jڑ‌œ‌œ™ڑ‌œ™J™�——ڑ‍œ‌œ‌œ‌œ‌œ‌œ‌œ™JJڑ‌™J™ڑ‌œ‌œ‌™J™J™Jڑ‌œ™—Jڑ‌œ™——ڑں(™(Kڑ‍œ‌œ‌œ‌œک!——ڑں™ڑں™Jڑœ‌œ‌œک8Jڑœ‌œ‌œ‌œکBJک�Jڑœ‌œ‌œک,Jڑœ‌œ‌œ‌œک6Jک�Jڑœ‌œ‌œک,Jڑœ‌œ‌œ‌œک6Jک�Jڑœ‌œ‌œک$Jڑœ‌œ‌œ‌œک.—ڑں™ڑ‍œ‌œ‌œ‌œک=Kڑœ‌œ‌œ‌œ‌
œ‌œک>Kک�—ڑ‍œ‌œ‌œ‌œکPKڑœ‌œکKک�—Kڑ‍œ‌œ‌œ‌œ‌œ‌œ‌œ‌œ‌œکxJک�ڑ	‍œ‌œ‌œ#‌œ‌کjKڑœ‌œ‌œک<ڑ
‌œ‌œ‌œ‌œ+‌œ	‌œ‌کZڑ‌œ9‌œکAJڑ‌œ‌œ#‌œ!‌œ کqJڑ‌œکJک—Jڑ‌œک—ڑ‌œ‌کJڑ‌œکJڑ‌œک—JڑœکJڑ‌œکJڑ‌œکKک�—ڑ	‍œ‌œ‌œ‌œ‌ک[Kڑœ‌œکKڑ
‌œ+‌œ	‌œ‌œ‌œکWKڑœ‌œ‌œ
ک4Kڑ‌œک——ڑں™™KLڑœ%‌œ‌œ@™oLڑœ!‌œ@™dLڑœ$‌œ	‌œK™~Lڑœ#‌œ‌œA™p—Jک�ڑ‍œ‌œ‌œ‌œv‌œ‌ک½Jڑ
œ‌œ‌œ
‌œ‌œ‌œ‌œکEJڑ‌œ‌œEکOJڑ‌œکJک�—ڑ‍œ‌œ‌œ‌œ<‌œ‌ک€Jڑ‌œ‌œ1ک;Jڑ‌œکJک�—ڑ‍œ‌œ‌œ‌œں‌œ‌کهJڑœMکMJڑ‌œ‌œ_کiJڑ‌œکJک�—ڑ‍œ‌œ‌œ‌œں‌œ‌کهJڑ‌œ‌œXکbJڑ‌œکJک�—ڑ‍œ‌œ‌œ‌œl‌œ‌ک¯Jڑ‌œ‌œGکQJڑ‌œکJک�—ڑ	‍œ‌œ‌œ3‌œ‌کmJڑ
‌œ‌œ‌œ‌œ‌œکHJ™#Jڑ‌œک—Jک�—ڑں™ڑ‍œ‌œ‌œ&‌کiڑ‌œ‌œ‌کJڑœ‌œ‌œک=Jڑ
‌œ‌œ‌œ‌œ"‌œکk—Jڑ‌œکJک�—ڑ	‍œ‌œ‌œ‌œJ‌ک†ڑ‌œ‌œ‌کJڑœ‌œ‌œ2کZJڑ
‌œ‌œ‌œ‌œ&‌œکo—ڑ‌œکJک�——ڑ‍œ‌œ‌œ‌œ=‌œ‌کژڑ‌œ‌œ‌کJڑœ‌œ‌œ(‌œکVJڑœ‌œ‌œ(‌œکWJڑ
‌œ‌œ‌œ‌œ2‌œک{—ڑ‌œکJک�——ڑ‍œ‌œ‌œ‌œ‌œ‌کAJڑ‌œ‌œکJڑ‌œکJک�—ڑ	‍	œ‌œ‌œ‌œ‌کMڑ‌œ‌œ‌œ‌کJڑœ‌œ"ک(Jڑœ‌œ!ک'Jڑœ‌œ"ک(Jڑœ‌œ"ک(Jڑœ‌œ%ک+Jڑ‌œ‌ک—JکJڑ‌œکJک�—Jک�—ڑں™ڑ	‍œ‌œ‌œ	‌œ‌کhڑ‌œ/‌œ‌œ‌کEJڑ‌œ,‌œ‌œ
کFJڑ‌œک—Jڑ‌œ‌œک
Jڑ‌œکJک�—ڑ	‍œ‌œ‌œ‌œ‌کgڑ‌œ‌œ‌کJک?Jڑœ:ک:Jڑ‌œ	‌œ‌œ‌œ	ک#JکJڑ‌œک—Jڑ‌œ‌œک
Jڑ‌œکJک�—ڑ‍œ‌œ‌œ‌کgJ™Mڑ‌œکڑ‌œ‌œ‌ک ڑœ‌œ&ک,Jڑ‌œ‌œOکW—ڑœ‌œ#ک)ڑ‌œ‌œ‌کJڑœ‌œ‌œک*Jڑœ‌œ‌œک,Jڑœ‌œ‌œ$ک.ڑ‌œکJڑ‌œ‌œ4ک<———Jڑ‌œ‌ک—Jک—Jڑ‌œکJک�—ڑں™ڑ	‍œ‌œ‌œ	‌œ‌™ZJڑ‌œ7™=Jڑ‌œ™J™�—ڑ	‍œ‌œ‌œ	‌œ‌™hڑ‌œ/‌œ‌œ‌™EJڑ‌œ,‌œ‌œ
™FJڑ‌œ™—Jڑ‌œ‌œ™
Jڑ‌œ™J™�—ڑ‍œ‌œ‌œ‌™Oڑ‌œ
‌œ‌™ڑœ‌œ
‌œ™0Jڑ‌œ‌œ4™=Jڑ‌œ™ J™&J™—ڑœ‌œ‌œ™-ڑ‌œ‌œ‌™Jڑœ‌œ‌œ‌œ™8Jڑœ‌œ‌œ‌œ™:Jڑœ‌œ‌œ‌œ™<Jڑ‌œ‌œ™——Jڑ‌œ‌œ™—Jڑ‌œ™——ڑں™Jڑœ"‌œ‌œ&کRJڑœ&‌œ‌œ‌œ&ک\Jک�ڑ	‍
œ‌œ‌œ	‌œ‌™Uڑ‌œ‌œ‌™
Jڑœ+™+Jڑ‌œ‌œ‌œ‌œ‌œ‌œ™8J™AJ™Jڑ‌œ™—Jڑ‌œ،8™?Jڑ‌œ™J™�—ڑ‍
œ‌œ‌œ‌œ	‌œC‌ک’Jڑœ"،کAJڑœ8ک8Jڑœ‌œکڑœ‌œ	‌œکJڑ
‌œ‌œ‌œ‌œ‌œکXڑ‌œ‌œ‌œ‌کJ™XJڑœ‌œ"ک(Jڑœ‌œ"ک(Jڑ‌œ‌œک——ڑ‌œ‌œ‌ک
JکBJڑœ8ک8ڑ‌œ‌œک
ڑ‌œ‌œ‌کJڑ
‌œ‌œ‌œ‌œ‌œکYJڑ‌œ‌œک&—ڑ‌œکJڑœ‌œ"ک+Jڑ‌œکJک—Jک—Jڑ‌œک—Jڑ‌œک—Jک�ڑ	‍œ‌œ‌œ	‌œ‌™tJڑœ"™"ڑ‌œ‌œ‌™ڑœ‌œ™Jڑ‌œ‌œ‌œ"‌œ™XJڑœ+™+J™—ڑ‌œ‌œ‌œ™.Jڑ‌œ‌œ‌œ"‌œ™XJڑœ+™+J™—Jڑ‌œ‌œ™—Jڑ‌œ‌œ‌œ™4Jڑ‌œ™J™�—Jک�ڑ‍œ‌œ‌œ‌œ	‌œ‌™rJڑ‌œ/™5Jڑ‌œ™J™�—ک�Jک�—ڑ‍œ‌œ‌œ‌œ	‌œ‌™lJ™ھJ™(Jڑœ"™"ڑ‌œ‌™
ڑ‌œ™Jڑ‌œ‌œ‌œ&‌œ™\Jڑœ+™+Jڑœ™—ڑ‌œ‌œ‌œ‌™ڑœ‌œ™#Jڑ‌œ‌œ‌œ&‌œ™\Jڑœ+™+J™—ڑœ‌œ™#ڑ‌œ™Jڑ‌œ‌œ
™ڑ‌œ™JڑœB™Bڑœ‌œ‌œ‌œ™2Jڑ‌œ‌œ™Jڑ‌œ‌œ™!—Jڑ‌œ‌œ,™6J™…J™——J™—ڑœ‌œ™#JڑœB™Bڑœ‌œ‌œ‌œ™2Jڑ‌œ‌œ™Jڑ‌œ‌œ™!—Jڑ‌œ‌œ,™6J™—Jڑ‌œ‌œ™——Jڑ‌œ™J™�——ڑ	‍œ‌œ‌œ>‌œ‌ک„Jڑœ‌œ2ک:Jڑœ‌œ‌œکJکڑ‌œ	‌œ‌œ‌œک/JکJکJڑœ‌œکJڑ‌œک—ڑ‌کJڑœ‌œ‌œ(‌œکCJکGJڑ
‌œ	‌œ‌œ‌œ‌œک3ڑ‌œ‌œ‌کڑœ‌œک!ڑ‌œ‌œ‌کJڑœ-ک-ڑœکJڑœ‌œ‌œ‌ک8Jڑ‌œ‌œ,ک6Jک—ڑ‌œ	کJڑœ‌œ‌œ‌ک;Jڑ‌œ‌œ,ک6Jک———ڑœ‌œک!ڑ‌œ‌œ‌کڑœکJڑœ‌œ‌œ‌ک8Jڑ‌œ‌œ,ک6Jک—ڑ‌œ	کJڑœ‌œ‌œ‌ک;Jڑ‌œ‌œ,ک6Jک———Jڑ‌œ‌œ‌œک+—J™چJڑ‌œک—ڑ‌œکJک�——ڑ	‍$œ‌œ‌œ:‌œ‌ک†ڑ‌œU‌œ	‌œ‌کmڑ‌œ‌œ‌کJڑœ‌œ‌œک&Jڑœ‌œ‌œ‌œک@Jڑ	œ‌œ‌œ'‌œ‌œکaJڑ	œ‌œ‌œ'‌œ‌œکaJڑœ‌œ‌œ‌œکEJڑ‌œ‌œک—Jڑ‌œک—Jڑ‌œ‌œک!Jڑ‌œکJک�—Jک�—ڑ‍œ‌œ
‌œ‌œ‌œ‌کGJڑ‌œ‌œ‌œک)Jڑ‌œکJک�—ڑ‌œکJک�———�…—����‍ّ��eD�