-- RTWalkSymbolsImpl.mesa -- Last Modified On December 21, 1982 3:18 pm by Paul Rovner DIRECTORY RTSymbolDefs USING[SymbolTableBase, SymbolIndex, SymbolContextIndex, SymbolIdIndex, nullSymbolIndex, symbolIndexForTYPE, SymbolRecordIndex, nullSymbolContextIndex, nullSymbolNameIndex], RTSymbolOps USING[], -- EXPORTS only RTSymbols USING[Outer]; RTWalkSymbolsImpl: PROGRAM IMPORTS RTSymbols EXPORTS RTSymbolOps = BEGIN OPEN RTSymbolDefs, RTSymbols; --Procedures-- IsRC: PUBLIC PROC [stb: SymbolTableBase, seIndex: SymbolIndex, checkCommon: BOOLEAN _ TRUE] RETURNS[BOOL] = { WITH cr: stb.seb[stb.UnderType[seIndex]] SELECT FROM record => BEGIN rcP: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = BEGIN sei: SymbolIndex _ stb.seb[isei].idType; WITH cse1: stb.seb[stb.UnderType[sei]] SELECT FROM union => BEGIN urcP: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = BEGIN IF IsRC[stb, isei, FALSE] THEN RETURN[TRUE]; -- stop looking. This is it RETURN[FALSE]; -- keep looking END; tagCardinality: CARDINAL _ stb.Cardinality[stb.seb[cse1.tagSei].idType]; RETURN[EnumerateCtxIseis[stb, cse1.caseCtx, urcP, (tagCardinality = stb.CtxEntries[cse1.caseCtx])]]; END; sequence => IF IsRC[stb, cse1.componentType] THEN RETURN[TRUE]; -- here 'tis ENDCASE => IF IsRC[stb, sei] THEN RETURN[TRUE]; -- stop looking. This is it RETURN[FALSE]; -- keep looking END; IF checkCommon THEN RETURN[cr.hints.refField] -- easy if the common parts are to be included ELSE RETURN[EnumerateCtxIseis[stb, cr.fieldCtx, rcP]]; -- look individually at the fields END; sequence, union => ERROR; transfer => RETURN[FALSE]; -- NOTE for now relative => RETURN[FALSE]; -- NOTE for now long => RETURN[WITH rse: stb.seb[stb.UnderType[cr.rangeType] ] SELECT FROM ref => rse.counted, ENDCASE => FALSE]; zone => RETURN[cr.counted]; array => RETURN[IsRC[stb, cr.componentType]]; ENDCASE => RETURN[FALSE]}; IsUnion: PUBLIC PROC [stb: SymbolTableBase, seIndex: SymbolIndex] RETURNS[BOOLEAN] = {RETURN[stb.seb[stb.UnderType[seIndex]].typeTag = union]}; IsSequence: PUBLIC PROC [stb: SymbolTableBase, seIndex: SymbolIndex] RETURNS[BOOLEAN] = {RETURN[stb.seb[stb.UnderType[seIndex]].typeTag = sequence]}; EnumerateRecordIseis: PUBLIC PROC [ stb: SymbolTableBase, rsei: SymbolRecordIndex, p: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN], level: CARDINAL _ 0, mesaSymbolsOK: BOOLEAN _ FALSE] RETURNS [stopped: BOOLEAN] = { proc: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = { sei: SymbolIndex _ stb.seb[isei].idType; IF NOT (IsUnion[stb, sei] OR IsSequence[stb, sei]) OR level = 0 THEN RETURN[p[stb, isei]]; RETURN[FALSE]}; IF rsei = nullSymbolIndex THEN RETURN[FALSE]; WITH lrc: stb.seb[rsei] SELECT FROM linked => { stopped _ EnumerateRecordIseis[stb, LOOPHOLE[stb.UnderType[lrc.linkType]], p, level + 1, mesaSymbolsOK]; IF stopped THEN RETURN[TRUE]}; ENDCASE; RETURN[EnumerateCtxIseis[stb, stb.seb[rsei].fieldCtx, proc, mesaSymbolsOK]]}; -- copied in RCMapBuilderImpl EnumerateCtxIseis: PUBLIC PROC [ stb: SymbolTableBase, ctx: SymbolContextIndex, proc: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN], reallyComplete: BOOLEAN _ FALSE, mesaSymbolsOK: BOOLEAN _ FALSE] RETURNS[stopped: BOOLEAN] = { isei: SymbolIdIndex; IF ctx = nullSymbolContextIndex THEN RETURN[FALSE]; IF NOT reallyComplete THEN { WITH c: stb.ctxb[ctx] SELECT FROM included => IF ~c.complete THEN { p: PROC[base: SymbolTableBase] = -- called once { stopped _ EnumerateCtxIseis[base, c.map, proc]}; Outer[stb, c.module, p, mesaSymbolsOK]; RETURN[stopped]; }; simple => NULL; ENDCASE => ERROR; }; FOR isei _ stb.FirstCtxSe[ctx], stb.NextSe[isei] UNTIL isei = nullSymbolIndex DO IF stb.seb[isei].hash = nullSymbolNameIndex AND stb.seb[isei].idCtx = nullSymbolContextIndex THEN LOOP; -- padding IF proc[stb, isei] THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]}; CountComponents: PUBLIC PROC [stb: SymbolTableBase, rsei: SymbolRecordIndex] RETURNS [n: NAT] = { n _ CountCommonComponents[stb, rsei]; IF stb.seb[rsei].hints.variant THEN n _ n + 1}; CountCommonComponents: PROC [stb: SymbolTableBase, rsei: SymbolRecordIndex] RETURNS [n: CARDINAL] = { count: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = { sei: SymbolIndex _ stb.seb[isei].idType; IF NOT (IsUnion[stb, sei] OR IsSequence[stb, sei]) THEN n _ n + 1; RETURN[FALSE]; -- keep counting }; n _ 0; [] _ EnumerateRecordIseis[stb, rsei, count]}; -- peel layers of id until the last one before either the underlying cons or a change of name -- or a specification of default initialization PeelAllButLast: PUBLIC PROC [stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[SymbolIdIndex] = { FOR sei: SymbolIndex _ stb.seb[isei].idInfo, stb.seb[isei].idInfo UNTIL stb.seb[isei].extended -- i.e. isei has default initialization specified DO WITH se: stb.seb[sei] SELECT FROM id => IF se.idType # symbolIndexForTYPE THEN ERROR ELSE IF stb.seb[isei].hash # stb.seb[LOOPHOLE[sei, SymbolIdIndex]].hash THEN EXIT ELSE isei _ LOOPHOLE[sei, SymbolIdIndex]; cons => EXIT; ENDCASE => ERROR; ENDLOOP; RETURN[isei]}; END. Ę˘JšŌĪcœ=œĪk œžœėžœœ žœžœžœ žœžœžœœĪnœžœžœkžœžœ žœžœžœ%žœžœžœžœ,žœžœ žœ>žœ#žœžœ(žœžœLžœžœžœžœžœžœžœžœœžœžœœžœ%žœDžœ›žœžœžœžœžœ œ žœžœžœžœžœœ žœžœœžœ žœžœžœ/œ žœžœ-#œžœžœžœžœœžœžœœ žœžœ,žœžœEžœžœžœžœ#žœžœžœŸœžœžœ4žœžœžœ5Ÿ œžœžœ4žœžœžœ8Ÿœžœžœcžœ,žœžœžœ%žœžœ žœ žœ žœ,žœžœAžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœwžœãžœ žœžœžœ žœžœKŸœžœžœWžœ,žœžœžœžœžœžœžœ žœžœžœžœžœžœžœžœžœžœžœžœ žœžœœ‡žœ&žœžœžœ žœ.žœžœžœ4žœ7žœžœ œžœžœžœžœžœžœžœŸœžœžœ:žœžœ6žœžœŸœžœ7žœžœžœ,žœžœAžœžœžœžœžœžœœO^œ0Ÿœžœžœ3žœžœDžœ2œžœžœžœžœžœ žœžœžœžœžœžœžœžœžœ(žœ žœžœžœžœ žœ˜Đ2—…—R#