DIRECTORY ThreeC4Support USING[GetReportStream], ThreeC4BaseDecl1Def USING[AppendToTypeList, BuildEmptyCode, BuildEmptyTypeList, BuildName, BuildName2, BuildRopeName, CodeFill, ConcatCode2, GetTheOneType, IdentifierNode, IdFill2, MesaCodeNode, NameFill, NameListNode, NameNode, RopeCode, RopeCode1, RopeFromRopeNode, RopeNode, TestEmptyCode, TypeListNode, TypeNode], ThreeC4BaseDecl2Def USING[FcnDefGraphNode, FunctionCase, Use], ThreeC4BasicAbTypesDef USING[IdListNode, WholeFileNode], ThreeC4RootAbGramDef USING[], ThreeC4PrimImplDefs USING[BuildType, BuildErrorTypeList, CopyTypeList, CreateHashTable, EnumerateHashTable, EqualNames, FindEntry, FindExistingEntry, GenNames, GenNameTypePairs, GenTypeList, GetNameIds, GetGlobalEnv, GetNameInfo, GetTypeInfo, GlobalEnvHandle, HashTable, IsErrorName, IsErrorTypeList, MakeEntry, PrintBadName, PrintError, RopeFromCode, ShowCode, ShowName, ShowNameList, TearDownFcnDefGraphNode, UnrecoveredError], ThreeC4FlowAnalDefs USING[ShowFcnDefGraph], IO USING[PutF, PutRope, rope, STREAM], Rope USING[Cat, Equal, ROPE]; ThreeC4PrimImpl3: CEDAR PROGRAM IMPORTS ThreeC4Support, ThreeC4BaseDecl1Def, ThreeC4PrimImplDefs, ThreeC4FlowAnalDefs, IO, Rope EXPORTS ThreeC4BaseDecl1Def, ThreeC4BaseDecl2Def, ThreeC4BasicAbTypesDef, ThreeC4RootAbGramDef, ThreeC4PrimImplDefs = BEGIN OPEN ThreeC4BaseDecl1Def, ThreeC4BaseDecl2Def, ThreeC4BasicAbTypesDef, ThreeC4PrimImplDefs, ThreeC4FlowAnalDefs; -- symbol table stuff ContextNode: TYPE = REF ContextNodeBody; ContextNodeBody: PUBLIC TYPE = RECORD[ types: HashTable, abstProds: HashTable, functions: HashTable, values: HashTable, grammarSymbols: HashTable, -- except genericTokens, which are in types -- productions: HashTable, parseTrees: HashTable]; LockedContextNode: TYPE = REF LockedContextNodeBody; LockedContextNodeBody: PUBLIC TYPE = RECORD[context: ContextNode]; AbstractTypeInfo: TYPE = REF AbstractTypeInfoBody; AbstractTypeInfoBody: TYPE = RECORD[ abstractTypeId: IdentifierNode, -- named to make this record different type from others, due to unpainted record types in Cedar Program modules. mesaDefFileName: Rope.ROPE, textCodeName: Rope.ROPE, recFcnIdList: IdListNode, recFcnNameList: NameListNode]; SimpleBaseTypeInfo: TYPE = REF SimpleBaseTypeInfoBody; SimpleBaseTypeInfoBody: TYPE = RECORD[ simpleBaseTypeId: IdentifierNode, mesaDefFileName: Rope.ROPE, textCodeName: Rope.ROPE]; EnumeratedBaseTypeInfo: TYPE = REF EnumeratedBaseTypeInfoBody; EnumeratedBaseTypeInfoBody: TYPE = RECORD[ enumeratedBaseTypeId: IdentifierNode, mesaDefFileName: Rope.ROPE, names: NameListNode, textCodeName: Rope.ROPE]; AbstractProductionInfo: TYPE = REF AbstractProductionInfoBody; AbstractProductionInfoBody: TYPE = RECORD[ abstractTypeId: IdentifierNode, caseId: IdentifierNode, -- might be NIL mesaDefFileName: Rope.ROPE, rightSideNames: NameListNode, productionContext: LockedContextNode]; AbstractRightSideSymbolInfo: TYPE = REF AbstractRightSideSymbolInfoBody; AbstractRightSideSymbolInfoBody: TYPE = RECORD[ typeName: NameNode]; GenericTokenTypeInfo: TYPE = REF GenericTokenTypeInfoBody; GenericTokenTypeInfoBody: TYPE = RECORD[ genericTokenTypeId: IdentifierNode, mesaDefFileName: Rope.ROPE, textCodeName: Rope.ROPE]; PreDefinedCedarTypeInfo: TYPE = REF PreDefinedCedarTypeInfoBody; PreDefinedCedarTypeInfoBody: TYPE = RECORD[ preDefinedCedarTypeId: IdentifierNode, textCodeName: Rope.ROPE]; CedarTypeInfo: TYPE = REF CedarTypeInfoBody; CedarTypeInfoBody: TYPE = RECORD[ cedarTypeId: IdentifierNode, mesaDefFileName: Rope.ROPE, textCodeName: Rope.ROPE]; TreeTypeInfo: TYPE = REF TreeTypeInfoBody; TreeTypeInfoBody: TYPE = RECORD[ treeTypeId: IdentifierNode, -- always nil textCodeName: Rope.ROPE]; RecFcnInfo: TYPE = REF RecFcnInfoBody; RecFcnInfoBody: TYPE = RECORD[ recFcnId: IdentifierNode, -- always nil, to make unique record type mesaDefFileName: Rope.ROPE, argTypes: TypeListNode, resultTypes: TypeListNode, defGraph: FcnDefGraphNode]; BaseFcnInfo: TYPE = REF BaseFcnInfoBody; BaseFcnInfoBody: TYPE = RECORD[ baseFcnId: IdentifierNode, -- always nil, to make unique record type mesaDefFileName: Rope.ROPE, argTypes: TypeListNode, resultTypes: TypeListNode, defGraph: FcnDefGraphNode]; CedarFcnInfo: TYPE = REF CedarFcnInfoBody; CedarFcnInfoBody: TYPE = RECORD[ cedarFcnId: IdentifierNode, -- always nil, to make unique record type mesaDefFileName: Rope.ROPE, argTypes: TypeListNode, resultTypes: TypeListNode, defGraph: FcnDefGraphNode]; RopeTokenInfo: TYPE = REF RopeTokenInfoBody; RopeTokenInfoBody: TYPE = RECORD[ ropeTknId: IdentifierNode, -- always nil, to make unique record type name: NameNode]; NonTerminalTokenInfo: TYPE = REF NonTerminalTokenInfoBody; NonTerminalTokenInfoBody: TYPE = RECORD[ nonTerminalTokenId: IdentifierNode, -- always nil, to make unique record type name: NameNode, builds: TypeNode]; ProductionInfo: TYPE = REF ProductionInfoBody; ProductionInfoBody: TYPE = RECORD[ productionInfoId: IdentifierNode, -- always nil, to make unique record type name: NameNode, index: INT]; ControlModuleInfo: TYPE = REF ControlModuleInfoBody; ControlModuleInfoBody: TYPE = RECORD[ controlModuleInfoId: IdentifierNode, -- always nil, to make unique record type mesaDefFileName: Rope.ROPE]; ParseTreeInfo: TYPE = REF ParseTreeInfoBody; ParseTreeInfoBody: TYPE = RECORD[ parseTreeInfoId: IdentifierNode, -- always nil, to make unique record type tree: WholeFileNode]; ErrorInfo: TYPE = REF ErrorInfoBody; ErrorInfoBody: TYPE = RECORD [ errorInfoBody: IdentifierNode -- always nil, to make unique record type ]; BuildErrorInfo: PUBLIC PROC RETURNS [REF ANY] = BEGIN RETURN [NEW[ErrorInfoBody _ [NIL]]]; END; BuildErrorType: PUBLIC PROC RETURNS [TypeNode] = BEGIN RETURN [BuildType[BuildErrorInfo[]]]; END; IsErrorType: PUBLIC PROC [type: TypeNode] RETURNS [BOOLEAN] = BEGIN RETURN [ISTYPE[GetTypeInfo[type], ErrorInfo]]; END; BuildEmptyContext: PUBLIC PROC RETURNS[ContextNode] = BEGIN RETURN[NEW[ContextNodeBody_[ CreateHashTable[10], CreateHashTable[10], CreateHashTable[10], CreateHashTable[10], CreateHashTable[10], CreateHashTable[10], CreateHashTable[10]]]]; END; FakeCopyContextForConditional: PUBLIC PROC[arg: ContextNode] RETURNS[ContextNode] = {RETURN[arg]}; LockContext: PUBLIC PROC[arg: ContextNode] RETURNS[LockedContextNode] = {RETURN[NEW[LockedContextNodeBody_[arg]]]}; RecordAbstractType: PUBLIC PROC[context: ContextNode, type: NameNode, mesaDefFileName: Rope.ROPE, codeName: MesaCodeNode, recFcnIdList: IdListNode, recFcnNameList: NameListNode] RETURNS[ContextNode] = BEGIN id1, id2: IdentifierNode; IF IsErrorName[type] THEN RETURN [context]; [id1, id2] _ GetNameIds[type]; IF id2 # NIL THEN BEGIN PrintBadName[type, "modified name not allowed in this context.\N"]; RETURN [context]; END; MakeEntry[context.types, type, NEW[AbstractTypeInfoBody_[id1, mesaDefFileName, RopeFromCode[codeName], recFcnIdList, recFcnNameList]]]; RETURN[context]; END; RecordSimpleBaseType: PUBLIC PROC[context: ContextNode, type: NameNode, mesaDefFileName: Rope.ROPE, codeName: MesaCodeNode] RETURNS[ContextNode] = BEGIN id1, id2: IdentifierNode; IF IsErrorName[type] THEN RETURN [context]; [id1, id2] _ GetNameIds[type]; IF id2 # NIL THEN BEGIN PrintBadName[type, "modified name not allowed in this context.\N"]; RETURN [context]; END; MakeEntry[context.types, type, NEW[SimpleBaseTypeInfoBody_[id1, mesaDefFileName, RopeFromCode[codeName]]]]; RETURN[context]; END; RecordEnumeratedBaseType: PUBLIC PROC[context: ContextNode, type: NameNode, mesaDefFileName: Rope.ROPE, names: NameListNode, codeName: MesaCodeNode] RETURNS[ContextNode] = BEGIN id1, id2: IdentifierNode; IF IsErrorName[type] THEN RETURN [context]; [id1, id2] _ GetNameIds[type]; IF id2 # NIL THEN BEGIN PrintBadName[type, "modified name not allowed in this context.\N"]; RETURN [context]; END; MakeEntry[context.types, type, NEW[EnumeratedBaseTypeInfoBody_[id1, mesaDefFileName, names, RopeFromCode[codeName]]]]; RETURN[context]; END; RecordAbstractProduction: PUBLIC PROC[context: ContextNode, productionName: NameNode, mesaDefFileName: Rope.ROPE, rightSideNames: NameListNode, productionContext: LockedContextNode] RETURNS[ContextNode] = BEGIN id1, id2: IdentifierNode; IF IsErrorName[productionName] THEN RETURN [context]; [id1, id2] _ GetNameIds[productionName]; MakeEntry[context.abstProds, productionName, NEW[AbstractProductionInfoBody_[id1, id2, mesaDefFileName, rightSideNames, productionContext]]]; RETURN[context]; END; RecordAbstRightSideSymbol: PUBLIC PROC[context: ContextNode, name: NameNode, typeName: NameNode] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] OR IsErrorName[typeName] THEN RETURN [context]; MakeEntry[context.values, name, NEW[AbstractRightSideSymbolInfoBody_[typeName]]]; RETURN[context]; END; RecordGenericToken: PUBLIC PROC[context: ContextNode, type: NameNode, mesaDefFileName: Rope.ROPE, codeName: MesaCodeNode] RETURNS[ContextNode] = BEGIN id1, id2: IdentifierNode; IF IsErrorName[type] THEN RETURN [context]; [id1, id2] _ GetNameIds[type]; IF id2 # NIL THEN BEGIN PrintBadName[type, "modified name not allowed in this context.\N"]; RETURN [context]; END; MakeEntry[context.types, type, NEW[GenericTokenTypeInfoBody_[id1, mesaDefFileName, RopeFromCode[codeName]]]]; RETURN[context]; END; RecordGenericTokenFrom: PUBLIC PROC[context: ContextNode, type: NameNode, mesaDefFileName: Rope.ROPE, codeName: MesaCodeNode] RETURNS[ContextNode] = BEGIN id1, id2: IdentifierNode; IF IsErrorName[type] THEN RETURN [context]; [id1, id2] _ GetNameIds[type]; IF id2 # NIL THEN BEGIN PrintBadName[type, "modified name not allowed in this context.\N"]; RETURN [context]; END; MakeEntry[context.types, type, NEW[GenericTokenTypeInfoBody_[id1, mesaDefFileName, RopeFromCode[codeName]]]]; RETURN[context]; END; RecordPreDefinedCedarType: PUBLIC PROC[context: ContextNode, type: NameNode, codeName: MesaCodeNode] RETURNS[ContextNode] = BEGIN id1, id2: IdentifierNode; IF IsErrorName[type] THEN RETURN [context]; [id1, id2] _ GetNameIds[type]; IF id2 # NIL THEN BEGIN PrintBadName[type, "modified name not allowed in this context.\N"]; RETURN [context]; END; MakeEntry[context.types, type, NEW[PreDefinedCedarTypeInfoBody_[id1, RopeFromCode[codeName]]]]; RETURN[context]; END; RecordCedarType: PUBLIC PROC[context: ContextNode, type: NameNode, mesaDefFileName: Rope.ROPE, codeName: MesaCodeNode] RETURNS[ContextNode] = BEGIN id1, id2: IdentifierNode; IF IsErrorName[type] THEN RETURN [context]; [id1, id2] _ GetNameIds[type]; IF id2 # NIL THEN BEGIN PrintBadName[type, "modified name not allowed in this context.\N"]; RETURN [context]; END; MakeEntry[context.types, type, NEW[CedarTypeInfoBody_[id1, mesaDefFileName, RopeFromCode[codeName]]]]; RETURN[context]; END; RecordCedarFunction: PUBLIC PROC[context: ContextNode, name: NameNode, mesaDefFileName: Rope.ROPE, argTypes: TypeListNode, resultTypes: TypeListNode] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] OR IsErrorTypeList[argTypes] OR IsErrorTypeList[resultTypes] THEN RETURN [context]; MakeEntry[context.functions, name, NEW[CedarFcnInfoBody_[NIL, mesaDefFileName, argTypes, resultTypes]]]; RETURN[context]; END; RecordBaseFunction: PUBLIC PROC[context: ContextNode, name: NameNode, mesaDefFileName: Rope.ROPE, argTypes: TypeListNode, resultTypes: TypeListNode, defGraph: FcnDefGraphNode] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] OR IsErrorTypeList[argTypes] OR IsErrorTypeList[resultTypes] THEN RETURN [context]; MakeEntry[context.functions, name, NEW[BaseFcnInfoBody_[NIL, mesaDefFileName, argTypes, resultTypes, defGraph]]]; RETURN[context]; END; RecordRecFcnDef: PUBLIC PROC[context: ContextNode, name: NameNode, mesaDefFileName: Rope.ROPE, argTypes: TypeListNode, resultTypes: TypeListNode, defGraph: FcnDefGraphNode] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] OR IsErrorTypeList[argTypes] OR IsErrorTypeList[resultTypes] THEN RETURN [context]; MakeEntry[context.functions, name, NEW[RecFcnInfoBody_[NIL, mesaDefFileName, argTypes, resultTypes, defGraph]]]; RETURN[context] END; RecordBaseFcnDef: PUBLIC PROC[context: ContextNode, name: NameNode, mesaDefFileName: Rope.ROPE, argTypes: TypeListNode, resultTypes: TypeListNode, defGraph: FcnDefGraphNode] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] OR IsErrorTypeList[argTypes] OR IsErrorTypeList[resultTypes] THEN RETURN [context]; MakeEntry[context.functions, name, NEW[BaseFcnInfoBody_[NIL, mesaDefFileName, argTypes, resultTypes, defGraph]]]; RETURN[context] END; RecordGlobalTreeType: PUBLIC PROC[context: ContextNode, name: NameNode, codeName: MesaCodeNode] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] THEN RETURN[context]; MakeEntry[context.types, name, NEW[TreeTypeInfoBody_[NIL, RopeFromCode[codeName]]]]; RETURN[context]; END; RecordRopeToken: PUBLIC PROC[context: ContextNode, rope: RopeNode] RETURNS[ContextNode] = BEGIN name: NameNode _ BuildRopeName[RopeFromRopeNode[rope]]; MakeEntry[context.grammarSymbols, name, NEW[RopeTokenInfoBody_[NIL, name]]]; RETURN[context]; END; RecordNonTerminalToken: PUBLIC PROC[context: ContextNode, name: NameNode, builds: NameNode] RETURNS[ContextNode] = BEGIN type: TypeNode; IF IsErrorName[name] OR IsErrorName[builds] THEN RETURN [context]; type _ FindType[context, builds]; IF GetNameIds[name].id2 # NIL THEN BEGIN PrintBadName[name, "modified name not allowed in this context"]; RETURN [context]; END; MakeEntry[context.grammarSymbols, name, NEW[NonTerminalTokenInfoBody_[NIL, name, type]]]; RETURN[context]; END; RecordProduction: PUBLIC PROC[context: ContextNode, name: NameNode, index: INT] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] THEN RETURN [context]; MakeEntry[context.productions, name, NEW[ProductionInfoBody_[NIL, name, index]]]; RETURN[context]; END; RecordControlModule: PUBLIC PROC[context: ContextNode, mesaDefFileName: Rope.ROPE] RETURNS[ContextNode] = BEGIN MakeEntry[context.types, BuildRopeName["$Control"], NEW[ControlModuleInfoBody_[NIL, mesaDefFileName]]]; RETURN[context]; END; RecordAbstractTypeFrom: PUBLIC PROC[context: ContextNode, type: NameNode, mesaDefFileName: Rope.ROPE, codeName: MesaCodeNode] RETURNS[ContextNode] = BEGIN id1, id2: IdentifierNode; IF IsErrorName[type] THEN RETURN [context]; [id1, id2] _ GetNameIds[type]; IF id2 # NIL THEN BEGIN PrintBadName[type, "modified name not allowed in this context"]; RETURN [context]; END; MakeEntry[context.types, type, NEW[AbstractTypeInfoBody_[id1, mesaDefFileName, RopeFromCode[codeName], NIL, NIL]]]; RETURN[context]; END; RecordParseTree: PUBLIC PROC[context: ContextNode, name: NameNode, tree: WholeFileNode] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] THEN RETURN [context]; MakeEntry[context.parseTrees, name, NEW[ParseTreeInfoBody_[NIL, tree]]]; RETURN[context] END; FindParseTree: PUBLIC PROC[context: ContextNode, name: NameNode] RETURNS[WholeFileNode] = BEGIN info: REF ANY; IF IsErrorName[name] THEN RETURN[NIL]; info _ FindEntry[context.parseTrees, name]; IF info = NIL THEN RETURN [NIL]; WITH info SELECT FROM pti: ParseTreeInfo => RETURN [pti.tree]; ei: ErrorInfo => RETURN [NIL]; ENDCASE => ERROR; END; RecordOtherParseTree: PUBLIC PROC[context: ContextNode, name: NameNode, info: REF ANY] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] THEN RETURN [context]; MakeEntry[context.parseTrees, name, info]; RETURN[context] END; FindOtherParseTree: PUBLIC PROC[context: ContextNode, name: NameNode] RETURNS[REF ANY] = BEGIN info: REF ANY; IF IsErrorName[name] THEN RETURN [BuildErrorInfo[]]; info _ FindEntry[context.parseTrees, name]; IF info = NIL THEN BEGIN PrintBadName[name, "undefined or out of context -- expected ParseTree"]; RETURN [BuildErrorInfo[]]; END; RETURN[info] END; RecordOtherType: PUBLIC PROC[context: ContextNode, name: NameNode, info: REF ANY] RETURNS[ContextNode] = BEGIN IF IsErrorName[name] THEN RETURN[context]; MakeEntry[context.types, name, info]; RETURN[context] END; FindType: PUBLIC PROC[context: ContextNode, name: NameNode] RETURNS[TypeNode] = BEGIN info: REF ANY; IF IsErrorName[name] THEN RETURN[BuildErrorType[]]; info _ FindEntry[context.types, name]; IF info = NIL THEN BEGIN PrintBadName[name, "undefined or out of context -- expected BaseType, AbstractType, or GenericToken"]; RETURN [BuildErrorType[]]; END; RETURN[BuildType[info]]; END; GetTypeCodeName: PUBLIC PROC[type: TypeNode] RETURNS[MesaCodeNode] = BEGIN WITH GetTypeInfo[type] SELECT FROM ati: AbstractTypeInfo => RETURN[RopeCode[ati.textCodeName]]; sbti: SimpleBaseTypeInfo => RETURN[RopeCode[sbti.textCodeName]]; gtti: GenericTokenTypeInfo => RETURN[RopeCode[gtti.textCodeName]]; pdcti: PreDefinedCedarTypeInfo => RETURN[RopeCode[pdcti.textCodeName]]; cti: CedarTypeInfo => RETURN[RopeCode[cti.textCodeName]]; tti: TreeTypeInfo => RETURN[RopeCode[tti.textCodeName]]; ebti: EnumeratedBaseTypeInfo => RETURN[RopeCode[ebti.textCodeName]]; ei: ErrorInfo => RETURN [RopeCode["** ERROR **"]]; ENDCASE => ERROR; END; CompareValTypeWithVarType: PUBLIC PROC[val: TypeNode, var: TypeNode] RETURNS[BOOLEAN] = BEGIN IF val = var THEN RETURN[TRUE]; IF GetTypeInfo[val] = GetTypeInfo[var] THEN RETURN[TRUE]; IF ISTYPE[GetTypeInfo[var], TreeTypeInfo] AND ISTYPE[GetTypeInfo[val], AbstractTypeInfo] THEN RETURN [TRUE]; IF ISTYPE[GetTypeInfo[var], ErrorInfo] OR ISTYPE[GetTypeInfo[val], ErrorInfo] THEN RETURN [TRUE]; PrintError["type mismatch -- expected a value of type ", GetTypeRope[var], " but found a value of type ", GetTypeRope[val]]; RETURN [FALSE]; END; EqualTypes: PUBLIC PROC[t1, t2: TypeNode] RETURNS[BOOLEAN] = BEGIN IF t1 = t2 THEN RETURN[TRUE]; IF GetTypeInfo[t1] = GetTypeInfo[t2] THEN RETURN[TRUE]; IF ISTYPE[GetTypeInfo[t1], ErrorInfo] THEN RETURN [TRUE]; IF ISTYPE[GetTypeInfo[t2], ErrorInfo] THEN RETURN [TRUE]; RETURN[FALSE]; END; GetTypeRope: PROC[type: TypeNode] RETURNS [Rope.ROPE] = BEGIN RETURN [GetTypeInfoRope[GetTypeInfo[type]]]; END; GetTypeInfoRope: PROC[info: REF ANY] RETURNS [Rope.ROPE] = BEGIN WITH info SELECT FROM ati: AbstractTypeInfo => RETURN [Rope.Cat["AbstractType(", ati.abstractTypeId.text, ")"]]; sbti: SimpleBaseTypeInfo => RETURN [Rope.Cat["BaseType(", sbti.simpleBaseTypeId.text, ")"]]; gtti: GenericTokenTypeInfo => RETURN [Rope.Cat["GenericToken(", gtti.genericTokenTypeId.text, ")"]]; pdcti: PreDefinedCedarTypeInfo => RETURN [Rope.Cat["CedarType(", pdcti.preDefinedCedarTypeId.text, ")"]]; cti: CedarTypeInfo => RETURN [Rope.Cat["CedarType(", cti.cedarTypeId.text, ")"]]; tti: TreeTypeInfo => RETURN ["AbstractType"]; ebti: EnumeratedBaseTypeInfo => RETURN [Rope.Cat["BaseType(", ebti.enumeratedBaseTypeId.text, ")"]]; api: AbstractProductionInfo => RETURN["AbstractProduction"]; arssi: AbstractRightSideSymbolInfo => RETURN["AbstractRightSideSymbol"]; rfi: RecFcnInfo => RETURN ["TreeRecursiveFunction"]; bfi: BaseFcnInfo => RETURN ["BaseFunction"]; cfi: CedarFcnInfo => RETURN["CedarFunction"]; rti: RopeTokenInfo => RETURN["RopeToken"]; ntti: NonTerminalTokenInfo => RETURN ["NonTerminal"]; pi: ProductionInfo => RETURN ["Production"]; cmi: ControlModuleInfo => RETURN ["ControlModule"]; pti: ParseTreeInfo => RETURN["ParseTree"]; ei: ErrorInfo => RETURN["** Error **"]; ENDCASE => RETURN ["???"]; END; ShortShowType: PUBLIC PROC[type: TypeNode, on: IO.STREAM] = BEGIN WITH GetTypeInfo[type] SELECT FROM ati: AbstractTypeInfo => ShowId[ati.abstractTypeId, on]; sbti: SimpleBaseTypeInfo => ShowId[sbti.simpleBaseTypeId, on]; gtti: GenericTokenTypeInfo => ShowId[gtti.genericTokenTypeId, on]; pdcti: PreDefinedCedarTypeInfo => ShowId[pdcti.preDefinedCedarTypeId, on]; cti: CedarTypeInfo => ShowId[cti.cedarTypeId, on]; tti: TreeTypeInfo => IO.PutF[on, "Tree$"]; ebti: EnumeratedBaseTypeInfo => ShowId[ebti.enumeratedBaseTypeId, on]; ENDCASE => ERROR; END; ShowTypeList: PUBLIC PROC[typeList: TypeListNode, on: IO.STREAM] = BEGIN oneShown: BOOLEAN _ FALSE; seeOneType: PROC[type: TypeNode] = BEGIN IF oneShown THEN IO.PutRope[on, ", "] ELSE oneShown _ TRUE; ShortShowType[type, on]; END; GenTypeList[typeList, seeOneType]; END; CheckForBOOLEANType: PUBLIC PROC[type: TypeNode] RETURNS[BOOLEAN] = BEGIN WITH GetTypeInfo[type] SELECT FROM pdcti: PreDefinedCedarTypeInfo => IF Rope.Equal["BOOLEAN", pdcti.textCodeName] THEN RETURN[TRUE]; ei: ErrorInfo => RETURN [TRUE]; ENDCASE => NULL; PrintError["type mismatch -- expected a value of type CedarType(BOOLEAN) but found a value of type ", GetTypeRope[type]]; RETURN [TRUE]; END; CheckForOneBoolean: PUBLIC PROC[list: TypeListNode] RETURNS[BOOLEAN] = BEGIN RETURN[CheckForBOOLEANType[GetTheOneType[list]]]; END; LookupContextNode: TYPE = REF LookupContextNodeBody; LookupContextNodeBody: PUBLIC TYPE = RECORD[ global: ContextNode, production: LockedContextNode, vars: VarItem, rightSideSymbols: RSSItem]; VarItem: TYPE = REF VarItemBody; VarItemBody: TYPE = RECORD[ name: NameNode, type: TypeNode, next: VarItem]; RSSItem: TYPE = REF RSSItemBody; RSSItemBody: TYPE = RECORD[ name: NameNode, type: TypeNode, next: RSSItem]; BuildBasicLookupContext: PUBLIC PROC[context: ContextNode] RETURNS[LookupContextNode] = {RETURN[NEW[LookupContextNodeBody_[context, NIL, NIL, NIL]]]}; FakeCopyLookupContext: PUBLIC PROC[lookup: LookupContextNode] RETURNS[LookupContextNode] = {RETURN[lookup]}; PushProductionContext: PUBLIC PROC[lookup: LookupContextNode, production: LockedContextNode] RETURNS[LookupContextNode] = BEGIN IF lookup.production # NIL THEN ERROR; RETURN[NEW[LookupContextNodeBody_[lookup.global, production, NIL]]]; END; RecordVarSeq: PUBLIC PROC[lookup: LookupContextNode, names: NameListNode, types: TypeListNode] RETURNS[LookupContextNode] = BEGIN newContext: LookupContextNode _ NEW[LookupContextNodeBody_[lookup.global, lookup.production, lookup.vars]]; SeePair: PROC[name: NameNode, type: TypeNode] = BEGIN newItem: VarItem; IF IsErrorName[name] THEN RETURN; newItem _ NEW[VarItemBody_[name, type, newContext.vars]]; newContext.vars _ newItem; END; GenNameTypePairs[names, types, SeePair]; RETURN[newContext]; END; TearDownGraphs: PUBLIC PROC [lookup: LookupContextNode] RETURNS [BOOLEAN] = BEGIN SeeOneEntry: PROC [info: REF ANY, name: NameNode] = BEGIN TearDown: PROC [defGraph: FcnDefGraphNode] RETURNS [FcnDefGraphNode] = BEGIN -- s: IO.STREAM; -- s _ SIGNAL ThreeC4Support.GetReportStream; -- IO.PutF[s, "tearing down "]; -- ShowName[name, s]; -- IO.PutF[s, "\N"]; RETURN[TearDownFcnDefGraphNode[defGraph]]; END; WITH info SELECT FROM rfi: RecFcnInfo => rfi.defGraph _ TearDown[rfi.defGraph]; cfi: CedarFcnInfo => cfi.defGraph _ TearDown[cfi.defGraph]; bfi: BaseFcnInfo => bfi.defGraph _ TearDown[bfi.defGraph]; ENDCASE => ERROR; END; EnumerateHashTable[lookup.global.functions, SeeOneEntry]; RETURN [TRUE]; END; LookUpAbTypeRecFcnsIdList: PUBLIC PROC[lookup: LookupContextNode, typeName: NameNode] RETURNS[IdListNode] = BEGIN info: REF ANY; IF IsErrorName[typeName] THEN ERROR UnrecoveredError; info _ FindEntry[lookup.global.types, typeName]; IF info = NIL THEN BEGIN PrintBadName[typeName, "undefined or out of context -- expected AbstractType"]; ERROR UnrecoveredError; END; WITH info SELECT FROM ati: AbstractTypeInfo => RETURN [ati.recFcnIdList]; ENDCASE => {PrintBadName[typeName, "type mismatch -- expected AbstractType but found ", GetTypeInfoRope[info]]; ERROR UnrecoveredError}; END; LookUpAbProduction: PUBLIC PROC[lookup: LookupContextNode, prodName: NameNode] RETURNS[NameListNode, LockedContextNode] = BEGIN info: REF ANY; IF IsErrorName[prodName] THEN ERROR UnrecoveredError; info _ FindEntry[lookup.global.abstProds, prodName]; IF info = NIL THEN BEGIN PrintBadName[prodName, "undefined or out of context -- expected AbstractProduction"]; ERROR UnrecoveredError; END; WITH info SELECT FROM api: AbstractProductionInfo => RETURN [api.rightSideNames, api.productionContext]; ENDCASE => ERROR; END; LookUpRecFcnDef: PUBLIC PROC[lookup: LookupContextNode, funName: NameNode] RETURNS[TypeListNode, TypeListNode] = BEGIN info: REF ANY; IF IsErrorName[funName] THEN RETURN [BuildErrorTypeList[], BuildErrorTypeList[]]; info _ FindEntry[lookup.global.functions, funName]; IF info = NIL THEN BEGIN PrintBadName[funName, "undefined or out of context -- expected TreeRecursiveFunction"]; RETURN [BuildErrorTypeList[], BuildErrorTypeList[]]; END; WITH info SELECT FROM rfi: RecFcnInfo => RETURN [rfi.argTypes, CopyTypeList[rfi.resultTypes]]; ENDCASE => {PrintBadName[funName, "type mismatch -- expected TreeRecursiveFunction but found ", GetTypeInfoRope[info]]; RETURN [BuildErrorTypeList[], BuildErrorTypeList[]]}; END; LookUpFcnDefGraph: PUBLIC PROC[lookup: LookupContextNode, funName: NameNode] RETURNS[FcnDefGraphNode] = BEGIN info: REF ANY; IF IsErrorName[funName] THEN ERROR UnrecoveredError; info _ FindEntry[lookup.global.functions, funName]; IF info = NIL THEN BEGIN PrintBadName[funName, "undefined or out of context -- expected TreeRecursiveFunction or BaseFunction"]; ERROR UnrecoveredError; END; WITH info SELECT FROM rfi: RecFcnInfo => RETURN[rfi.defGraph]; bfi: BaseFcnInfo => RETURN[bfi.defGraph]; ENDCASE => {PrintBadName[funName, "type mismatch -- expected TreeRecursiveFunction or BaseFunction but found ", GetTypeInfoRope[info]]; ERROR UnrecoveredError}; END; LookUpType: PUBLIC PROC[lookup: LookupContextNode, typeName: NameNode] RETURNS[TypeNode] = BEGIN info: REF ANY; IF IsErrorName[typeName] THEN RETURN[BuildErrorType[]]; info _ FindEntry[lookup.global.types, typeName]; IF info = NIL THEN BEGIN PrintBadName[typeName, "undefined or out of context -- expected BaseType, AbstractType, or GenericToken"]; RETURN [BuildErrorType[]]; END; RETURN[BuildType[info]]; END; LookUpOtherType: PUBLIC PROC[lookup: LookupContextNode, typeName: NameNode] RETURNS[REF ANY] = BEGIN info: REF ANY; IF IsErrorName[typeName] THEN RETURN[BuildErrorInfo[]]; info _ FindEntry[lookup.global.types, typeName]; IF info = NIL THEN BEGIN PrintBadName[typeName, "undefined or out of context -- expected BaseType, AbstractType, or GenericToken"]; RETURN [BuildErrorInfo[]]; END; RETURN[info]; END; LookUpSimpleValue: PUBLIC PROC[lookup: LookupContextNode, id: IdentifierNode] RETURNS[TypeNode, MesaCodeNode] = BEGIN name: NameNode _ BuildName[id]; -- see if its a local variable FOR varItem: VarItem _ lookup.vars, varItem.next WHILE varItem # NIL DO IF EqualNames[varItem.name, name] THEN RETURN[varItem.type, RopeCode1["%g", NameFill[name]]]; ENDLOOP; -- see if we find it in production context BEGIN info1: REF ANY _ FindEntry[lookup.production.values, name]; info: AbstractRightSideSymbolInfo; type: TypeNode; IF info1 # NIL AND NOT ISTYPE[info1, AbstractRightSideSymbolInfo] THEN ERROR; info _ NARROW[info1]; type _ IF info # NIL THEN LookUpType[lookup, info.typeName] ELSE NIL; IF type # NIL THEN RETURN[type, RopeCode1["treeData.%g", NameFill[name]]]; END; -- so, we can't find it PrintBadName[name, "undefined or out of context -- expected a value"]; RETURN [BuildErrorType[], RopeCode["** ERROR **"]]; END; LookUpValue2: PUBLIC PROC[lookup: LookupContextNode, id1, id2: IdentifierNode] RETURNS[TypeNode, MesaCodeNode] = BEGIN -- see if we find it in production context BEGIN nameA: NameNode _ BuildName2[id1, id2]; info1: REF ANY _ FindEntry[lookup.production.values, nameA]; info: AbstractRightSideSymbolInfo; type: TypeNode; IF info1 # NIL AND NOT ISTYPE[info1, AbstractRightSideSymbolInfo] THEN ERROR; info _ NARROW[info1]; type _ IF info # NIL THEN LookUpType[lookup, info.typeName] ELSE NIL; IF type # NIL THEN RETURN[type, RopeCode1["treeData.%g", IdFill2[id1, id2]]]; END; -- see if it is an enumerated type value BEGIN type: TypeNode; code: MesaCodeNode; [type, code] _ LookUpEnumTypeVal1[lookup, BuildName[id1], BuildName[id2]]; IF type # NIL THEN RETURN[type, code]; END; -- so, we can't find it PrintBadName[BuildName2[id1, id2], "undefined or out of context -- expected a value"]; RETURN [BuildErrorType[], RopeCode["** ERROR **"]]; END; -- LookUpEnumTypeVal1 is just like LookUpEnumTypeVal, except that the former will return NIL values when anything goes wrong. LookUpEnumTypeVal1: PROC[lookup: LookupContextNode, nameB1: NameNode, nameB2: NameNode] RETURNS[TypeNode, MesaCodeNode] = BEGIN type: TypeNode; info : REF ANY; IF IsErrorName[nameB1] OR IsErrorName[nameB2] THEN RETURN [BuildErrorType[], RopeCode["** ERROR **"]]; info _ FindEntry[lookup.global.types, nameB1]; IF info = NIL THEN RETURN [NIL, BuildEmptyCode[]]; type _ BuildType[info]; WITH info SELECT FROM ebti: EnumeratedBaseTypeInfo => BEGIN -- check for legal value name legal: BOOLEAN _ FALSE; seeName: PROC[nm: NameNode] = {IF EqualNames[nm, nameB2] THEN legal _ TRUE}; GenNames[ebti.names, seeName]; IF legal THEN RETURN[type, ConcatCode2[RopeCode[ebti.textCodeName], RopeCode1[".%g", NameFill[nameB2]]]]; END; ENDCASE => NULL; RETURN[NIL, BuildEmptyCode[]]; END; LookUpEnumTypeVal: PUBLIC PROC[lookup: LookupContextNode, nameB1: NameNode, nameB2: NameNode] RETURNS[TypeNode, MesaCodeNode] = BEGIN type: TypeNode; code: MesaCodeNode; IF IsErrorName[nameB1] OR IsErrorName[nameB2] THEN RETURN [BuildErrorType[], RopeCode["** ERROR **"]]; [type, code] _ LookUpEnumTypeVal1[lookup, nameB1, nameB2]; IF type = NIL THEN BEGIN PrintBadName[nameB1, "undefined or out of context -- expected a value"]; RETURN [BuildErrorType[], RopeCode["** ERROR **"]]; END; RETURN [type, code]; END; LookUpFunction: PUBLIC PROC[lookup: LookupContextNode, funName: NameNode] RETURNS[case: FunctionCase, argTypes: TypeListNode, resultTypes: TypeListNode] = BEGIN info: REF ANY; IF IsErrorName[funName] THEN RETURN[base, BuildErrorTypeList[], BuildErrorTypeList[]]; info _ FindEntry[lookup.global.functions, funName]; IF info = NIL THEN BEGIN PrintBadName[funName, "undefined or out of context -- expected Function"]; RETURN[base, BuildErrorTypeList[], BuildErrorTypeList[]]; END; WITH info SELECT FROM rfi: RecFcnInfo => RETURN[recursive, rfi.argTypes, CopyTypeList[rfi.resultTypes]]; bfi: BaseFcnInfo => RETURN[base, bfi.argTypes, CopyTypeList[bfi.resultTypes]]; cfi: CedarFcnInfo => RETURN[base, cfi.argTypes, CopyTypeList[cfi.resultTypes]]; ENDCASE => ERROR; END; LookUpProduction: PUBLIC PROC[lookup: LookupContextNode, name: NameNode] RETURNS[INT] = BEGIN info: REF ANY; IF IsErrorName[name] THEN ERROR UnrecoveredError; info _ FindEntry[lookup.global.productions, name]; IF info = NIL THEN BEGIN PrintBadName[name, "undefined or out of context -- expected Production"]; ERROR UnrecoveredError; END; WITH info SELECT FROM pi: ProductionInfo => RETURN[pi.index]; ENDCASE => ERROR; END; LookUpParseTree: PUBLIC PROC[lookup: LookupContextNode, name: NameNode] RETURNS[WholeFileNode] = BEGIN info: REF ANY; IF IsErrorName[name] THEN ERROR UnrecoveredError; info _ FindEntry[lookup.global.parseTrees, name]; IF info = NIL THEN BEGIN PrintBadName[name, "undefined or out of context -- expected ParseTree"]; ERROR UnrecoveredError; END; WITH info SELECT FROM pti: ParseTreeInfo => RETURN [pti.tree]; ENDCASE => ERROR; END; EqualFunCase: PUBLIC PROC[c1, c2: FunctionCase] RETURNS[BOOLEAN] = {RETURN[c1 = c2]}; CheckLegalRopeToken: PUBLIC PROC [lookup: LookupContextNode, rope: RopeNode] RETURNS[BOOLEAN] = BEGIN name: NameNode _ BuildRopeName[RopeFromRopeNode[rope]]; info: REF ANY _ FindEntry[lookup.global.grammarSymbols, name]; IF info = NIL THEN BEGIN PrintBadName[name, "undefined or out of context -- expected RopeToken"]; RETURN [TRUE]; END; WITH info SELECT FROM rti: RopeTokenInfo => RETURN [TRUE]; ENDCASE => {PrintError["type mismatch -- expected RopeToken but found ", GetTypeInfoRope[info]]; RETURN [TRUE]}; END; PushLocalRSS: PUBLIC PROC[lookup: LookupContextNode, name: NameNode, type: TypeNode] RETURNS[LookupContextNode] = BEGIN IF IsErrorName[name] THEN RETURN [lookup]; BEGIN item: RSSItem _ NEW[RSSItemBody_[name, type, lookup.rightSideSymbols]]; newLookup: LookupContextNode _ NEW[LookupContextNodeBody_[lookup.global, lookup.production, lookup.vars, item]]; RETURN[newLookup]; END; END; LookUpGrammarSymbol: PUBLIC PROC[lookup: LookupContextNode, name: NameNode] RETURNS[TypeNode] = BEGIN info: REF ANY; IF IsErrorName[name] THEN RETURN [BuildErrorType[]]; info _ FindEntry[lookup.global.grammarSymbols, name]; IF info # NIL THEN WITH info SELECT FROM --rti: RopeTokenInfo => ERROR; ntti: NonTerminalTokenInfo => RETURN[ntti.builds]; ENDCASE => {PrintBadName[name, "type mismatch -- expected GenericToken or NonTerminal but found ", GetTypeInfoRope[info]]; RETURN [BuildErrorType[]]}; -- might be a generic token or abstract type info _ FindEntry[lookup.global.types, name]; WITH info SELECT FROM gtti: GenericTokenTypeInfo => RETURN[BuildType[info]]; -- ati: AbstractTypeInfo => ERROR; some day I want to have a concrete production build a pure value. This requires some more work in Tran2B.1casaba. ENDCASE => {PrintBadName[name, "type mismatch -- expected GenericToken or NonTerminal but found ", GetTypeInfoRope[info]]; RETURN [BuildErrorType[]]}; END; LookUpAbstractProduction: PUBLIC PROC[lookup: LookupContextNode, name: NameNode] RETURNS[TypeNode, TypeListNode] = BEGIN info: REF ANY; IF IsErrorName[name] THEN RETURN [BuildErrorType[], BuildErrorTypeList[]]; info _ FindEntry[lookup.global.abstProds, name]; IF info = NIL THEN BEGIN PrintBadName[name, "undefined or out of context -- expected AbstractProduction"]; RETURN [BuildErrorType[], BuildErrorTypeList[]]; END; WITH info SELECT FROM api: AbstractProductionInfo => BEGIN type: TypeNode _ LookUpType[lookup, BuildName[api.abstractTypeId]]; -- why didnt I record the type typeList: TypeListNode _ BuildEmptyTypeList[]; seeAName: PROC[argName: NameNode] = {IF IsErrorName[argName] THEN typeList _ BuildErrorTypeList[] ELSE typeList _ AppendToTypeList[typeList, LookUpType[lookup, BuildName[GetNameIds[argName].id1]]]}; GenNames[api.rightSideNames, seeAName]; RETURN[type, typeList] END; ENDCASE => ERROR; END; LookUpRightSideSymbol: PUBLIC PROC[lookup: LookupContextNode, name: NameNode] RETURNS[TypeNode] = BEGIN IF IsErrorName[name] THEN RETURN [BuildErrorType[]]; FOR item: RSSItem _ lookup.rightSideSymbols, item.next WHILE item # NIL DO IF EqualNames[item.name, name] THEN RETURN[item.type]; ENDLOOP; RETURN[NIL]; -- this is not always an error condition END; FoundType: PUBLIC PROC[type: TypeNode] RETURNS[BOOLEAN] = BEGIN RETURN [type # NIL]; END; EmptyRSContext: PUBLIC PROC[lookup: LookupContextNode] RETURNS[BOOLEAN] = {RETURN[lookup.rightSideSymbols = NIL]}; -- usage info UsageNode: TYPE = REF UsageNodeBody; UsageNodeBody: PUBLIC TYPE = RECORD[ usageHT: HashTable]; UseInfo: TYPE = REF UseInfoBody; UseInfoBody: TYPE = RECORD[ bits: ARRAY Use OF BOOLEAN]; BuildEmptyUsage: PUBLIC PROC RETURNS[UsageNode] = {RETURN[NEW[UsageNodeBody_[CreateHashTable[10]]]]}; RecordTypeUse: PUBLIC PROC[usage: UsageNode, type: TypeNode] RETURNS[UsageNode] = BEGIN fileName: Rope.ROPE; info: REF ANY _ GetTypeInfo[type]; WITH info SELECT FROM ati: AbstractTypeInfo => fileName _ ati.mesaDefFileName; sbti: SimpleBaseTypeInfo => fileName _ sbti.mesaDefFileName; gtti: GenericTokenTypeInfo => fileName _ gtti.mesaDefFileName; pdcti: PreDefinedCedarTypeInfo => RETURN[usage]; cti: CedarTypeInfo => fileName _ cti.mesaDefFileName; tti: TreeTypeInfo => RETURN[usage]; ebti: EnumeratedBaseTypeInfo => fileName _ ebti.mesaDefFileName; ei: ErrorInfo => RETURN[usage]; ENDCASE => ERROR; RecordUse[usage, BuildRopeName[fileName], ref]; RETURN[usage] END; RecordTypesUse: PUBLIC PROC[usage: UsageNode, types: TypeListNode] RETURNS[UsageNode] = BEGIN seeType: PROC[type: TypeNode] = {usage _ RecordTypeUse[usage, type]}; GenTypeList[types, seeType]; RETURN[usage]; END; RecordFcnUse: PUBLIC PROC[usage: UsageNode, name: NameNode, use: Use, context: LookupContextNode] RETURNS[UsageNode] = BEGIN fileName: Rope.ROPE; info: REF ANY; IF IsErrorName[name] THEN RETURN [usage]; info _ FindEntry[context.global.functions, name]; IF info = NIL THEN BEGIN PrintBadName[name, "undefined or out of context -- expected Function"]; RETURN [usage]; END; WITH info SELECT FROM rfi: RecFcnInfo => fileName _ rfi.mesaDefFileName; bfi: BaseFcnInfo => fileName _ bfi.mesaDefFileName; cfi: CedarFcnInfo => fileName _ cfi.mesaDefFileName; ENDCASE => ERROR; RecordUse[usage, BuildRopeName[fileName], use]; RETURN[usage] END; RecordAbstProdUse: PUBLIC PROC[usage: UsageNode, name: NameNode, use: Use, context: LookupContextNode] RETURNS[UsageNode] = BEGIN info1: REF ANY; IF IsErrorName[name] THEN RETURN [usage]; info1 _ FindEntry[context.global.abstProds, name]; IF info1 = NIL THEN BEGIN PrintBadName[name, "undefined or out of context -- expected AbstractProduction"]; RETURN [usage]; END ELSE IF ISTYPE[info1, ErrorInfo] THEN RETURN [usage] ELSE BEGIN info: AbstractProductionInfo _ NARROW[info1]; fileName: Rope.ROPE _ info.mesaDefFileName; RecordUse[usage, BuildRopeName[fileName], use]; RETURN[usage]; END; END; RecordGenericTokenUse: PUBLIC PROC[usage: UsageNode, name: NameNode, use: Use, context: LookupContextNode] RETURNS[UsageNode] = BEGIN info1: REF ANY; IF IsErrorName[name] THEN RETURN [usage]; info1 _ FindEntry[context.global.types, name]; IF info1 = NIL THEN BEGIN PrintBadName[name, "undefined or out of context -- expected GenericToken"]; RETURN [usage]; END ELSE IF ISTYPE[info1, ErrorInfo] THEN RETURN [usage] ELSE BEGIN info: GenericTokenTypeInfo _ NARROW[info1]; fileName: Rope.ROPE _ info.mesaDefFileName; RecordUse[usage, BuildRopeName[fileName], use]; RETURN[usage]; END; END; RecordLinkExport: PUBLIC PROC[usage: UsageNode, context: LookupContextNode] RETURNS[UsageNode] = BEGIN info: ControlModuleInfo _ NARROW[FindExistingEntry[context.global.types, BuildRopeName["$Control"]]]; RecordUse[usage, BuildRopeName["ParserDriver"], ref]; RecordUse[usage, BuildRopeName[info.mesaDefFileName], export]; RETURN[usage] END; RecordDefFileUse: PUBLIC PROC[usage: UsageNode, fNameText: Rope.ROPE, use: Use] RETURNS[UsageNode] = BEGIN RecordUse[usage, BuildRopeName[fNameText], use]; RETURN[usage]; END; Hello: SIGNAL = CODE; interestingFileName: Rope.ROPE _ NIL; interestingUse: Use _ import; RecordUse: PROC[usage: UsageNode, fileName: NameNode, use: Use] = BEGIN info: UseInfo; nameText: Rope.ROPE; IF IsErrorName[fileName] THEN RETURN; info _ NARROW[FindEntry[usage.usageHT, fileName]]; nameText _ GetNameInfo[fileName].text; IF Rope.Equal[nameText, interestingFileName] AND use = interestingUse THEN Hello; IF info = NIL THEN BEGIN info _ NEW[UseInfoBody_[[FALSE, FALSE, FALSE]]]; MakeEntry[usage.usageHT, fileName, info]; END; info.bits[use] _ TRUE; END; BuildDefUseCode: PUBLIC PROC[usage: UsageNode, self: Rope.ROPE] RETURNS[directoryCode, openCode: MesaCodeNode] = BEGIN selfName: NameNode _ BuildRopeName[self]; ViewUseEntry: PROC[info: REF ANY, name: NameNode] = BEGIN useInfo: UseInfo _ NARROW[info]; IF IsErrorName[name] THEN RETURN; IF EqualNames[name, selfName] THEN RETURN; IF useInfo.bits[ref] OR useInfo.bits[import] THEN BEGIN newCode: MesaCodeNode; IF directoryCode # NIL THEN newCode _ RopeCode1[",\N\T%g", NameFill[name]] ELSE newCode _ RopeCode1["\N\T%g", NameFill[name]]; directoryCode _ ConcatCode2[directoryCode, newCode]; END; IF useInfo.bits[export] AND NOT (useInfo.bits[ref] OR useInfo.bits[import]) THEN BEGIN newCode: MesaCodeNode; IF directoryCode # NIL THEN newCode _ RopeCode1[",\N\T%g USING[]", NameFill[name]] ELSE newCode _ RopeCode1["\N\T%g USING[]", NameFill[name]]; directoryCode _ ConcatCode2[directoryCode, newCode]; END; IF useInfo.bits[ref] OR useInfo.bits[import] THEN BEGIN newCode: MesaCodeNode; IF openCode # NIL THEN newCode _ RopeCode1[", %g", NameFill[name]] ELSE newCode _ RopeCode1["%g", NameFill[name]]; openCode _ ConcatCode2[openCode, newCode]; END; END; directoryCode _ BuildEmptyCode[]; openCode _ BuildEmptyCode[]; EnumerateHashTable[usage.usageHT, ViewUseEntry]; IF NOT TestEmptyCode[openCode] THEN openCode _ RopeCode1["OPEN %g;\N", CodeFill[openCode]]; RETURN[ RopeCode1["DIRECTORY%g;\N\N", CodeFill[directoryCode]], openCode]; END; BuildImplUseCode: PUBLIC PROC[usage: UsageNode] RETURNS[directoryCode, importsCode, exportsCode, openCode: MesaCodeNode] = BEGIN ViewUseEntry: PROC[info: REF ANY, name: NameNode] = BEGIN useInfo: UseInfo _ NARROW[info]; IF IsErrorName[name] THEN RETURN; IF useInfo.bits[ref] OR useInfo.bits[import] THEN BEGIN newCode: MesaCodeNode; IF directoryCode # NIL THEN newCode _ RopeCode1[",\N\T%g", NameFill[name]] ELSE newCode _ RopeCode1["\N\T%g", NameFill[name]]; directoryCode _ ConcatCode2[directoryCode, newCode]; END; IF useInfo.bits[export] AND NOT (useInfo.bits[ref] OR useInfo.bits[import]) THEN BEGIN newCode: MesaCodeNode; IF directoryCode # NIL THEN newCode _ RopeCode1[",\N\T%g USING[]", NameFill[name]] ELSE newCode _ RopeCode1["\N\T%g USING[]", NameFill[name]]; directoryCode _ ConcatCode2[directoryCode, newCode]; END; IF useInfo.bits[import] THEN BEGIN newCode: MesaCodeNode; IF importsCode # NIL THEN newCode _ RopeCode1[", %g", NameFill[name]] ELSE newCode _ RopeCode1["%g", NameFill[name]]; importsCode _ ConcatCode2[importsCode, newCode]; END; IF useInfo.bits[export] THEN BEGIN newCode: MesaCodeNode; IF exportsCode # NIL THEN newCode _ RopeCode1[", %g", NameFill[name]] ELSE newCode _ RopeCode1["%g", NameFill[name]]; exportsCode _ ConcatCode2[exportsCode, newCode]; END; IF useInfo.bits[ref] OR useInfo.bits[import] THEN BEGIN newCode: MesaCodeNode; IF openCode # NIL THEN newCode _ RopeCode1[", %g", NameFill[name]] ELSE newCode _ RopeCode1["%g", NameFill[name]]; openCode _ ConcatCode2[openCode, newCode]; END; END; directoryCode _ BuildEmptyCode[]; importsCode _ BuildEmptyCode[]; exportsCode _ BuildEmptyCode[]; openCode _ BuildEmptyCode[]; EnumerateHashTable[usage.usageHT, ViewUseEntry]; IF NOT TestEmptyCode[importsCode] THEN importsCode _ RopeCode1[" IMPORTS %g", CodeFill[importsCode]]; IF NOT TestEmptyCode[exportsCode] THEN exportsCode _ RopeCode1[" EXPORTS %g", CodeFill[exportsCode]]; IF NOT TestEmptyCode[openCode] THEN openCode _ RopeCode1["OPEN %g;\N", CodeFill[openCode]]; RETURN[ RopeCode1["DIRECTORY%g;\N\N", CodeFill[directoryCode]], importsCode, exportsCode, openCode]; END; FakeUsageCopy: PUBLIC PROC[usage: UsageNode] RETURNS[UsageNode] = {RETURN[usage]}; ShowIndent: PROC[indent: CARDINAL, on: IO.STREAM] = BEGIN FOR I: CARDINAL IN [0..indent) DO IO.PutRope[on, " "] ENDLOOP; END; InspectContext: PUBLIC PROC[lookup: LookupContextNode] RETURNS[BOOLEAN] = BEGIN IF FALSE THEN ShowContext[lookup.global, 0, ThreeC4Support.GetReportStream[]]; RETURN[TRUE]; END; ShowContext: PUBLIC PROC[context: ContextNode, indent: CARDINAL, on: IO.STREAM] = BEGIN IF context = NIL THEN RETURN; ShowHashTable[context.types, indent, on, ShowTypeInfo]; ShowHashTable[context.abstProds, indent, on, ShowAbstractProductionInfo]; ShowHashTable[context.functions, indent, on, ShowFunctionInfo]; ShowHashTable[context.values, indent, on, ShowValueInfo]; END; ShowHashTable: PROC[table: HashTable, indent: CARDINAL, on: IO.STREAM, show: PROC[REF ANY, CARDINAL, IO.STREAM]] = BEGIN SeeOneEntry: PROC[info: REF ANY, name: NameNode] = BEGIN IF IsErrorName[name] THEN {IO.PutRope[on, "** ERROR **"]; RETURN}; ShowIndent[indent, on]; ShowName[name, on]; IO.PutRope[on, "\N"]; show[info, indent+5, on]; END; EnumerateHashTable[table, SeeOneEntry]; END; ShowTypeInfo: PROC[info: REF ANY, indent: CARDINAL, on: IO.STREAM] = BEGIN WITH info SELECT FROM ati: AbstractTypeInfo => ShowAbstractTypeInfo[ati, indent, on]; sbti: SimpleBaseTypeInfo => ShowSimpleBaseTypeInfo[sbti, indent, on]; gtti: GenericTokenTypeInfo => ShowGenericTokenTypeInfo[gtti, indent, on]; pdcti: PreDefinedCedarTypeInfo => ShowPreDefinedCedarTypeInfo[pdcti, indent, on]; cti: CedarTypeInfo => ShowCedarTypeInfo[cti, indent, on]; tti: TreeTypeInfo => ShowTreeTypeInfo[tti, indent, on]; ebti: EnumeratedBaseTypeInfo => ShowEnumeratedBaseTypeInfo[ebti, indent, on]; cmi: ControlModuleInfo => ShowControlModuleInfo[cmi, indent, on]; ei: ErrorInfo => ShowErrorInfo[ei, indent, on]; ENDCASE => ERROR; END; ShowErrorInfo: PROC[info: REF ANY, indent: CARDINAL, on: IO.STREAM] = BEGIN IO.PutRope[on, "** ERROR **"]; END; ShowFunctionInfo: PROC[info: REF ANY, indent: CARDINAL, on: IO.STREAM] = BEGIN WITH info SELECT FROM rfib: RecFcnInfo => ShowRecFcnInfo[rfib, indent, on]; bfib: BaseFcnInfo => ShowBaseFcnInfo[bfib, indent, on]; ENDCASE => ERROR; END; ShowValueInfo: PROC[info: REF ANY, indent: CARDINAL, on: IO.STREAM] = BEGIN WITH info SELECT FROM arssi: AbstractRightSideSymbolInfo => ShowAbstractRightSideSymbolInfo[arssi, indent, on]; ENDCASE => ERROR; END; ShowAbstractTypeInfo: PROC[info: AbstractTypeInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "is an abstract type, mesaDefFileName = %g\N", IO.rope[info.mesaDefFileName]]; ShowCodeNameText[info.textCodeName, indent+3, on]; ShowIndent[indent, on]; IO.PutRope[on, "\Tdefined recursive functions = ("]; ShowNameList[info.recFcnNameList, on]; IO.PutRope[on, ")\N"]; END; ShowSimpleBaseTypeInfo: PROC[info: SimpleBaseTypeInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "\Tis a simple base type, mesaDefFileName = %g\N", IO.rope[info.mesaDefFileName]]; ShowCodeNameText[info.textCodeName, indent+3, on]; END; ShowGenericTokenTypeInfo: PROC[info: GenericTokenTypeInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "\Tis a generic token type, mesaDefFileName = %g\N", IO.rope[info.mesaDefFileName]]; ShowCodeNameText[info.textCodeName, indent+3, on]; END; ShowPreDefinedCedarTypeInfo: PROC[info: PreDefinedCedarTypeInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "\Tis a pre defined Cedar type\N"]; ShowCodeNameText[info.textCodeName, indent+3, on]; END; ShowCedarTypeInfo: PROC[info: CedarTypeInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "\Tis a Cedar type, mesaDefFileName = %g\N", IO.rope[info.mesaDefFileName]]; ShowCodeNameText[info.textCodeName, indent+5, on]; END; ShowTreeTypeInfo: PROC[info: TreeTypeInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "\Tis a Tree type\N"]; ShowCodeNameText[info.textCodeName, indent+5, on]; END; ShowEnumeratedBaseTypeInfo: PROC[info: EnumeratedBaseTypeInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "\Tis an Enumerated Base Type, mesaDefFileName = %g\N", IO.rope[info.mesaDefFileName]]; ShowCodeNameText[info.textCodeName, indent+5, on]; ShowIndent[indent+5, on]; IO.PutRope[on, "value names = ("]; ShowNameList[info.names, on]; IO.PutF[on, ")\N"]; END; ShowControlModuleInfo: PROC[info: ControlModuleInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "\Tis control module info, mesaDefFileName = %g\N", IO.rope[info.mesaDefFileName]]; END; ShowRecFcnInfo: PROC[info: RecFcnInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "\Tis a recursive function, mesaDefFileName = %g\N", IO.rope[info.mesaDefFileName]]; ShowIndent[indent, on]; IO.PutF[on, "\Twith arg types = ("]; ShowTypeList[info.argTypes, on]; IO.PutF[on, "), result types = ("]; ShowTypeList[info.resultTypes, on]; IO.PutF[on, ")\N"]; ShowFcnDefGraph[info.defGraph, indent+2, on]; END; ShowBaseFcnInfo: PROC[info: BaseFcnInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "\Tis a base function, mesaDefFileName = %g\N", IO.rope[info.mesaDefFileName]]; ShowIndent[indent, on]; IO.PutF[on, "\Twith arg types = ("]; ShowTypeList[info.argTypes, on]; IO.PutF[on, "), result types = ("]; ShowTypeList[info.resultTypes, on]; IO.PutF[on, ")\N"]; ShowFcnDefGraph[info.defGraph, indent+2, on]; END; ShowAbstractProductionInfo: PROC[api: REF ANY, indent: CARDINAL, on: IO.STREAM] = BEGIN info: AbstractProductionInfo _ NARROW[api]; ShowIndent[indent, on]; IO.PutF[on, "is an abstract production, mesaDefFileName = %g\N", IO.rope[info.mesaDefFileName]]; ShowIndent[indent+5, on]; IO.PutF[on, "type = %g, case = %g\N", IO.rope[info.abstractTypeId.text], IF info.caseId # NIL THEN IO.rope[info.caseId.text] ELSE IO.rope[""]]; ShowIndent[indent+5, on]; IO.PutRope[on, "right side names = ("]; ShowNameList[info.rightSideNames, on]; IO.PutRope[on, ")\N"]; ShowIndent[indent+5, on]; IO.PutRope[on, "local context follows:\N"]; ShowContext[info.productionContext.context, indent+10, on]; END; ShowAbstractRightSideSymbolInfo: PROC[info: AbstractRightSideSymbolInfo, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutRope[on, "type = "]; ShowName[info.typeName, on]; IO.PutRope[on, "\N"]; END; ShowCodeName: PROC[codeName: MesaCodeNode, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "with codeName = "]; ShowCode[codeName, on]; IO.PutRope[on, "\N"]; END; ShowCodeNameText: PROC[text: Rope.ROPE, indent: CARDINAL, on: IO.STREAM] = BEGIN ShowIndent[indent, on]; IO.PutF[on, "with codeName = %g\N", IO.rope[text]]; END; ShowId: PROC[id: IdentifierNode, on: IO.STREAM] = {IO.PutF[on, "%g", IO.rope[id.text]]}; -- some error recovery base functions BPrintError: PUBLIC PROC [b: BOOLEAN, msg: Rope.ROPE] RETURNS [BOOLEAN] = BEGIN IF NOT b THEN PrintError[msg]; RETURN [b]; END; BPrintBadName: PUBLIC PROC [b: BOOLEAN, name: NameNode, msg: Rope.ROPE] RETURNS [BOOLEAN] = BEGIN IF NOT b THEN PrintBadName[name, msg]; RETURN [b]; END; BAbort: PUBLIC PROC [b: BOOLEAN] RETURNS [BOOLEAN] = BEGIN IF NOT b THEN ERROR UnrecoveredError; RETURN [b]; END; True: PUBLIC PROC RETURNS [BOOLEAN] = {RETURN [TRUE]}; False: PUBLIC PROC RETURNS [BOOLEAN] = {RETURN [FALSE]}; MarkErrors: PUBLIC PROC RETURNS [BOOLEAN] = BEGIN globalEnv: GlobalEnvHandle; globalEnv _ GetGlobalEnv[]; globalEnv.errorMark _ globalEnv.errorCount; RETURN [TRUE]; END; AreErrors: PUBLIC PROC RETURNS [BOOLEAN] = BEGIN globalEnv: GlobalEnvHandle; globalEnv _ GetGlobalEnv[]; RETURN [globalEnv.errorCount > globalEnv.errorMark]; END; END.. VThreeC4PrimImpl3.mesa: October 18, 1985 9:52:32 am PDT Sturgis, June 28, 1986 1:27:57 pm PDT Shoup, July 1, 1986 0:29:01 am PDT there will be one of the following with name "Tree$" Note: a Mesa definition file name can be built from a base by Concat[baseName, "Def.mesa"] damages context argument, result shares with names argument damages context argument. result shares with name list argument damages context argument damages context argument damages context argument damages context argument damages context argument damages context argument result shares with the two list arguments damages context argument result shares with the two list arguments damages context argument result shares with the two list arguments damages context argument result shares with the two list arguments damages context argument damages context argument damages context argument damages context argument damages context argument damages context argument used for other varieties of parse trees (e.g. tran4) used for other varieties of parse trees (e.g. tran4) used, for example, by tran4 exported to Tran4BridgeDef Lookup contexts argument is shared with result both arguments are shared with result neither shares nor affects any argument 1st arg shared with both results 1st arg shared with first result 1st arg shared with result used, for example, by tran4 exported to Tran4BridgeDef first arg shared with argTypes result this is called during build expressions, and returns the abstract type associated with the concrete type. i.e. for GenericTokens, returns the GenericToken type itself, for NonTerminals, returns the associated AbstractType, for rope terminals, it is an error. damages usage argument damages usage argument damages usage argument damages usage argument damages usage argument damages usage argument to be marked as damaging its argument context print code Ê®˜Jšœ6™6šœ%™%Icode™"—J˜šÏk ˜ Jšœ&˜&Jšœ½˜½Jšœ>˜>J˜8J˜J˜J˜¯J˜J˜+J˜J˜'J˜J˜—J˜šœœœœÏ˜öJš œVœ˜vJ˜˜J˜—J˜J˜J˜J˜(˜&J˜J˜J˜J˜J˜JJ˜J˜—J˜J˜4J˜BJ˜J˜2˜$J˜J˜J˜J˜J˜J˜—J˜6˜&J˜!J˜J˜—J˜J˜>˜*J˜%J˜J˜J˜—J˜J˜>˜*J˜J˜'J˜J˜J˜&J˜—J˜H˜/J˜—J˜J˜:˜(J˜#J˜J˜—J˜J˜@˜+J˜&J˜—J˜J˜,˜!J˜J˜J˜—˜J™4—J˜*˜ J˜)J˜—J˜J˜&˜J˜CJ˜J˜J˜J˜—J˜J˜(˜J˜DJ˜J˜J˜J˜—J˜J˜*˜ J˜EJ˜J˜J˜J˜—J˜J˜,˜!J˜DJ˜—J˜J˜:˜(J˜MJ˜J˜—J˜J˜.˜"J˜KJ˜J˜ J˜—J˜4˜%J˜NJ˜—J˜J˜,˜!J˜JJ˜—J˜J˜$˜J˜GJ˜J˜J˜—˜/J˜J˜$J˜—J˜˜0J˜J˜%J˜—J˜˜=J˜J˜.J˜J˜—J˜™ZJ™J™—˜5J˜˜J˜J˜J˜J˜J˜J˜J˜—J˜J˜—˜SJ˜—J˜˜GJ˜+—J˜˜ÈJ˜J˜J˜J˜+J˜J˜˜J˜J˜CJ˜J˜—J˜‡J˜J˜—J˜˜’J˜J˜J˜J˜+J˜J˜˜J˜J˜CJ˜˜J˜——J˜kJ˜J˜—˜J™;—˜«J˜J˜J˜J˜+J˜J˜J˜J˜˜J˜J˜CJ˜J˜—J˜vJ˜J˜—˜J™J™%—˜ÌJ˜J˜J˜J˜5J˜J˜(J˜J˜J˜J˜J™—˜wJ˜J˜DJ˜J˜QJ˜J˜—˜J™—˜J˜J˜J˜J˜+J˜J˜˜J˜J˜CJ˜J˜—J˜mJ˜J˜—˜J™—˜”J˜J˜J˜J˜+J˜J˜˜J˜J˜CJ˜J˜—J˜mJ˜J˜—˜J™—˜{J˜J˜J˜J˜+J˜J˜˜J˜J˜CJ˜˜J˜——J˜_J˜J˜—˜J™—˜J˜J˜J˜J˜+J˜J˜˜J˜J˜CJ˜J˜—J˜fJ˜J˜—˜J™J™)—˜¬J˜˜VJ˜—J˜J˜hJ˜J˜—˜J™J™)—˜ÆJ˜˜VJ˜—J˜J˜qJ˜J˜—J˜˜J™J™)—˜ÃJ˜˜VJ˜—J˜J˜pJ˜J˜J˜J™J™)—˜ÄJ˜˜VJ˜—J˜J˜qJ˜J˜J™J™—˜vJ˜J˜*J˜J˜TJ˜J˜—˜J™—šœY˜YJ˜J˜7J˜LJ˜J˜—˜J˜J™—˜rJ˜J˜J˜J˜BJ˜J˜!˜#J˜J˜@J˜J˜—J˜YJ˜J˜—˜J™—˜fJ˜J˜+J˜J˜QJ˜J˜—˜J™—šœi˜iJ˜Jšœg˜gJ˜J˜J˜—˜J™—šœ”˜”Jšœ˜J˜J˜J˜+J˜J˜˜J˜J˜@J˜J˜—J˜sJ˜Jšœ˜—J˜˜nJ˜J˜+J˜J˜HJ˜J˜J˜—˜YJ˜J˜J˜J˜&J˜J˜+J˜ ˜J˜(J˜J˜—J˜J˜J™4—˜mJ˜J˜+J˜J˜*J˜J˜J™J™4—˜XJ˜J˜J˜J˜4J˜J˜+˜J˜J˜HJ˜J˜—J˜ J˜—J˜˜J™J™—˜hJ˜J˜J˜*J˜J˜%J˜J˜J˜—˜OJ˜J˜J˜J˜3J˜J˜&˜J˜J˜fJ˜J˜—J˜J˜—J˜˜DJ˜˜"Jšœ<˜˜>JšœC˜CJšœJ˜JJšœ2˜2Jšœ*˜*JšœG˜GJšœ˜—Jšœ˜—J˜˜BJ˜J˜˜"J˜J˜;J˜J˜J˜—J˜"J˜—˜J˜—˜CJ˜˜"J˜aJ˜J˜J˜J˜yJ˜—J˜—J˜˜FJ˜J˜1J˜—J˜J™J˜J˜4˜,J˜J˜J˜J˜—J˜J˜ ˜J˜J˜J˜—J˜J˜ ˜J˜J˜J˜J˜J™—˜WJ˜>J˜—˜[J˜J˜J™%—˜yJ˜J˜&J˜DJ˜—˜J™'—˜{J˜J˜kJ˜˜/J˜J˜J˜!J˜J˜9J˜J˜—J˜J˜(J˜J˜J˜—˜KJ˜˜3J˜J˜˜FJ˜J˜J˜J˜-J˜J˜J˜J˜J˜*J˜J˜J˜—˜J˜9J˜;J˜:—J˜J˜J˜—J˜9J˜˜J˜—J˜—˜lJ˜J˜J˜J˜5J˜J˜1˜J˜J˜OJ˜J˜—˜J˜3J˜ˆ—J˜J˜—˜J™ —˜yJ˜J˜J˜J˜5J˜J˜4˜J˜J˜UJ˜J˜—˜J˜RJ˜—J˜—˜J™ —˜pJ˜J˜J˜J˜QJ˜J˜3˜J˜J˜WJ˜4J˜—˜J˜HJ˜­—J˜J˜J˜J™—˜gJ˜J˜J˜J˜4J˜J˜3˜J˜J˜gJ˜J˜—˜J˜(J˜)J˜ —J˜—J˜˜ZJ˜J˜J˜J˜7J˜J˜0˜J˜J˜jJ˜J˜—J˜J˜—˜J™J™—˜^J˜J˜J˜J˜7J˜J˜0˜J˜J˜jJ˜J˜—J˜ J˜—J˜˜oJ˜J˜J˜J˜J˜J˜˜G˜!J˜;—J˜—J˜J˜*J˜˜J˜J˜;J˜"J˜J˜J˜˜GJ˜J˜—J˜J˜EJ˜JJ˜—J˜J˜J˜J˜FJ˜3J˜J˜—J˜˜pJ˜J˜J˜*˜J˜J˜'J˜˜J˜J˜HJ˜J˜—˜J˜$J˜p—J˜—J˜šœq˜qJ˜˜*J˜J˜GJ˜pJ˜J˜—J˜J˜J™ƒ—šœ_˜_J˜J˜J˜J˜4J˜J˜5˜(J˜J˜2J˜–—J˜J˜,J˜,˜J˜6J˜–J˜–—J˜—J˜˜rJ˜J˜J˜J˜JJ˜J˜0˜J˜J˜QJ˜0J˜—˜˜J˜J˜bJ˜.J˜˜#J˜¢—J˜J˜'J˜J˜—J˜—J˜—J˜˜aJ˜J˜4J˜˜JJ˜6J˜—J˜5J˜J˜—˜9J˜J˜J˜J˜—˜IJ˜(—J˜J˜J˜ J˜J˜$˜$J˜—J˜J˜J˜ ˜J˜—J˜J˜˜1J˜3—˜J™—˜QJ˜J˜J˜"˜J˜8J˜J˜0J˜5J˜#J˜@J˜J˜—J˜/J˜ J˜—˜J™—˜WJ˜˜J˜%—J˜J˜J˜—˜J™—˜vJ˜J˜J˜J˜J˜)J˜J˜1˜J˜J˜GJ˜J˜—˜J˜2J˜3J˜4J˜—J˜/J˜ J˜—˜J™—˜{J˜J˜J˜J˜)J˜J˜2˜J˜J˜QJ˜J˜—˜%J˜—˜J˜J˜-J˜+J˜/J˜J˜—J˜—˜J™—˜J˜J˜J˜J˜)J˜J˜.˜J˜J˜KJ˜J˜—˜%J˜—˜J˜J˜+J˜+J˜/J˜J˜—J˜—˜J™—˜`J˜J˜eJ˜5J˜>J˜ J˜—J˜šœd˜dJ˜J˜0J˜J˜—J˜J˜J˜%J˜J˜˜AJ˜J˜J˜J˜J˜%J˜J˜2J˜&J˜Q˜J˜J˜0J˜)J˜—J˜J˜—J˜˜pJ˜J˜)J˜˜3J˜J˜ J˜J˜!J˜J˜*˜1J˜J˜˜JJ˜4—J˜4J˜—˜PJ˜J˜˜RJ˜;—J˜4J˜—˜1J˜J˜˜BJ˜/—J˜*J˜—J˜J˜—J˜!J˜J˜J˜0J˜J˜J˜[J˜˜J˜7J˜ J˜—J˜J˜—˜zJ˜J˜˜3J˜J˜ J˜J˜!J˜˜1J˜J˜˜JJ˜4—J˜4J˜—˜PJ˜J˜˜RJ˜;—J˜4J˜—˜J˜J˜˜EJ˜/—J˜0J˜—˜J˜J˜˜EJ˜/—J˜0J˜—J˜˜1J˜J˜˜BJ˜/—J˜*J˜—J˜J˜—J˜!J˜J˜J˜J˜J˜0J˜J˜eJ˜eJ˜[J˜J˜˜J˜7J˜ J˜ J˜ J˜—J˜—˜J™%—˜AJ˜—J™J™J™J˜˜3J˜J˜>J˜—J˜˜IJ˜J˜NJ˜ J˜—J˜˜QJ˜J˜J˜7J˜IJ˜?J˜9J˜—J˜˜rJ˜˜2J˜J˜BJ˜AJ˜J˜—J˜'J˜—J˜˜DJ˜˜J˜?J˜EJ˜IJ˜QJ˜9J˜7J˜MJ˜AJ˜/J˜—J˜—J˜˜FJ˜J˜J˜—J˜˜IJ˜˜J˜5J˜7J˜—J˜—J˜˜FJ˜˜J˜YJ˜—J˜—J˜˜UJ˜J˜rJ˜3J˜LJ˜&J˜J˜—J˜˜YJ˜J˜vJ˜2J˜—J˜˜]J˜J˜xJ˜2J˜—J˜˜cJ˜J˜GJ˜2J˜—J˜˜OJ˜J˜pJ˜2J˜—J˜˜MJ˜J˜:J˜2J˜—J˜˜aJ˜J˜{J˜2J˜