DIRECTORY ConvertUnsafe USING [SubString], IO, MobListerUtils USING [PrintName, PrintSei], OSMiscOps USING [bytesPerUnit], Rope USING [ROPE], SortedSymbolLister USING [], StructuredStreams USING [Begin, Bp, Create, End], SymbolOps USING [DecodeCard, DecodeType, FindExtension, FirstCtxSe, LinkMode, NextSe, NormalType, RecField, SubStringForName, ToType, TypeLink, UnderType, XferMode], Symbols USING [Base, BitAddress, BodyRecord, BTIndex, codeANY, codeCHAR, CSEIndex, CSENull, CTXIndex, CTXNull, ExtensionType, FirstStandardCtx, HTIndex, HTNull, ISEIndex, ISENull, LastStandardCtx, lZ, RecordSEIndex, SEIndex, SENull, SERecord, TransferMode, typeANY, typeTYPE], SymbolSegment USING [Base, STHeader], SymbolTable USING [SymbolTableBaseRep], SymbolTablePrivate USING [SymbolTableBase, SymbolTableBaseRep], Tree USING [Base, Index, Link, Node, Null, Scan], TreeOps USING [GetTag], UnparserBuffer USING [Handle, Init, NewInittedHandle]; SortedSymbolListerImpl: PROGRAM IMPORTS IO, MobListerUtils, StructuredStreams, UnparserBuffer, SymbolOps, TreeOps EXPORTS SortedSymbolLister, SymbolTable = BEGIN OPEN Symbols; bitsPerByte: CARD = 8; bitsPerUnit: CARD = OSMiscOps.bytesPerUnit*bitsPerByte; STREAM: TYPE = IO.STREAM; SymbolTableBase: TYPE = REF SymbolTableBaseRep; SymbolTableBaseRep: PUBLIC TYPE = SymbolTablePrivate.SymbolTableBaseRep; ROPE: TYPE = Rope.ROPE; Control: TYPE = {begin, end, brk, tbrk}; DoControl: PROC[st: IO.STREAM, cc: Control] = { SELECT cc FROM $begin => StructuredStreams.Begin[st]; $end => StructuredStreams.End[st]; $brk => StructuredStreams.Bp[st, width, 2]; $tbrk => StructuredStreams.Bp[st, united, 2]; ENDCASE => ERROR; }; alwaysMD: BOOL ฌ FALSE; VfTag: TYPE = {signed, unsigned, char, enum, array, transfer, ref, real, other}; ValFormat: TYPE = RECORD[ bias: INTEGERฌ0, var: SELECT tag: VfTag FROM signed => [], --an INTEGER or subrange with base < 0 unsigned => [], -- a CARDINAL, WORD, UNSPECIFIED, or subrange w/ base >= 0 char => [], --a character enum => [esei: EnumeratedSEIndex], --an enumerated type array => [componentType: SEIndex], transfer => [mode: TransferMode], --a PROC, SIGNAL, ERROR, PROGRAM, or PORT ref => [], --a pointer real => [], other => [], --anything else (whether single word or multi-word) ENDCASE ]; PrintInterface: PUBLIC PROC[st: STREAM, stb: SymbolTableBase] = { sei: ISEIndex; stHandle: LONG POINTER TO SymbolSegment.STHeader = stb.stHandle; st.PutRope[" -- Item # -- Item Name\n"]; FOR sei ฌ SymbolOps.FirstCtxSe[stb, stHandle.outerCtx], SymbolOps.NextSe[stb, sei] UNTIL sei = ISENull DO SELECT SymbolOps.LinkMode[stb, sei] FROM val => { PutValue[st, stb, sei]; st.PutRope[ModePrintName[SymbolOps.XferMode[stb, stb.seb[sei].idType]]]; st.PutRope["\n"]; }; ref => { PutValue[st, stb, sei]; st.PutRope["EXPORTED Variable"]; st.PutRope["\n"]; }; manifest => NULL; -- constant ENDCASE; ENDLOOP; }; PutValue: PROCEDURE [st: STREAM, stb: SymbolTableBase, sei: Symbols.ISEIndex] = { idValue: CARD ฌ SymbolOps.DecodeCard[stb.seb[sei].idValue]; st.PutRope[" -- "]; IF stb.seb[sei].extended THEN st.PutRope["(INLINE?) "]; PutUnsigned[st, idValue]; st.PutRope[" -- "]; MobListerUtils.PrintSei[sei: sei, stream: st, stb: stb]; st.PutRope[": "]; }; ModePrintName: ARRAY Symbols.TransferMode OF Rope.ROPE = ["PROCEDURE", "PORT", "SIGNAL", "ERROR", "PROCESS", "PROGRAM", "OTHER", "NONE"]; AddSymbols: PUBLIC PROC[rList: LIST OF REF ANY , stb: SymbolTableBase] RETURNS[LIST OF REF ANY] = { ros: IO.STREAM ฌ IO.ROS[]; upb: UnparserBuffer.Handle; strc: IO.STREAM; modname: ROPE; mySei, sei: ISEIndex; stHandle: LONG POINTER TO SymbolSegment.STHeader = stb.stHandle; ros.PutRope[": --"]; -- set up modname FOR sei ฌ SymbolOps.FirstCtxSe[stb, stHandle.directoryCtx], SymbolOps.NextSe[stb, sei] UNTIL sei = ISENull DO mySei ฌ sei; ENDLOOP; MobListerUtils.PrintSei[mySei, ros, stb]; ros.PutRope["--"]; modname ฌ ros.RopeFromROS[FALSE]; upb ฌ UnparserBuffer.NewInittedHandle[[output: [stream[ros]]]]; strc ฌ StructuredStreams.Create[upb]; FOR sei ฌ SymbolOps.FirstCtxSe[stb, stHandle.outerCtx], SymbolOps.NextSe[stb, sei] UNTIL sei = ISENull DO ros.Reset[]; upb.Init[]; DoControl[strc, $begin]; PrintSym[strc, stb, sei, modname, TRUE]; strc.PutChar[';]; DoControl[strc, $end]; rList ฌ CONS[ros.RopeFromROS[FALSE], rList]; ENDLOOP; RETURN[rList]}; FirstChar: PROC[stb: SymbolTableBase, hti: HTIndex] RETURNS[CHAR] = { ss: ConvertUnsafe.SubString; IF hti = HTNull THEN RETURN['\000]; ss ฌ SymbolOps.SubStringForName[stb, hti]; RETURN[IF ss.length = 0 THEN '\000 ELSE ss.base[ss.offset]]}; PrintSym: PROC[ st: IO.STREAM, stb: SymbolTableBase, sei: ISEIndex, colonstring: ROPE, defaultPublic: BOOL] = { PrintSei: PROC[val: ISEIndex] = { MobListerUtils.PrintSei[sei: val, stream: st, stb: stb]}; PutRope: PROC[val: ROPE] = { st.PutRope[val]}; typeSei: SEIndex; vf: ValFormat; hti: HTIndex; hti ฌ stb.seb[sei].hash; IF FirstChar[stb, hti] = '& THEN RETURN; DoControl[st, $begin]; IF hti # HTNull THEN {PrintSei[sei]; PutRope[colonstring]}; IF stb.seb[sei].public # defaultPublic THEN { defaultPublic ฌ stb.seb[sei].public; PutRope[IF defaultPublic THEN "PUBLIC " ELSE "PRIVATE "]}; IF stb.seb[sei].idType = typeTYPE THEN { typeSei ฌ SymbolOps.DecodeType[stb.seb[sei].idInfo]; PutRope["TYPE"]; WITH t~~stb.seb[typeSei] SELECT FROM cons => WITH t SELECT FROM opaque => NULL; ENDCASE => PutRope[" = "]; ENDCASE => PutRope[" = "]; DoControl[st, $brk]; vf ฌ PrintType[st, stb, typeSei, NoSub, defaultPublic]; DoControl[st, $brk]; PrintDefaultValue[st, stb, sei, vf]} ELSE { typeSei ฌ stb.seb[sei].idType; IF stb.seb[sei].immutable AND NOT stb.seb[sei].constant AND (SELECT SymbolOps.XferMode[stb, typeSei] FROM none, process => TRUE, ENDCASE => FALSE) THEN PutRope["READONLY "]; vf ฌ PrintType[st, stb, typeSei, NoSub, defaultPublic]; IF stb.seb[sei].constant AND vf.tag <= enum THEN { PutRope[" = "]; DoControl[st, $brk]; IF stb.seb[sei].extended THEN PrintTreeLink[st, stb, SymbolOps.FindExtension[stb, sei].tree, vf] ELSE PrintTypedVal[st, stb, SymbolOps.DecodeCard[stb.seb[sei].idValue], vf]} }; DoControl[st, $end]}; PrintTypedVal: PROC[st: IO.STREAM, stb: SymbolTableBase, val: LONG UNSPECIFIED, vf: ValFormat] = { PutCharConst: PROC[val: CARDINAL] = {st.PutF1["%bC", [cardinal[val]]]}; loophole: BOOL ฌ FALSE; val ฌ val + vf.bias; WITH vf SELECT FROM signed => PutSigned[st, LOOPHOLE[val, INT]]; unsigned => PutUnsigned[st, LOOPHOLE[val, CARD]]; char => PutCharConst[val]; enum => PutEnum[st, stb, val, esei]; transfer, ref => IF val = 0 THEN st.PutRope["NIL"] ELSE loophole ฌ TRUE; ENDCASE => loophole ฌ TRUE; IF loophole THEN { st.PutRope["LOOPHOLE ["]; PutUnsigned[st, LOOPHOLE[val, CARD]]; st.Put1[[character[']]]]}; }; GetBitSpec: PROC[stb: SymbolTableBase, isei: ISEIndex] RETURNS[ROPE] = { a: Symbols.BitAddress; s: CARDINAL; ros: IO.STREAM ฌ IO.ROS[]; [offset: a, size: s] ฌ SymbolOps.RecField[stb, isei]; ros.PutF1[" (%d", [cardinal[a.bd/bitsPerUnit]]]; IF s # 0 THEN ros.PutF[":%d..%d", [cardinal[a.bd MOD bitsPerUnit]], [cardinal[(a.bd+s-1) MOD bitsPerUnit]]]; ros.PutRope["): "]; RETURN[ros.RopeFromROS[]]}; PrintFieldCtx: PROC[st: IO.STREAM, stb: SymbolTableBase, ctx: CTXIndex, md: BOOL, defaultPublic: BOOL] = { PutChar: PROC[val: CHAR] = { st.Put1[[character[val]]]}; PutRope: PROC[val: ROPE] = { st.PutRope[val]}; isei: ISEIndex ฌ SymbolOps.FirstCtxSe[stb, ctx]; bitspec: ROPE ฌ ": "; first: BOOL ฌ TRUE; IF isei # ISENull AND stb.seb[isei].idCtx # ctx THEN isei ฌ SymbolOps.NextSe[stb, isei]; IF isei = ISENull THEN { PutRope["NULL"]; RETURN }; PutChar['[]; FOR isei ฌ isei, SymbolOps.NextSe[stb, isei] UNTIL isei = ISENull DO IF first THEN first ฌ FALSE ELSE PutRope[", "]; DoControl[st, $brk]; IF md THEN bitspec ฌ GetBitSpec[stb, isei]; DoControl[st, $begin]; PrintSym[st, stb, isei, bitspec, defaultPublic]; PrintDefaultValue[st, stb, isei, GetValFormat[stb, stb.seb[isei].idType]]; DoControl[st, $end]; ENDLOOP; PutChar[']]}; PrintValue: PROC[st: IO.STREAM, value: LONG UNSPECIFIED] = { lc: LONG CARDINAL ฌ LOOPHOLE[value]; PutUnsigned[st, lc]}; NoSub: PROC[ptr: BOOL] = { }; EnumeratedSEIndex: TYPE = Symbols.Base RELATIVE LONG POINTER TO SERecord.cons.enumerated; PutEnum: PROC[st: IO.STREAM, stb: SymbolTableBase, val: LONG UNSPECIFIED, esei: EnumeratedSEIndex] = { sei: ISEIndex; FOR sei ฌ SymbolOps.FirstCtxSe[stb, stb.seb[esei].valueCtx], SymbolOps.NextSe[stb, sei] WHILE sei # ISENull DO IF SymbolOps.DecodeCard[stb.seb[sei].idValue] = val THEN {MobListerUtils.PrintSei[sei, st, stb]; RETURN}; ENDLOOP; st.PutRope["LOOPHOLE ["]; PrintValue[st, val]; st.Put1[[character[']]]]}; GetValFormat: PROC[stb: SymbolTableBase, tsei: SEIndex] RETURNS[vf: ValFormat] = { WITH t~~stb.seb[tsei] SELECT FROM id => RETURN[GetValFormat[stb, SymbolOps.UnderType[stb, tsei]]]; cons => WITH t SELECT FROM basic => SELECT code FROM codeANY => vf ฌ [,unsigned[]]; codeCHAR => vf ฌ [,char[]]; ENDCASE; enumerated => vf ฌ [,enum [LOOPHOLE [tsei]]]; array => vf ฌ [,array [componentType]]; transfer => vf ฌ [,transfer[mode]]; relative => vf ฌ GetValFormat[stb, offsetType]; subrange => { vf ฌ GetValFormat[stb, rangeType]; IF vf.tag = signed AND origin >= 0 THEN vf ฌ [,unsigned[]]; vf.bias ฌ origin}; real => vf ฌ [,real[]]; ref => vf ฌ [,ref[]]; ENDCASE => vf ฌ [,other[]]; ENDCASE => vf ฌ [,other[]]; }; octalThreshold: NAT ฌ 1024; PutSigned: PROC[st: IO.STREAM, val: INT] = { IF val > octalThreshold THEN st.PutF1["%bB", [integer[val]]] ELSE st.PutF1["%d", [integer[val]]]}; PutUnsigned: PROC[st: IO.STREAM, val: LONG CARDINAL] = { IF val > octalThreshold THEN st.PutF1["%bB", [cardinal[val]]] ELSE st.PutF1["%d", [cardinal[val]]]}; PrintType: PROC[ st: IO.STREAM, stb: SymbolTableBase, tsei: SEIndex, dosub: PROC[ptr: BOOL], defaultPublic: BOOL] RETURNS[vf: ValFormat] = { PutChar: PROC[val: CHAR] = { st.Put1[[character[val]]]}; PutRope: PROC[val: ROPE] = { st.PutRope[val]}; PrintSei: PROC[val: ISEIndex] = { MobListerUtils.PrintSei[sei: val, stream: st, stb: stb]}; PrintHti: PROC[val: HTIndex] = { MobListerUtils.PrintName[name: val, stream: st, stb: stb]}; vf ฌ GetValFormat[stb, tsei]; WITH t~~stb.seb[tsei] SELECT FROM id => { printBase: BOOL ฌ TRUE; multiSubrange: BOOL ฌ FALSE; bsei: SEIndex ฌ tsei; csei: CSEIndex; tseiNext: SEIndex; { l1: SEIndex = SymbolOps.DecodeType[t.idInfo]; IF stb.seb[l1].seTag = id THEN GO TO noAdj; UNTIL (tseiNext ฌ SymbolOps.TypeLink[stb, tsei]) = SENull DO WITH stb.seb[tsei] SELECT FROM id => { PrintSei[LOOPHOLE[tsei]]; PutChar[' ]; }; ENDCASE; tsei ฌ tseiNext; ENDLOOP; EXITS noAdj => NULL; }; IF t.idCtx NOT IN [Symbols.FirstStandardCtx..Symbols.LastStandardCtx] THEN WITH c~~stb.ctxb [t.idCtx] SELECT FROM included => { hti: HTIndex = stb.mdb [c.module].moduleId; PrintHti [hti]; --interface name PutChar ['.]}; -- dot qualification ENDCASE; DO csei ฌ SymbolOps.UnderType[stb, bsei]; WITH stb.seb[csei] SELECT FROM basic => { EXIT}; subrange => {bsei ฌ rangeType; multiSubrange ฌ TRUE}; enumerated => {printBase ฌ TRUE; EXIT}; ENDCASE => EXIT; ENDLOOP; IF printBase OR dosub = NoSub THEN PrintSei[LOOPHOLE[tsei]]; dosub[FALSE]}; cons => WITH t SELECT FROM enumerated => { isei: ISEIndex; v: CARDINAL ฌ 0; sv: CARDINAL; md: BOOL = machineDep; first: BOOL ฌ TRUE; IF md THEN PutRope["MACHINE DEPENDENT "]; PutChar['{]; FOR isei ฌ SymbolOps.FirstCtxSe[stb, valueCtx], SymbolOps.NextSe[stb, isei] UNTIL isei = ISENull DO IF first THEN first ฌ FALSE ELSE PutRope[", "]; DoControl[st, $brk]; IF md THEN { hti: Symbols.HTIndex = stb.seb[isei].hash; sv ฌ SymbolOps.DecodeCard[stb.seb[isei].idValue]; IF hti # HTNull THEN PrintSei[isei]; IF hti = HTNull OR sv # v THEN {PutChar['(]; PutUnsigned[st, sv]; PutChar[')]}; v ฌ sv + 1} ELSE PrintSei[isei]; ENDLOOP; PutChar['}]}; record => { IF stb.ctxb[fieldCtx].level # lZ THEN { fctx: CTXIndex = fieldCtx; bti: BTIndex ฌ FIRST[BTIndex]; btlimit: BTIndex = bti + stb.stHandle.bodyBlock.size; PutRope["FRAME ["]; UNTIL bti = btlimit DO WITH entry~~stb.bb[bti] SELECT FROM Callable => { IF entry.localCtx = fctx THEN {PrintSei[entry.id]; PutChar[']]; EXIT}; bti ฌ bti + BodyRecord.Callable.SIZE; }; ENDCASE => bti ฌ bti + BodyRecord.Other.SIZE; ENDLOOP; } ELSE { IF defaultPublic AND hints.privateFields THEN PutRope["PRIVATE "]; IF monitored THEN PutRope["MONITORED "]; IF machineDep THEN PutRope["MACHINE DEPENDENT "]; PutRope["RECORD"]; PrintFieldCtx[st, stb, fieldCtx, machineDep, defaultPublic AND ~hints.privateFields]; }; }; ref => { referent: SEIndex = refType; IF var THEN PutRope[IF readOnly THEN "READONLY " ELSE "VAR "] ELSE { IF ordered THEN PutRope["ORDERED "]; IF basing THEN PutRope["BASE "]; IF counted THEN { isList: BOOL; element: SEIndex; [isList, element] ฌ CheckForList[stb, LOOPHOLE[tsei]]; IF isList THEN { PutRope["LIST OF "]; [] ฌ PrintType[st, stb, element, NoSub, defaultPublic]; GO TO noprint} ELSE PutRope["REF "]; WITH rt~~stb.seb[referent] SELECT FROM cons => WITH rt SELECT FROM any => { PutRope["ANY"]; GO TO noprint}; ENDCASE; ENDCASE; } ELSE { PutRope["POINTER"]; IF dosub # NoSub THEN { PutChar[' ]; dosub[TRUE]}; WITH rt~~stb.seb[referent] SELECT FROM cons => WITH rt SELECT FROM basic => IF code = Symbols.codeANY AND ~readOnly THEN GO TO noprint; ENDCASE; ENDCASE; PutRope[" TO "]; IF readOnly THEN PutRope["READONLY "]}; }; DoControl[st, $brk]; [] ฌ PrintType[st, stb, referent, NoSub, defaultPublic]; EXITS noprint => NULL; }; array => { IF packed THEN PutRope["PACKED "]; PutRope["ARRAY "]; [] ฌ PrintType[st, stb, indexType, NoSub, defaultPublic]; PutRope[" OF "]; DoControl[st, $brk]; [] ฌ PrintType[st, stb, componentType, NoSub, defaultPublic]}; arraydesc => { PutRope["DESCRIPTOR FOR "]; IF readOnly THEN PutRope["READONLY "]; DoControl[st, $brk]; [] ฌ PrintType[st, stb, describedType, NoSub, defaultPublic]}; transfer => { PutModeName[st, mode]; IF typeIn # CSENull THEN { PutChar[' ]; WITH tt~~stb.seb[typeIn] SELECT FROM record => PrintFieldCtx[st, stb, tt.fieldCtx, FALSE, defaultPublic]; any => PutRope["ANY"]; ENDCASE => ERROR; }; IF typeOut # CSENull THEN { DoControl[st, $brk]; PutRope[" RETURNS "]; WITH tt~~stb.seb[typeOut] SELECT FROM record => PrintFieldCtx[st, stb, tt.fieldCtx, FALSE, defaultPublic]; any => PutRope["ANY"]; ENDCASE => ERROR; }; }; union => { tagType: SEIndex; PutRope["SELECT "]; IF ~controlled THEN PutRope[IF overlaid THEN "OVERLAID " ELSE "COMPUTED "] ELSE { PrintSei[tagSei]; PutRope[IF machineDep OR alwaysMD THEN GetBitSpec[stb, tagSei] ELSE ": "]}; tagType ฌ stb.seb[tagSei].idType; IF stb.seb[tagSei].public # defaultPublic THEN PutRope[IF defaultPublic THEN "PRIVATE " ELSE "PUBLIC "]; WITH stb.seb[tagType] SELECT FROM id => [] ฌ PrintType[st, stb, tagType, NoSub, defaultPublic]; cons => PutChar['*]; ENDCASE; PutRope[" FROM "]; { isei: ISEIndex; varRec: RecordSEIndex; FOR isei ฌ SymbolOps.FirstCtxSe[stb, caseCtx], SymbolOps.NextSe[stb, isei] UNTIL isei = ISENull DO DoControl[st, $tbrk]; DoControl[st, $begin]; PrintSei[isei]; PutRope[" => "]; varRec ฌ LOOPHOLE[SymbolOps.UnderType[stb, SymbolOps.DecodeType[stb.seb[isei].idInfo]]]; PrintFieldCtx[st, stb, stb.seb[varRec].fieldCtx, machineDep, defaultPublic]; PutRope[", "]; DoControl[st, $end]; ENDLOOP; DoControl[st, $tbrk]; PutRope["ENDCASE"]; }; }; relative => { IF baseType # SENull THEN [] ฌ PrintType[st, stb, baseType, NoSub, defaultPublic]; PutRope[" RELATIVE "]; [] ฌ PrintType[st, stb, offsetType, dosub, defaultPublic]}; sequence => { tagType: SEIndex; pubTag: BOOL ฌ stb.seb[tagSei].public; IF packed THEN PutRope["PACKED "]; PutRope["SEQUENCE "]; IF ~controlled THEN PutRope["COMPUTED "] ELSE { PrintSei[tagSei]; PutRope[IF machineDep THEN GetBitSpec[stb, tagSei] ELSE ": "]}; tagType ฌ stb.seb[tagSei].idType; IF pubTag # defaultPublic THEN PutRope[IF defaultPublic THEN "PRIVATE " ELSE "PUBLIC "]; [] ฌ PrintType[st, stb, tagType, NoSub, pubTag]; PutRope[" OF "]; [] ฌ PrintType[st, stb, componentType, NoSub, defaultPublic]}; subrange => { org: INTEGER ฌ origin; size: CARDINAL ฌ range; mt: BOOL ฌ empty; doit: PROC[ptr: BOOL] = { vfSub: ValFormat ฌ IF ptr THEN [,unsigned[]] ELSE vf; vfSub.bias ฌ 0; PutChar['[]; PrintTypedVal[st, stb, org, vfSub]; PutRope[".."]; IF mt THEN {PrintTypedVal[st, stb, org, vfSub]; PutChar[')]} ELSE {PrintTypedVal[st, stb, org + size, vfSub]; PutChar[']]}}; [] ฌ PrintType[st, stb, rangeType, doit, defaultPublic]; vf.bias ฌ org}; zone => SELECT TRUE FROM counted => PutRope["ZONE"]; mds => PutRope["MDSZone"]; ENDCASE => PutRope["UNCOUNTED ZONE"]; opaque => { IF lengthKnown THEN { PutChar['[]; PutUnsigned[st, length/bitsPerUnit]; PutChar[']]} }; real => PutRope["REAL"]; ENDCASE => PutRope["xxxx"]; ENDCASE; }; IsVarOrRef: PROC[tsei: Symbols.SEIndex, stb: SymbolTableBase] RETURNS[BOOL] = { WITH t~~stb.seb[tsei] SELECT FROM id => RETURN[FALSE]; cons => WITH t2~~t SELECT FROM ref => RETURN[t2.var OR t2.counted] ENDCASE => RETURN[FALSE]; ENDCASE => RETURN[FALSE]; }; RefIndex: TYPE = Symbols.Base RELATIVE LONG POINTER TO SERecord.cons.ref; CheckForList: PROC[stb: SymbolTableBase, rsei: RefIndex] RETURNS[BOOL, SEIndex] = { rft: SEIndex ฌ stb.seb[rsei].refType; seb: Symbols.Base = stb.seb; WITH rt~~seb[rft] SELECT FROM id => RETURN[FALSE, SENull]; cons => WITH rec~~rt SELECT FROM record => { ctx: CTXIndex = rec.fieldCtx; first, rest: ISEIndex; element: SEIndex; restp: CSEIndex; IF ctx = CTXNull THEN RETURN[FALSE, SENull]; first ฌ SymbolOps.FirstCtxSe[stb, ctx]; IF first = ISENull THEN RETURN[FALSE, SENull]; element ฌ seb[first].idType; rest ฌ SymbolOps.NextSe[stb, first]; IF rest = ISENull THEN RETURN[FALSE, SENull]; restp ฌ SymbolOps.UnderType[stb, seb[rest].idType]; WITH seb[restp] SELECT FROM ref => RETURN[refType = rft, element]; ENDCASE => RETURN[FALSE, SENull]; }; ENDCASE => RETURN[FALSE, SENull]; ENDCASE => RETURN[FALSE, SENull]; }; PutModeName: PROC[st: IO.STREAM, n: TransferMode] = { ModePrintName: ARRAY TransferMode OF ROPE = ["PROC", "PORT", "SIGNAL", "ERROR", "PROCESS", "PROGRAM", "OTHER", "NONE"]; st.PutRope[ModePrintName[n]]}; LUP: TYPE = LONG POINTER TO LONG UNSPECIFIED; NodePointer: TYPE = LONG POINTER TO Tree.Node; PrintDefaultValue: PROC[st: IO.STREAM, stb: SymbolTableBase, sei: ISEIndex, vf: ValFormat] = { extType: ExtensionType; tree: Tree.Link; [extType, tree] ฌ SymbolOps.FindExtension[stb, sei]; IF extType # default THEN RETURN; st.PutRope[" _ "]; WITH tree SELECT TreeOps.GetTag[tree] FROM subtree => IF stb.tb[index].name = list AND stb.tb[index].nSons = 2 THEN { PrintTreeLink[st, stb, stb.tb[index].son[1], vf]; st.PutChar['|]; PrintTreeLink[st, stb, stb.tb[index].son[2], vf]; RETURN}; ENDCASE ; PrintTreeLink[st, stb, tree, vf]}; endIndex: Tree.Index = Tree.Index.LAST; endMark: Tree.Link = [subtree[index: endIndex]]; ScanList: PROC[tb: Symbols.Base, root: Tree.Link, action: Tree.Scan] = { IF root # Tree.Null THEN WITH root SELECT TreeOps.GetTag[root] FROM subtree => { node: Tree.Index = index; i, n: CARDINAL; t: Tree.Link; IF tb[node].name # $list THEN action[root] ELSE IF (n ฌ tb[node].nSons) # 0 THEN FOR i ฌ 1, i+1 WHILE i <= n DO action[tb[node].son[i]] ENDLOOP ELSE FOR i ฌ 1, i+1 UNTIL (tฌtb[node].son[i]) = endMark DO action[t] ENDLOOP}; ENDCASE => action[root]}; LiteralValue: PROC[stb: SymbolTableBase, tree: Tree.Link] RETURNS[CARD] = { WITH t~~tree SELECT TreeOps.GetTag[tree] FROM literal => WITH lr~~stb.ltb[t.index] SELECT FROM short => RETURN[SymbolOps.DecodeCard[lr.value]]; ENDCASE; ENDCASE; RETURN[0]}; PrintTreeLink: PROC[st: IO.STREAM, stb: SymbolTableBase, tree: Tree.Link, vf: ValFormat] = { PutChar: PROC[val: CHAR] = { st.PutChar[val]}; PutRope: PROC[val: ROPE] = { st.PutRope[val]}; PrintSei: PROC[val: ISEIndex] = { MobListerUtils.PrintSei[sei: val, stream: st, stb: stb]}; PrintHti: PROC[val: HTIndex] = { MobListerUtils.PrintName[name: val, stream: st, stb: stb]}; IF tree = Tree.Null THEN RETURN; WITH t~~tree SELECT TreeOps.GetTag[tree] FROM subtree => { node: NodePointer = @stb.tb[t.index]; SELECT node.name FROM all => { PutRope["ALL["]; WITH v~~vf SELECT FROM array => PrintTreeLink[st, stb, node.son [1], GetValFormat[stb, v.componentType]]; ENDCASE; PutChar[']]}; atom => { PutChar['$]; PrintTreeLink[st, stb, node.son [1], vf]}; clit => { ch: CHAR ฌ VAL[CARDINAL[LiteralValue[stb, node.son[1]]]]; PutChar['']; PutChar[ch]}; mwconst, cast, loophole => PrintTreeLink[st, stb, node.son [1], vf]; nil => PutRope["NIL"]; void => PutRope["TRASH"]; dot, cdot => { PrintTreeLink[st, stb, node.son[1], [,other[]]]; PutChar ['.]; --dot PrintTreeLink[st, stb, node.son[2], [,other[]]]}; first, last, size => { PutRope[SELECT node.name FROM first => "FIRST[", last => "LAST[", ENDCASE => "SIZE["]; PrintTreeLink[st, stb, node.son[1], vf]; PutChar [']]}; lengthen => { s1: Tree.Link = node.son[1]; IF TreeOps.GetTag[s1] = literal THEN PrintTreeLink[st, stb, s1, vf] ELSE { PutRope["LONG["]; PrintTreeLink[st, stb, s1, vf]; PutChar [']]}; }; construct => { s1: Tree.Link = node.son[1]; PutChar['[]; IF node.nSons = 2 THEN PrintTreeLink [st, stb, node.son[2], vf]; PutChar[']]}; union => { PrintTreeLink [st, stb, node.son[1], vf]; PutChar ['[]; PrintTreeLink [st, stb, node.son[2], vf]; PutChar [']]}; list => { first: BOOL ฌ TRUE; PrintOne: Tree.Scan = { IF first THEN first ฌ FALSE ELSE PutRope[", "]; PrintTreeLink [st, stb, t, [,other[]]]}; ScanList[stb.tb, tree, PrintOne]}; longTC => { PutRope["LONG "]; PrintTreeLink [st, stb, node.son[1], vf]}; callx => { PrintTreeLink [st, stb, node.son[1], vf]; PutChar ['[]; PrintTreeLink [st, stb, node.son[2], vf]; PutChar [']]}; uparrow => { ptr: Tree.Link = node.son[1]; type: Symbols.CSEIndex; WITH p~~ptr SELECT TreeOps.GetTag[ptr] FROM symbol => type ฌ SymbolOps.NormalType[stb, SymbolOps.UnderType[stb, stb.seb[p.index].idType]]; subtree => type ฌ LOOPHOLE[SymbolOps.ToType[stb.tb[p.index].info]]; ENDCASE => type ฌ Symbols.typeANY; PrintTreeLink[st, stb, node.son[1], [,other[]]]; WITH q~~stb.seb[type] SELECT FROM ref => IF ~q.var THEN PutChar['^]; ENDCASE => PutChar['^]; }; ENDCASE => PutRope["xxxx"]; }; hash => PrintHti [t.index]; symbol => PrintSei [t.index]; string => PutRope["(STRING)"]; literal => { WITH stb.ltb[t.index] SELECT FROM short => PrintTypedVal [st, stb, SymbolOps.DecodeCard[value], vf]; long => SELECT bits FROM 2*bitsPerUnit => { loophole: BOOL ฌ FALSE; SELECT vf.tag FROM signed => { li: INT = LOOPHOLE[value[0]]; SELECT li FROM INT.FIRST => PutRope["FIRST[INT]"]; INT.LAST => PutRope["LAST[INT]"]; ENDCASE => PutSigned[st, li]; }; unsigned => { lu: LONG CARDINAL = LOOPHOLE [value[0]]; SELECT lu FROM LAST[LONG CARDINAL] => PutRope["LAST[LONG CARDINAL]"]; ENDCASE => PutUnsigned[st, lu]; }; real => st.Put1[[real[LOOPHOLE [value[0]]]]]; transfer, ref => IF LOOPHOLE[value[0], LONG UNSPECIFIED] = 0 THEN PutRope["NIL"] ELSE loophole ฌ TRUE; ENDCASE => loophole ฌ TRUE; IF loophole THEN { PutRope["LOOPHOLE ["]; PutUnsigned [st, LOOPHOLE [value[0]]]; PutChar [']]}; }; ENDCASE => PutRope["--constant--"]; ENDCASE; --shouldn't happen! }; ENDCASE; --shouldn't happen! }; END. x SortedSymbolListerImpl.mesa; modified by Copyright ำ 1991 by Xerox Corporation. All rights reserved. Sweet October 8, 1985 3:29:44 pm PDT Satterthwaite March 11, 1986 10:45:02 am PST Mike Spreitzer July 30, 1986 10:56:28 pm PDT Andy Litman March 3, 1988 3:27:57 pm PST JKF February 27, 1990 1:10:52 pm PST Michael Plass, November 26, 1991 4:36 pm PST check for weird inserted symbols it's not a proc, signal, error, program, or port print adjectives, if any print module qualification of last ID in chain simple => PutCurrentModuleDot[]; finally print that last ID SELECT code FROM codeINT => printBase _ multiSubrange; ENDCASE; basic => won't see one, see the id first. long => { IF NOT IsVarOrRef [rangeType, stb] THEN PutRope["LONG "]; [] _ PrintType[st, stb, rangeType, NoSub, defaultPublic]}; li: INT = LOOPHOLE [@value, LUP]^; lu: LONG CARDINAL = LOOPHOLE [@value, LUP]^; สฑ–(cedarcode) style•NewlineDelimiter ™šœ)™)Jšœ ฯeœ1™˜>—šœ˜K˜Kšžœ žœ˜&K˜Kšœ>˜>—šœ ˜ K˜šžœžœ˜Kšœ ˜ šžœžœž˜$Kšœ.žœ˜EK˜Kšžœžœ˜—Kšœ˜—šžœžœ˜K˜K˜šžœžœž˜%Kšœ.žœ˜DK˜Kšžœžœ˜—Kšœ˜—Kšœ˜—šœ ˜ K˜K˜šžœ ž˜Kšœžœ žœ žœ ˜6—šžœ˜K˜Kš œžœ žœ žœžœ˜K—K˜!šžœ(ž˜.Kšœžœžœ žœ ˜9—šžœžœž˜!K˜=K˜Kšžœ˜—K˜Kšœ˜K˜K˜KšžœH˜Kšžœž˜K˜K˜K˜K˜Kšœ žœG˜XK˜LK˜K˜Kšžœ˜—K˜K˜Kšœ˜Kšœ˜—šœ ˜ Kšžœžœ9˜RK˜Kšœ;˜;—šœ ˜ K˜Kšœžœ˜&Kšžœžœ˜"K˜Kšžœ žœ˜(šžœ˜K˜Kšœžœ žœžœ˜?—K˜!šžœž˜Kšœžœžœ žœ ˜9—K˜0K˜Kšœ>˜>—šœ ˜ Kšœžœ ˜Kšœžœ ˜Kšœžœ ˜K˜šœžœžœ˜Kšœžœžœžœ˜5K˜K˜ K˜#K˜Kšžœžœ2˜—šž˜Kšžœ žœžœ žœ˜I——Kšžœ˜———K˜šŸ œžœ(žœžœ˜Kšžœ žœž˜-šœ žœžœž˜0Kšœ žœ!˜0Kšžœ˜—Kšžœ˜—Kšžœ˜ K˜—K˜šŸ œžœžœžœ;˜\šŸœžœžœ˜Kšœ˜—šŸœžœžœ˜Kšœ˜—šŸœžœ˜!K˜9—šŸœžœ˜ K˜;K˜—Kšžœžœžœ˜ šžœ žœž˜-šœ ˜ K˜%šžœ ž˜šœ˜K˜šžœžœž˜K˜RKšžœ˜—Kšœ ˜ —˜ K˜ K˜*—˜ Kšœžœžœžœ"˜9K˜ K˜ —K˜DK˜K˜šœ˜K˜0Kšœ ˜Kšœ1˜1—šœ˜šœžœ žœ˜K˜K˜Kšžœ ˜—K˜(Kšœ˜—šœ ˜ K˜Kšžœžœ˜Cšžœ˜K˜K˜K˜—Kšœ˜—šœ˜K˜K˜ Kšžœžœ*˜@Kšœ ˜ —šœ ˜ Kšœ)˜)Kšœ ˜ Kšœ)˜)Kšœ˜—šœ ˜ Kšœžœžœ˜šŸœ˜Kšžœžœ žœžœ˜/Kšœ(˜(—Kšœ"˜"—šœ ˜ K˜Kšœ*˜*—˜ Kšœ)˜)Kšœ ˜ Kšœ)˜)Kšœ˜—šœ ˜ K˜K˜šžœžœž˜+˜ ˜:K˜——Kšœžœ)˜CKšžœ˜"—K˜0šžœžœž˜!Kšœžœžœ ˜"Kšžœ˜—Kšœ˜—Kšžœ˜—Kšœ˜—K˜K˜Kšœ˜šœ ˜ šžœžœž˜!K˜B˜šžœž˜šœ˜Kšœ žœžœ˜šžœž˜šœ ˜ Jšœ"™"Kšœžœžœ ˜šžœž˜Kšžœžœ˜#Kšžœžœ˜!Kšžœ˜—Kšœ˜—šœ ˜ Jšœ,™,Kšœžœžœžœ ˜(šžœž˜Kšžœžœžœ$˜6Kšžœ˜—Kšœ˜—Kšœžœ˜-˜šžœžœ žœž œ˜+Kšžœ˜Kšžœ žœ˜——Kšžœžœ˜—šžœ žœ˜K˜Kšœžœ ˜&Kšœ˜—Kšœ˜—Kšžœ˜#——Kšžœ ˜—Kšœ˜—Kšžœ ˜—Kšœ˜K˜——˜Kšžœ˜—K˜K˜—…—Yฎyื