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�