-- AMTypesAImpl.Mesa -- Paul Rovner, March 4, 1983 4:01 pm -- NOTE do Equal, AsGoodAs -- try to avoid acquisition of already acquired symbol tables -- status stuff is wrong. -- Russ Atkinson, April 4, 1983 8:06 pm -- IndexToName[seqType, 0] now returns tag name -- IndexToName, NameToIndex & IndexToType cache values for union types DIRECTORY AMBridge USING [SetTVFromLC, SetTVFromLI, TVForReferent], AMTypes USING[Class, Index, Status, TypedVariable, ErrorReason, New, TypeClass, Size], BrandXSymbolDefs USING[SymbolConstructorIndex, SymbolIdIndex, nullSymbolIndex, SymbolModuleIndex, thisModuleIndex, symbolIndexForANY], BrandYSymbolDefs USING[SymbolConstructorIndex, SymbolIdIndex, nullSymbolIndex, SymbolModuleIndex, thisModuleIndex, symbolIndexForANY], Rope USING [ROPE, Equal], RTBasic USING [nullType], RTStorageOps USING[NewObject], RTSymbolDefs USING [SymbolTableBase, SymbolConstructorIndex, SymbolContextIndex, SymbolIdIndex, SymbolRecordIndex, SymbolIndex, nullBase], RTSymbolOps USING [EnumerateCtxIseis, EnumerateRecordIseis, CountComponents, AcquireType, AcquireSequenceType, AcquireRope, STBToModuleName, SEUnderType, ISEConstant, IDCardinalValue, ISEName, ISEImmutable, ISEType, ISEInfo], RTSymbols USING [GetTypeSymbols, GetOriginalTypeSymbols, ReleaseSTB], RTTCache USING[RefEntry, LookupRef, FillRefEntry, IntEntry, LookupInt, FillIntEntry, ComponentMap, NewComponentMap, FillTypeComponent, FillNameComponent, GetComponentAtIndex, GetComponentForName, ComponentEntry], RTTypesBasic USING[Type, unspecType, nullType, fhType, gfhType, listOfRefAnyType, refAnyType, anyType], RTTypesPrivate USING[]; AMTypesAImpl: PROGRAM IMPORTS AMBridge, AMTypes, Rope, RTStorageOps, RTSymbolOps, RTSymbols, RTTCache EXPORTS AMTypes, RTTypesPrivate = BEGIN OPEN AMBridge, AMTypes, bx: BrandXSymbolDefs, by: BrandYSymbolDefs, Rope, RTTypesBasic, RTSymbolDefs, RTSymbolOps, RTSymbols, RTStorageOps; -- E R R O R Error: PUBLIC ERROR[ reason: ErrorReason, msg: ROPE _ NIL, type: Type _ RTBasic.nullType,-- used with TypeFault, IncompatibleTypes otherType: Type _ RTBasic.nullType -- used with IncompatibleTypes ] = CODE; -- P U B L I C P R O C E D U R E S -- These procedures have applicability restrictions, noted as comments -- MOVE NComponents: PUBLIC SAFE PROC[type: Type--record, structure--] RETURNS [ans: Index] = TRUSTED { entry: RTTCache.IntEntry; int: INT; IF type = nullType THEN RETURN[0]; entry _ RTTCache.LookupInt[type, NComponents]; int _ entry.int; IF int >= 0 THEN RETURN [int]; {stb: SymbolTableBase; sei: SymbolIndex; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; csei: SymbolConstructorIndex _ SEUnderType[stb, sei]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM record => ans _ CountComponents[stb, LOOPHOLE[csei]]; definition => {proc: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {ans _ ans + 1; RETURN[FALSE]}; ans _ 0; [] _ EnumerateCtxIseis[stb, [x[ser.defCtx]], proc]}; ENDCASE => ERROR Error[reason: typeFault, type: type]; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM record => ans _ CountComponents[stb, LOOPHOLE[csei]]; definition => {proc: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {ans _ ans + 1; RETURN[FALSE]}; ans _ 0; [] _ EnumerateCtxIseis[stb, [y[ser.defCtx]], proc]}; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR; }; ReleaseSTB[stb]}; [] _ RTTCache.FillIntEntry[entry, ans]; }; -- This returns the Type of the specified component of -- instances of the type. index starts at 1. -- break up and MOVE IndexToType: PUBLIC SAFE PROC[type: Type--record, structure, union--, index: Index] RETURNS[ans: Type] = TRUSTED { proc1: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] = { ans _ IF index = 0 THEN AcquireType[stb, ISEType[stb, isei]] ELSE AcquireType[stb, ISEInfo[stb, isei]]}; proc2: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] = { sei: SymbolIndex _ ISEType[stb, isei]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH cse: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.x].e]] SELECT FROM sequence => {recstb: SymbolTableBase; recsei: SymbolIndex; [recstb, recsei] _ GetTypeSymbols[type]; ans _ AcquireSequenceType[stb, sei, recstb, LOOPHOLE[SEUnderType[recstb, recsei], SymbolRecordIndex] ! UNWIND => ReleaseSTB[recstb]]; ReleaseSTB[recstb]}; ref => {IF cse.var THEN sei _ [x[cse.refType]]; ans _ AcquireType[stb, sei]}; ENDCASE => ans _ AcquireType[stb, sei]; t: SymbolTableBase.y => WITH cse: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.y].e]] SELECT FROM sequence => {recstb: SymbolTableBase; recsei: SymbolIndex; [recstb, recsei] _ GetTypeSymbols[type]; ans _ AcquireSequenceType[stb, sei, recstb, LOOPHOLE[SEUnderType[recstb, recsei], SymbolRecordIndex] ! UNWIND => ReleaseSTB[recstb]]; ReleaseSTB[recstb]}; ref => {IF cse.var THEN sei _ [y[cse.refType]]; ans _ AcquireType[stb, sei]}; ENDCASE => ans _ AcquireType[stb, sei]; ENDCASE => ERROR; }; entry: RTTCache.RefEntry; map: RTTCache.ComponentMap; class: Class; n: NAT _ 0; type _ UnderType[type]; class _ TypeClass[type]; SELECT class FROM record, structure => n _ NComponents[type]; union => n _ NValues[Domain[type]]; ENDCASE => ERROR Error[reason: typeFault, type: type]; entry _ RTTCache.LookupRef[type, IndexToType]; map _ NARROW[entry.ref, RTTCache.ComponentMap]; IF map # NIL AND index IN [1..map.len] AND map[index-1].validType THEN RETURN [map[index-1].type]; SELECT class FROM record, structure => RecordComponentISEI[type, index, proc2]; union => ComponentISEI[type, index, proc1]; ENDCASE => ERROR Error[reason: typeFault, type: type]; IF n > 0 AND index IN [1..n] THEN {-- put the answer back into the cache IF map = NIL THEN [] _ RTTCache.FillRefEntry[entry, map _ RTTCache.NewComponentMap[n]]; [] _ RTTCache.FillTypeComponent[map, index-1, ans]}; }; -- This returns the Status of the specified component of -- instances of the type. index starts at 1. -- MOVE IndexToStatus: PUBLIC PROC[type: Type--record, structure--, index: Index] RETURNS[ans: Status] = { proc: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] = {ans _ (IF ISEImmutable[stb, isei] THEN readOnly ELSE IF ISEConstant[stb, isei] THEN const ELSE mutable)}; RecordComponentISEI[type, index, proc]}; -- index starts at 1 -- raises typeFault, badName -- break up and MOVE NameToIndex: PUBLIC SAFE PROC [type: Type--record, structure, union, enumerated--, name: ROPE] RETURNS[ans: CARDINAL _ 0] = TRUSTED { enumerated: BOOLEAN _ FALSE; stb: SymbolTableBase; sei: SymbolIndex; class: Class; n: INT _ 0; found: BOOL _ FALSE; entry: RTTCache.RefEntry; map: RTTCache.ComponentMap; proc: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {IF enumerated THEN ans _ IDCardinalValue[stb, isei] + 1 ELSE ans _ ans + 1; stop _ Equal[name, AcquireRope[stb, ISEName[stb, isei]]]}; type _ UnderType[type]; class _ TypeClass[type]; SELECT class FROM record, structure => n _ NComponents[type]; enumerated => n _ NValues[type]; union => n _ NValues[Domain[type]]; ENDCASE; IF n IN [1..256) THEN {entry _ RTTCache.LookupRef[type, IndexToType]; map _ NARROW[entry.ref, RTTCache.ComponentMap]; IF map # NIL THEN {int: INT _ RTTCache.GetComponentForName[map, name].index; IF int >= 0 THEN RETURN [int+1]}}; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; WITH stb SELECT FROM t: SymbolTableBase.x => {csei: bx.SymbolConstructorIndex _ t.e.UnderType[NARROW[sei, SymbolIndex.x].e]; WITH ser: t.e.seb[csei] SELECT FROM record => {srx: SymbolIndex = [x[csei]]; found _ EnumerateRecordIseis[stb, LOOPHOLE[srx, SymbolRecordIndex], proc]}; definition => found _ EnumerateCtxIseis[stb, [x[ser.defCtx]], proc]; union => found _ EnumerateCtxIseis[stb, [x[ser.caseCtx]], proc]; enumerated => {enumerated _ TRUE; found _ EnumerateCtxIseis[stb, [x[ser.valueCtx]], proc]}; ENDCASE => ERROR Error[reason: typeFault, type: type]}; t: SymbolTableBase.y => {csei: by.SymbolConstructorIndex _ t.e.UnderType[NARROW[sei, SymbolIndex.y].e]; WITH ser: t.e.seb[csei] SELECT FROM record => {srx: SymbolIndex = [y[csei]]; found _ EnumerateRecordIseis[stb, LOOPHOLE[srx, SymbolRecordIndex], proc]}; definition => found _ EnumerateCtxIseis[stb, [y[ser.defCtx]], proc]; union => found _ EnumerateCtxIseis[stb, [y[ser.caseCtx]], proc]; enumerated => {enumerated _ TRUE; found _ EnumerateCtxIseis[stb, [y[ser.valueCtx]], proc]}; ENDCASE => ERROR Error[reason: typeFault, type: type]}; ENDCASE => ERROR; }; ReleaseSTB[stb]; IF NOT found THEN ERROR Error[reason: badName, type: type, msg: name]; IF ans > 0 AND n IN [1..256) THEN {IF map = NIL THEN [] _ RTTCache.FillRefEntry[entry, map _ RTTCache.NewComponentMap[n]]; [] _ RTTCache.FillNameComponent[map, ans-1, name]}; }; -- end NameToIndex -- break up and MOVE IndexToName: PUBLIC SAFE PROC[type: Type--record, structure, union, enumerated--, index: CARDINAL] RETURNS[ans: ROPE] = TRUSTED {proc: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] = {ans _ AcquireRope[stb, ISEName[stb, isei]]}; n: INT _ 0; class: Class; entry: RTTCache.RefEntry; map: RTTCache.ComponentMap _ NIL; type _ UnderType[type]; class _ TypeClass[type]; SELECT class FROM record, structure => n _ NComponents[type]; enumerated => n _ NValues[type]; union, sequence => IF index = 0 THEN { -- RRA: the tag name is cached differently from other component names entry _ RTTCache.LookupRef[type, IndexToName]; IF entry.valid THEN RETURN [NARROW[entry.ref]]; ComponentISEI[type, 0, proc]; entry.ref _ ans; entry.valid _ TRUE; RETURN} ELSE { -- RRA: only union types are further processed IF class = sequence THEN GO TO err; n _ NValues[Domain[type]]; }; ENDCASE; IF n IN [1..256) THEN {entry _ RTTCache.LookupRef[type, IndexToType]; map _ NARROW[entry.ref, RTTCache.ComponentMap]; IF map = NIL THEN [] _ RTTCache.FillRefEntry[entry, map _ RTTCache.NewComponentMap[n]]; IF index IN [1..map.len] THEN {comp: RTTCache.ComponentEntry _ RTTCache.GetComponentAtIndex[map, index-1]; IF comp.validName THEN RETURN [comp.name]}; }; SELECT class FROM record, structure => RecordComponentISEI[type, index, proc]; union, enumerated => ComponentISEI[type, index, proc]; ENDCASE => GO TO err; IF map # NIL THEN [] _ RTTCache.FillNameComponent[map, index-1, ans]; EXITS err => ERROR Error[reason: typeFault, type: type]; }; -- MOVE IsPacked: PUBLIC SAFE PROC[type: Type--array, sequence--] RETURNS [ans: BOOLEAN] = TRUSTED { stb: SymbolTableBase; sei: SymbolIndex; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.x].e]] SELECT FROM array => ans _ ser.packed; sequence => ans _ ser.packed; ENDCASE => ERROR Error[reason: typeFault, type: type]; t: SymbolTableBase.y => WITH ser: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.y].e]] SELECT FROM array => ans _ ser.packed; sequence => ans _ ser.packed; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR; ReleaseSTB[stb]; }}; -- break up and MOVE -- MOVE Domain: PUBLIC SAFE PROC [type: Type--array, sequence, union, transfer, descriptor, longDescriptor, relativePointer--] RETURNS[ans: Type] = TRUSTED { stb: SymbolTableBase; sei: SymbolIndex; entry: RTTCache.IntEntry; int: INT; entry _ RTTCache.LookupInt[type, Domain]; int _ entry.int; IF int >= 0 THEN {card: CARDINAL _ int; RETURN [LOOPHOLE[card]]}; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.x].e]] SELECT FROM relative => ans _ AcquireType[stb, [x[ser.offsetType]]]; array => ans _ AcquireType[stb, [x[ser.indexType]]]; sequence => ans _ AcquireType[stb, [x[t.e.seb[ser.tagSei].idType]]]; union => ans _ AcquireType[stb, [x[t.e.seb[ser.tagSei].idType]]]; transfer => ans _ (IF ser.typeIn = bx.nullSymbolIndex THEN nullType ELSE AcquireType[stb, [x[ser.typeIn]]]); ENDCASE => ERROR Error[reason: typeFault, type: type]; t: SymbolTableBase.y => WITH ser: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.y].e]] SELECT FROM relative => ans _ AcquireType[stb, [y[ser.offsetType]]]; array => ans _ AcquireType[stb, [y[ser.indexType]]]; sequence => ans _ AcquireType[stb, [y[t.e.seb[ser.tagSei].idType]]]; union => ans _ AcquireType[stb, [y[t.e.seb[ser.tagSei].idType]]]; transfer => ans _ (IF ser.typeIn = by.nullSymbolIndex THEN nullType ELSE AcquireType[stb, [y[ser.typeIn]]]); ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR; ReleaseSTB[stb]}; -- end ENABLE UNWIND [] _ RTTCache.FillIntEntry[entry, LOOPHOLE[ans, CARDINAL]]}; --applicable to array, sequence, procedure, signal, process, address (not atom, rope)-- -- break up and MOVE Range: PUBLIC SAFE PROC[type: Type] RETURNS[ans: Type] = TRUSTED { stb: SymbolTableBase; sei: SymbolIndex; entry: RTTCache.IntEntry; int: INT; entry _ RTTCache.LookupInt[type, Range]; int _ entry.int; IF int >= 0 THEN {card: CARDINAL _ int; RETURN [LOOPHOLE[card]]}; SELECT TypeClass[UnderType[type]] FROM array, sequence, procedure, signal, process, list, ref, pointer, longPointer, descriptor, longDescriptor, relativePointer, basePointer => NULL; ENDCASE => ERROR Error[reason: typeFault, type: type]; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.x].e]] SELECT FROM array => ans _ AcquireType[stb, [x[ser.componentType]]]; sequence => ans _ AcquireType[stb, [x[ser.componentType]]]; transfer => ans _ (IF ser.typeOut = bx.nullSymbolIndex THEN nullType ELSE AcquireType[stb, [x[ser.typeOut]]]); relative => ans _ Range[AcquireType[stb, [x[ser.resultType]]]]; ref => {IF ser.counted THEN ERROR Error[reason: typeFault, type: type]; ans _ (IF t.e.UnderType[ser.refType] = bx.symbolIndexForANY THEN unspecType ELSE AcquireType[stb, [x[ser.refType]]])}; arraydesc => ans _ AcquireType[stb, [x[ser.describedType]]]; long => WITH rse: t.e.seb[t.e.UnderType[ser.rangeType]] SELECT FROM ref => ans _ (IF t.e.UnderType[rse.refType] = bx.symbolIndexForANY THEN unspecType ELSE AcquireType[stb, [x[rse.refType]]]); arraydesc => ans _ AcquireType[stb, [x[rse.describedType]]]; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR Error[reason: typeFault, type: type]; t: SymbolTableBase.y => WITH ser: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.y].e]] SELECT FROM array => ans _ AcquireType[stb, [y[ser.componentType]]]; sequence => ans _ AcquireType[stb, [y[ser.componentType]]]; transfer => ans _ (IF ser.typeOut = by.nullSymbolIndex THEN nullType ELSE AcquireType[stb, [y[ser.typeOut]]]); relative => ans _ Range[AcquireType[stb, [y[ser.resultType]]]]; ref => {IF ser.counted THEN ERROR Error[reason: typeFault, type: type]; ans _ (IF t.e.UnderType[ser.refType] = by.symbolIndexForANY THEN unspecType ELSE AcquireType[stb, [y[ser.refType]]])}; arraydesc => ans _ AcquireType[stb, [y[ser.describedType]]]; long => WITH rse: t.e.seb[t.e.UnderType[ser.rangeType]] SELECT FROM ref => ans _ (IF t.e.UnderType[rse.refType] = by.symbolIndexForANY THEN unspecType ELSE AcquireType[stb, [y[rse.refType]]]); arraydesc => ans _ AcquireType[stb, [y[rse.describedType]]]; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR; ReleaseSTB[stb]}; -- END ENABLE UNWIND [] _ RTTCache.FillIntEntry[entry, LOOPHOLE[ans, CARDINAL]]}; -- end Range -- MOVE ReferentStatus: PUBLIC SAFE PROC [type: Type--address--] RETURNS [ans: Status] = TRUSTED { stb: SymbolTableBase; sei: SymbolIndex; entry: RTTCache.IntEntry; int: INT; entry _ RTTCache.LookupInt[type, ReferentStatus]; int _ entry.int; IF int >= 0 THEN {card: CARDINAL _ int; RETURN [LOOPHOLE[card]]}; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; readOnlyReferent: BOOLEAN _ FALSE; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.x].e]] SELECT FROM long => WITH ser1: t.e.seb[t.e.UnderType[ser.rangeType]] SELECT FROM arraydesc => readOnlyReferent _ ser1.readOnly; ref => readOnlyReferent _ ser1.readOnly; ENDCASE => ERROR Error[reason: typeFault, type: type]; ref => readOnlyReferent _ ser.readOnly; relative => WITH ser2: t.e.seb[t.e.UnderType[ser.resultType]] SELECT FROM long => WITH ser1: t.e.seb[t.e.UnderType[ser2.rangeType]] SELECT FROM ref => readOnlyReferent _ ser1.readOnly; ENDCASE => ERROR Error[reason: typeFault, type: type]; ref => readOnlyReferent _ ser2.readOnly; ENDCASE => ERROR Error[reason: typeFault, type: type]; arraydesc => readOnlyReferent _ ser.readOnly; ENDCASE => ERROR Error[reason: typeFault, type: type]; t: SymbolTableBase.y => WITH ser: t.e.seb[t.e.UnderType[NARROW[sei, SymbolIndex.y].e]] SELECT FROM long => WITH ser1: t.e.seb[t.e.UnderType[ser.rangeType]] SELECT FROM arraydesc => readOnlyReferent _ ser1.readOnly; ref => readOnlyReferent _ ser1.readOnly; ENDCASE => ERROR Error[reason: typeFault, type: type]; ref => readOnlyReferent _ ser.readOnly; relative => WITH ser2: t.e.seb[t.e.UnderType[ser.resultType]] SELECT FROM long => WITH ser1: t.e.seb[t.e.UnderType[ser2.rangeType]] SELECT FROM ref => readOnlyReferent _ ser1.readOnly; ENDCASE => ERROR Error[reason: typeFault, type: type]; ref => readOnlyReferent _ ser2.readOnly; ENDCASE => ERROR Error[reason: typeFault, type: type]; arraydesc => readOnlyReferent _ ser.readOnly; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR; ReleaseSTB[stb]; ans _ IF readOnlyReferent THEN readOnly ELSE mutable}; -- end ENABLE UNWIND [] _ RTTCache.FillIntEntry[entry, LOOPHOLE[ans, CARDINAL]]}; -- end ReferentStatus -- break up and MOVE TypeToName: PUBLIC SAFE PROC [type: Type--definition--, moduleName, fileName: REF ROPE _ NIL] RETURNS [ans: ROPE] = TRUSTED { IF type = nullType THEN RETURN[NIL]; IF type = unspecType THEN RETURN ["UNSPECIFIED"]; IF type = fhType THEN RETURN ["SomeFrameHandle"]; IF type = gfhType THEN RETURN["SomeGlobalFrameHandle"]; IF type = listOfRefAnyType THEN RETURN["ListOfREFANY"]; IF type = refAnyType THEN RETURN["REFANY"]; IF type = anyType THEN RETURN["ANY"]; { stb: SymbolTableBase _ nullBase; sei: SymbolIndex; class: Class _ TypeClass[type]; IF class = atom THEN RETURN["ATOM"] ELSE IF class = rope THEN RETURN["ROPE"]; IF moduleName # NIL OR fileName # NIL THEN [stb, sei] _ GetOriginalTypeSymbols[type ! Error => CONTINUE]; IF stb = nullBase THEN [stb, sei] _ GetTypeSymbols[type]; WITH stb SELECT FROM t: SymbolTableBase.x => { ENABLE UNWIND => ReleaseSTB[stb]; mdi: bx.SymbolModuleIndex _ bx.thisModuleIndex; WITH ser: t.e.seb[NARROW[sei, SymbolIndex.x].e] SELECT FROM id => {ans _ AcquireRope[stb, [x[ser.hash]]]; IF moduleName # NIL OR fileName # NIL THEN {WITH cer: t.e.ctxb[ser.idCtx] SELECT FROM included => mdi _ cer.module; ENDCASE; IF moduleName # NIL THEN moduleName^ _ AcquireRope[stb, [x[t.e.mdb[mdi].moduleId]]]; IF fileName # NIL THEN fileName^ _ AcquireRope[stb, [x[t.e.mdb[mdi].fileId]]]}}; ENDCASE => {csei: bx.SymbolConstructorIndex = t.e.UnderType[NARROW[sei, SymbolIndex.x].e]; IF moduleName # NIL THEN moduleName^ _ STBToModuleName[stb]; WITH ser: t.e.seb[csei] SELECT FROM definition => ans _ STBToModuleName[stb]; -- interface type ENDCASE => ans _ NIL}; ReleaseSTB[stb]}; -- end ENABLE UNWIND t: SymbolTableBase.y => { ENABLE UNWIND => ReleaseSTB[stb]; mdi: by.SymbolModuleIndex _ by.thisModuleIndex; WITH ser: t.e.seb[NARROW[sei, SymbolIndex.y].e] SELECT FROM id => {ans _ AcquireRope[stb, [y[ser.hash]]]; IF moduleName # NIL OR fileName # NIL THEN {WITH cer: t.e.ctxb[ser.idCtx] SELECT FROM included => mdi _ cer.module; ENDCASE; IF moduleName # NIL THEN moduleName^ _ AcquireRope[stb, [y[t.e.mdb[mdi].moduleId]]]; IF fileName # NIL THEN fileName^ _ AcquireRope[stb, [y[t.e.mdb[mdi].fileId]]]}}; ENDCASE => {csei: by.SymbolConstructorIndex = t.e.UnderType[NARROW[sei, SymbolIndex.y].e]; IF moduleName # NIL THEN moduleName^ _ STBToModuleName[stb]; WITH ser: t.e.seb[csei] SELECT FROM definition => ans _ STBToModuleName[stb]; -- interface type ENDCASE => ans _ NIL}; ReleaseSTB[stb]}; -- end ENABLE UNWIND ENDCASE => ERROR; }}; -- peels off one layer -- MOVE Ground: PUBLIC SAFE PROC [type: Type--definition, subrange--] RETURNS[ans: Type] = TRUSTED { stb: SymbolTableBase; sei: SymbolIndex; entry: RTTCache.IntEntry; int: INT; entry _ RTTCache.LookupInt[type, Ground]; int _ entry.int; IF int >= 0 THEN {card: CARDINAL _ int; RETURN [LOOPHOLE[card]]}; [stb, sei] _ GetTypeSymbols[type]; {ENABLE UNWIND => ReleaseSTB[stb]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[sei, SymbolIndex.x].e] SELECT FROM id => ans _ AcquireType[stb, [x[ser.idInfo]]]; -- a definition ENDCASE => {csei: bx.SymbolConstructorIndex _ t.e.UnderType[NARROW[sei, SymbolIndex.x].e]; WITH ser: t.e.seb[csei] SELECT FROM subrange => { IF TypeClass[type] = cardinal THEN {ReleaseSTB[stb]; GO TO fault}; ans _ AcquireType[stb, [x[ser.rangeType]]]}; ENDCASE => {ReleaseSTB[stb]; GO TO fault}}; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[sei, SymbolIndex.y].e] SELECT FROM id => ans _ AcquireType[stb, [y[ser.idInfo]]]; -- a definition ENDCASE => {csei: by.SymbolConstructorIndex _ t.e.UnderType[NARROW[sei, SymbolIndex.y].e]; WITH ser: t.e.seb[csei] SELECT FROM subrange => { IF TypeClass[type] = cardinal THEN {ReleaseSTB[stb]; GO TO fault}; ans _ AcquireType[stb, [y[ser.rangeType]]]}; ENDCASE => {ReleaseSTB[stb]; GO TO fault}}; ENDCASE => ERROR; ReleaseSTB[stb]}; -- end ENABLE UNWIND [] _ RTTCache.FillIntEntry[entry, LOOPHOLE[ans, CARDINAL]]; EXITS fault => ERROR Error[reason: typeFault, type: type]; }; GroundStar: PUBLIC SAFE PROC[type: Type--definition, subrange--] RETURNS[Type] = TRUSTED {entry: RTTCache.IntEntry; int: INT; entry _ RTTCache.LookupInt[type, GroundStar]; int _ entry.int; IF int >= 0 THEN {card: CARDINAL _ int; RETURN [LOOPHOLE[card]]}; UNTIL AtGround[type] DO type _ Ground[type] ENDLOOP; [] _ RTTCache.FillIntEntry[entry, LOOPHOLE[type, CARDINAL]]; RETURN[type]}; UnderType: PUBLIC SAFE PROC[type: Type--definition--] RETURNS[Type] = TRUSTED { entry: RTTCache.IntEntry; int: INT; entry _ RTTCache.LookupInt[type, UnderType]; int _ entry.int; IF int >= 0 THEN {card: CARDINAL _ int; RETURN [LOOPHOLE[card]]}; UNTIL TypeClass[type] # definition DO type _ Ground[type]; ENDLOOP; [] _ RTTCache.FillIntEntry[entry, LOOPHOLE[type, CARDINAL]]; RETURN[type]}; AtGround: PROC[type: Type] RETURNS [BOOLEAN] = { class: Class = TypeClass[type]; RETURN[class # definition AND class # subrange]}; -- break up and MOVE First: PUBLIC SAFE PROC [type: Type--enumerated, subrange, basic--] RETURNS [tv: TypedVariable] = TRUSTED {class: Class = TypeClass[UnderType[type]]; IF class = subrange THEN {stb: SymbolTableBase; sei: SymbolIndex; csei: SymbolConstructorIndex; [stb, sei] _ GetTypeSymbols[type]; csei _ SEUnderType[stb, sei]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM subrange => {empty: BOOLEAN = ser.empty; ReleaseSTB[stb]; IF empty THEN ERROR Error[reason: rangeFault]}; ENDCASE => {ReleaseSTB[stb]; ERROR}; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM subrange => {empty: BOOLEAN = ser.empty; ReleaseSTB[stb]; IF empty THEN ERROR Error[reason: rangeFault]}; ENDCASE => {ReleaseSTB[stb]; ERROR}; ENDCASE => ERROR; tv _ New[type]; RETURN}; -- the "0" that's there already is always the right stored representation!! tv _ New[type]; SELECT class FROM enumerated => SetTVFromLC[tv, 0]; cardinal => SetTVFromLC[tv, FIRST[CARDINAL]]; integer => SetTVFromLI[tv, LONG[FIRST[INTEGER]]]; character => SetTVFromLC[tv, LONG[LOOPHOLE[FIRST[CHARACTER], CARDINAL]]]; longInteger => SetTVFromLI[tv, FIRST[LONG INTEGER]]; longCardinal => SetTVFromLC[tv, FIRST[LONG CARDINAL]]; ENDCASE => ERROR Error[reason: typeFault, type: type]; }; -- break up and MOVE Last: PUBLIC SAFE PROC [type: Type--enumerated, subrange, basic--] RETURNS[tv: TypedVariable] = TRUSTED { class: Class = TypeClass[UnderType[type]]; tv _ New[type]; SELECT class FROM enumerated, subrange => { stb: SymbolTableBase; sei: SymbolIndex; i: INTEGER; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; csei: SymbolConstructorIndex _ SEUnderType[stb, sei]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM enumerated => i _ LOOPHOLE[ser.nValues - 1, INTEGER]; subrange => {IF ser.empty THEN ERROR Error[reason: rangeFault]; i _ ser.origin + ser.range}; ENDCASE => ERROR Error[reason: typeFault, type: type]; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM enumerated => i _ LOOPHOLE[ser.nValues - 1, INTEGER]; subrange => {IF ser.empty THEN ERROR Error[reason: rangeFault]; i _ ser.origin + ser.range}; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR; ReleaseSTB[stb]; }; IF class = enumerated THEN SetTVFromLC[tv, LONG[LOOPHOLE[i, CARDINAL]]] ELSE SetTVFromLI[tv, LONG[i]]}; cardinal => SetTVFromLC[tv, LAST[CARDINAL]]; integer => SetTVFromLI[tv, LONG[LAST[INTEGER]]]; character => SetTVFromLC[tv, LONG[LOOPHOLE[LAST[CHARACTER], CARDINAL]]]; longInteger => SetTVFromLI[tv, LAST[LONG INTEGER]]; longCardinal => SetTVFromLC[tv, LAST[LONG CARDINAL]]; ENDCASE => ERROR Error[reason: typeFault, type: type]; }; -- MOVE NValues: PUBLIC SAFE PROC[type: Type--enumerated, subrange--] RETURNS [int: INT] = TRUSTED { stb: SymbolTableBase; sei: SymbolIndex; csei: SymbolConstructorIndex; entry: RTTCache.IntEntry; type _ UnderType[type]; entry _ RTTCache.LookupInt[type, NValues]; int _ entry.int; IF int >= 0 THEN RETURN[int]; [stb, sei] _ GetTypeSymbols[type]; {ENABLE UNWIND => ReleaseSTB[stb]; csei _ SEUnderType[stb, sei]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM enumerated => int _ IF ser.nValues = 0 THEN 200000B ELSE ser.nValues; subrange => int _ IF ser.empty THEN 0 ELSE 1 + ser.range; ENDCASE => ERROR Error[reason: typeFault, type: type]; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM enumerated => int _ IF ser.nValues = 0 THEN 200000B ELSE ser.nValues; subrange => int _ IF ser.empty THEN 0 ELSE 1 + ser.range; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR; ReleaseSTB[stb]}; [] _ RTTCache.FillIntEntry[entry, int]; }; -- raises typeFault, badIndex -- index range is [1..NValues[type]] Value: PUBLIC SAFE PROC[type: Type--enumerated--, index: CARDINAL] RETURNS[tv: TypedVariable] = TRUSTED { type _ UnderType[type]; IF TypeClass[type] = enumerated THEN {IF index > NValues[type] THEN ERROR Error[reason: badIndex]; tv _ TVForReferent[NewObject[type, 1]]; SetTVFromLC[tv, index-1]} ELSE ERROR Error[reason: typeFault, type: type]}; -- This is exported to RTTypesPrivate, and is imported by RTTypedVariablesImpl -- MOVE ComponentISEI: PUBLIC PROC[type: Type--union, enumerated--, index: CARDINAL, p: PROC[stb: SymbolTableBase, isei: SymbolIdIndex]] = { stb: SymbolTableBase; sei: SymbolIndex; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; csei: SymbolConstructorIndex _ SEUnderType[stb, sei]; n: CARDINAL _ 0; ctxi: SymbolContextIndex; enumeration: BOOLEAN _ FALSE; looker: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = { n _ n + 1; IF enumeration THEN {IF index-1 = IDCardinalValue[stb, isei] THEN {p[stb, isei]; RETURN[TRUE]} ELSE RETURN[FALSE]} ELSE {IF n = index THEN {p[stb, isei]; RETURN[TRUE]} ELSE RETURN[FALSE]}}; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM union => IF index = 0 THEN {p[stb, [x[ser.tagSei]]]; ReleaseSTB[stb]; RETURN} ELSE ctxi _ [x[ser.caseCtx]]; sequence => {-- RRA: to get the name of a sequence tag p[stb, [x[ser.tagSei]]]; ReleaseSTB[stb]; RETURN}; enumerated => {enumeration _ TRUE; ctxi _ [x[ser.valueCtx]]}; ENDCASE => ERROR Error[reason: typeFault, type: type]; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM union => IF index = 0 THEN {p[stb, [y[ser.tagSei]]]; ReleaseSTB[stb]; RETURN} ELSE ctxi _ [y[ser.caseCtx]]; sequence => {-- RRA: to get the name of a sequence tag p[stb, [y[ser.tagSei]]]; ReleaseSTB[stb]; RETURN}; enumerated => {enumeration _ TRUE; ctxi _ [y[ser.valueCtx]]}; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR; IF NOT EnumerateCtxIseis[stb, ctxi, looker] THEN ERROR Error[reason: badIndex]; ReleaseSTB[stb]}; }; -- MOVE RecordComponentISEI: PUBLIC PROC[type: Type--record, structure--, index: Index, p: PROC[stb: SymbolTableBase, isei: SymbolIdIndex]] = { stb: SymbolTableBase; sei: SymbolIndex; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; csei: SymbolConstructorIndex _ SEUnderType[stb, sei]; n: Index _ 0; looker: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = { n _ n + 1; IF n = index THEN {p[stb, isei]; RETURN[TRUE]} ELSE RETURN[FALSE]}; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM record => IF NOT EnumerateRecordIseis[stb, LOOPHOLE[csei, SymbolRecordIndex], looker] THEN ERROR Error[reason: badIndex]; definition => IF NOT EnumerateCtxIseis[stb, [x[ser.defCtx]], looker] THEN ERROR Error[reason: badIndex]; ENDCASE => ERROR Error[reason: typeFault, type: type]; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM record => IF NOT EnumerateRecordIseis[stb, LOOPHOLE[csei, SymbolRecordIndex], looker] THEN ERROR Error[reason: badIndex]; definition => IF NOT EnumerateCtxIseis[stb, [y[ser.defCtx]], looker] THEN ERROR Error[reason: badIndex]; ENDCASE => ERROR Error[reason: typeFault, type: type]; ENDCASE => ERROR; ReleaseSTB[stb]}; -- end ENABLE UNWIND }; -- ... NOTE and procedures for dealing with code TypedVariables... -- Procedures private to this module CtxEntries: PROC[stb: SymbolTableBase, ctx: SymbolContextIndex] RETURNS[CARDINAL] = { n: CARDINAL _ 0; counter: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {n _ n + 1; RETURN[FALSE]}; [] _ EnumerateCtxIseis[stb, ctx, counter]; RETURN[n]}; GetOrigin: PUBLIC SAFE PROC[type: Type] RETURNS[origin: INTEGER _ 0] = TRUSTED { stb: SymbolTableBase; sei: SymbolIndex; csei: SymbolConstructorIndex; entry: RTTCache.IntEntry _ NIL; IF Size[type] > 1 THEN RETURN[0]; -- no subranges in long domain entry _ RTTCache.LookupInt[type, GetOrigin]; IF entry.int # -1 THEN RETURN[entry.int]; [stb, sei] _ GetTypeSymbols[type]; { ENABLE UNWIND => ReleaseSTB[stb]; csei _ SEUnderType[stb, sei]; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM subrange => origin _ ser.origin ENDCASE; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM subrange => origin _ ser.origin ENDCASE; ENDCASE => ERROR; ReleaseSTB[stb]; }; IF entry # NIL THEN [] _ RTTCache.FillIntEntry[entry, origin]; }; END. Ê/– "Mesa" style˜IprocšæÏcVœ>œÀœÏk œžœ>žœwžœ©žœžœžœžœžœžœ–žœóžœDžœ£žœ†žœžœžœ[žœžœžœ³ œžœžœ6žœžœ:*œ=œžœ%œGœÏn œžœžœžœ œžœžœ(žœžœžœžœNžœ žœžœfžœžœXžœžœžœ/žœžœ$žœžœ4žœ=žœ,žœžœ(žœžœsžœžœUžœžœ$žœžœ4žœ=žœ,žœžœ(žœžœsžœžœ0žœžœX7œ-œŸ œžœžœžœ œžœžœ žœ<žœžœ7žœ3žœežœžœžœ/žœžœžœžœ”žœŠžœežœ žœUžœOžœžœžœžœ”žœŠžœežœ žœUžœ*žœžœbžœCžœžœcžœžœdžœ(žœžœžœžœžœžœžœžœžœ}žœžœ2žœžœžœžœ &œžœžœžœ9œ-œœŸ œžœžœ œžœžœ<žœžœžœžœžœžœ<œœœŸ œžœžœžœ(œžœ žœžœžœžœžœKžœžœžœJžœ,žœžœ žœ žœ&žœ‘žœžœŽžœžœžœ žœFžœ,žœžœžœžœ>žœ žœžœ<žœžœžœžœžœ^žœ&žœžœžœºžœÇžœKžœžœ…žœ&žœžœžœºžœÇžœKžœžœ/žœžœ$žœžœžœžœ4žœ žœžœ žœ žœžœžœ—œœŸ œžœžœžœ (œ2žœžœžœžœ žœižœWžœEžœžœ|žœžœ LœMžœ žœžœžœxžœžœžœ/œžœžœžœžœIžœžœžœ žœFžœ,žœžœ žœOžœžœžœtžœžœžœžœžœ‡žœžœžœ žœžœžœ9žœžœ1œŸœžœžœžœ œ žœžœžœ_žœžœžœžœžœ-žœžœžœžœcžœžœSžœžœžœžœcžœžœ.žœžœ&ŸœžœžœžœQœžœžœ[žœIžœ žœžœžœžœ8žœžœžœžœžœ-žœžœžœžœÓžœGžœ0žœ2žœžœSžœžœžœžœÓžœGžœ0žœ2žœžœ.žœžœœ(žœžœ WœœŸœžœžœžœ žœžœ[žœHžœ žœžœžœžœžœžœžœžœžœZžœžœžœžœžœ-žœžœžœžœ³žœGžœ/žœŠžœ žœžœEžœSžœ,žœˆžœ,žœžœ,žœažœ9žœœžœžœ4žœžœSžœžœžœžœ³žœGžœ/žœŠžœ žœžœEžœSžœ,žœˆžœ,žœžœ,žœažœ9žœœžœžœ4žœžœ.žœžœœ&žœžœ œœŸœžœžœžœ œžœžœ[žœQžœ žœžœžœžœ8žœžœ-žœžœ žœžœžœ-žœžœžœžœžœ-žœžœ©žœžœ~žœ.žœžœ(žœ.žœžœžœžœžœžœržœžœSžœžœžœžœžœ-žœžœ©žœžœ~žœ.žœžœ(žœ.žœžœžœžœžœžœržœžœ.žœžœ&žœžœ žœ œ(žœžœœŸ œžœžœžœœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœ žœžœžœžœžœžœžœžœžœužœžœžœ žœžœžœžœžœžœžœ žœžœ5žœ žœžœ*žœžœžœ/žœžœažœžœžœžœWžœžœžœ žœžœžœžœžœ\žœžœžœžœxžœ žœžœjžœGžœ,žœžœžœ8žœžœžœAœžœ žœ$œ.žœžœažœžœžœžœWžœžœžœ žœžœžœžœžœ\žœžœžœžœxžœ žœžœjžœGžœ,žœžœžœ8žœžœžœAœžœ žœ$œžœžœœŸœžœžœžœœžœžœZžœIžœ žœžœžœžœ7žœžœžœžœžœ-žœžœžœžœ<œ žœCžœ(žœžœžœ4žœžœžœžœZžœžœžœ6žœžœžœžœ<œ žœCžœ(žœžœžœ4žœžœžœžœZžœžœžœžœžœœ'žœžœžœ žœ/Ÿ œžœžœžœ œ žœ žœ'žœMžœ žœžœžœžœžœžœžœ(žœžœžœ Ÿ œžœžœžœ œžœ žœ)žœLžœ žœžœžœžœžœ$žœžœ(žœžœžœ Ÿœžœ žœžœ,žœžœŸœžœžœžœœžœžœ3žœžœÏžœžœžœ>žœžœ$žœžœ+žœkžœžœžœ2žœžœ@žœžœ$žœžœ+žœkžœžœžœ2žœžœžœžœ.žœLœžœžœMžœžœ&žœžœžœ)žœžœžœž œžœ+žœžœžœ+žœžœžœ žœžœ0ŸœžœžœžœœžœžœIžœžœjžœ;žœžœežœžœžœ>žœžœ$žœžœ*žœžœ'žœ žœžœwžœžœdžœžœ$žœžœ*žœžœ'žœ žœžœwžœžœ6žœžœ:žœ žœžœžœžœžœžœ*žœžœ&žœžœžœ)žœžœžœž œžœ+žœžœžœ+žœžœžœ žœžœ0Ÿœžœžœžœ œ žœžœžœ×žœ žœžœ4žœžœ=žœžœžœ-žœžœ$žœžœ$žœžœ žœ/žœ žœžœžœžœSžœžœ$žœžœ$žœžœ žœ/žœ žœžœžœžœ.žœžœRœ%Ÿœžœžœžœ œ žœ žœžœ!žœ%žœ žœžœžœwžœžœ+OœŸ œžœžœ œ.žœ*žœŒžœžœZžœ9žœžœžœ,žœžœ'žœžœžœ=žœžœžœžœžœžœžœžœ!žœžœžœžœžœžœ žœžœžœ-žœžœ$žœžœ+žœ žœ,žœžœH*œ=žœ/žœ+žœžœSžœžœ$žœžœ+žœ žœ,žœžœH*œ=žœ/žœ+žœžœ.žœžœžœžœ&žœžœ;œŸœžœžœ œsžœŒžœžœtžœ,žœžœ#žœžœžœžœžœžœžœ žœžœžœ-žœžœ$žœžœžœžœ[žœ‚žœžœ6žœžœPžœžœ'žœžœSžœžœ$žœžœžœžœ[žœ‚žœžœ6žœžœPžœžœ'žœžœ.žœžœœCœ%œŸ œžœ0žœžœ žœžœ,žœžœžœžœ;žœŸ œžœžœžœ žœ žœžœnžœžœžœžœœ3žœžœžœ œ)žœžœ9žœžœžœ)žœžœ$žœžœ6žœ+žœžœ$žœžœ6žœžœžœžœ žœžœ3žœ˜È¿—…—ŸÊ°ÿ