-- DumpType.mesa; modified by: -- Hayes, October 16, 1980 11:25 PM -- Bruce, August 29, 1980 1:12 PM -- Mark, Oct 17, 1980 12:29 AM DIRECTORY Ascii USING [SP], DI USING [Format, SEIndex], DOutput USING [Char, EOL, Octal, Text], Dump USING [HashVal, HtiVal, ModeName, TypedNum], Lookup USING [CopyMore], MachineDefs USING [WordLength], SymbolOps USING [FirstCtxSe, NextSe, TypeLink, UnderType], Symbols USING [ BodyRecord, BTIndex, codeANY, CSEIndex, CTXIndex, HTIndex, HTNull, ISEIndex, ISENull, lZ, RecordSEIndex, RecordSENull, SEIndex, SENull, TransferMode, typeTYPE], SymbolSegment USING [bodyType, ctxType, seType], Table USING [AddNotify, Base, Bounds, DropNotify, Notifier]; DumpType: PROGRAM IMPORTS DI, DOutput, Dump, Lookup, SymbolOps, Table EXPORTS Dump = BEGIN OPEN DI, Dump, SymbolOps, Symbols; Sub: TYPE = PROCEDURE; NoSub: Sub = BEGIN RETURN END; seb: Table.Base; ctxb: Table.Base; bb: Table.Base; Notify: Table.Notifier = BEGIN OPEN SymbolSegment; seb ← base[seType]; ctxb ← base[ctxType]; bb ← base[bodyType]; END; Type: PUBLIC PROCEDURE [isei: ISEIndex, pub: BOOLEAN ← FALSE, nest: CARDINAL ← 0, recurring: BOOLEAN ← FALSE] = BEGIN OPEN seb[isei]; IF ~recurring THEN Table.AddNotify[Notify]; IF hash # HTNull THEN BEGIN HtiVal[hash]; DOutput.Text[": "L] END; IF ~recurring THEN BEGIN DOutput.Text[IF (pub ← public) THEN "PUBLIC "L ELSE "PRIVATE "L]; DOutput.Text["TYPE = "L]; END; PrintType[ tsei: IF idType = typeTYPE THEN idInfo ELSE idType, pub: pub, nest: nest]; IF ~recurring THEN Table.DropNotify[Notify]; END; TypedFieldCtx: PROCEDURE [ ctx: CTXIndex, pub: BOOLEAN, rec: BOOLEAN ← TRUE, nest: CARDINAL ← 0] = BEGIN isei: ISEIndex ← FirstCtxSe[ctx]; first: BOOLEAN ← TRUE; IF isei # ISENull AND seb[isei].idCtx # ctx THEN isei ← NextSe[isei]; IF isei = ISENull THEN BEGIN IF rec THEN DOutput.Text["[]"L]; RETURN END; IF rec THEN DOutput.Char['[]; FOR isei ← isei, NextSe[isei] UNTIL isei = ISENull DO IF first THEN first ← FALSE ELSE IF rec THEN DOutput.Text[", "L] ELSE DOutput.EOL[]; Type[isei, pub, nest, TRUE]; ENDLOOP; IF rec THEN DOutput.Char[']]; END; Indent: PROCEDURE [level: CARDINAL] = BEGIN i: CARDINAL; FOR i IN [0..level] DO DOutput.Text[" "L] ENDLOOP; END; PrintType: PROCEDURE [ tsei: SEIndex, pub: BOOLEAN, dosub: Sub ← NoSub, arraySub: BOOLEAN ← FALSE, nest: CARDINAL ← 0] = BEGIN OPEN DOutput; WITH t: seb[tsei] SELECT FROM id => BEGIN IF dosub = NoSub OR ~Format[LOOPHOLE[tsei]].intSub THEN BEGIN HashVal[LOOPHOLE[tsei]]; UNTIL (tsei ← TypeLink[tsei]) = SENull DO WITH seb[tsei] SELECT FROM id => BEGIN Char[' ]; HashVal[LOOPHOLE[tsei]]; IF ~mark3 OR ctxb[idCtx].level # lZ THEN BEGIN dosub[]; RETURN END; END; ENDCASE; ENDLOOP; END; dosub[]; END; cons => BEGIN WITH t SELECT FROM basic => NULL; ENDCASE => Lookup.CopyMore[tsei, TRUE]; WITH t SELECT FROM --basic => won't see one, see the id first. enumerated => BEGIN isei: ISEIndex; first: BOOLEAN ← TRUE; Char['{]; FOR isei ← FirstCtxSe[valueCtx], NextSe[isei] UNTIL isei= ISENull DO IF first THEN first ← FALSE ELSE Text[", "L]; HashVal[isei]; ENDLOOP; Char['}]; END; record => BEGIN IF ctxb[fieldCtx].level # lZ THEN BEGIN fctx: CTXIndex = fieldCtx; bti: BTIndex ← FIRST[BTIndex]; btlimit: BTIndex = bti+Table.Bounds[SymbolSegment.bodyType].size; Text["FRAME ["L]; UNTIL bti = btlimit DO WITH entry: bb[bti] SELECT FROM Callable => BEGIN IF entry.localCtx = fctx THEN BEGIN HashVal[entry.id]; Char[']]; EXIT END; bti ← bti + (WITH entry SELECT FROM Inner => SIZE[Inner Callable BodyRecord], ENDCASE => SIZE[Outer Callable BodyRecord]); END; ENDCASE => bti ← bti + SIZE[Other BodyRecord]; ENDLOOP; END ELSE BEGIN IF monitored THEN Text["MONITORED "L]; IF machineDep THEN Text["MACHINE DEPENDENT "L]; Text["RECORD "L]; TypedFieldCtx[fieldCtx, pub]; END; END; ref => BEGIN IF readOnly THEN Text["READ ONLY "L]; IF ordered THEN Text["ORDERED "L]; IF basing THEN Text["BASE "L]; Text["POINTER"L]; IF dosub # NoSub THEN BEGIN Char[Ascii.SP]; dosub[]; END; WITH seb[UnderType[refType]] SELECT FROM basic => IF code = Symbols.codeANY THEN GO TO noprint; ENDCASE; Text[" TO "L]; PrintType[refType, pub]; EXITS noprint => NULL; END; array => BEGIN IF packed THEN Text["PACKED "L]; Text["ARRAY "L]; PrintType[indexType, pub, NoSub, TRUE]; Text[" OF "L]; PrintType[componentType, pub]; END; arraydesc => BEGIN Text["DESCRIPTOR FOR "L]; PrintType[describedType, pub]; END; transfer => BEGIN ModeName[mode]; IF inRecord # RecordSENull THEN BEGIN Char[' ]; TypedFieldCtx[seb[inRecord].fieldCtx, pub]; END; IF outRecord # RecordSENull THEN BEGIN Text[" RETURNS "L]; TypedFieldCtx[seb[outRecord].fieldCtx, pub]; END; END; union => BEGIN tagType: SEIndex; Text["SELECT "L]; IF ~controlled THEN IF overlaid THEN Text["OVERLAID "L] ELSE Text["COMPUTED "L] ELSE BEGIN HashVal[tagSei]; Text[": "L] END; tagType ← seb[tagSei].idType; IF pub # seb[tagSei].public THEN Text[ IF ~pub THEN "PUBLIC "L ELSE "PRIVATE "L]; WITH seb[tagType] SELECT FROM id => PrintType[tagType, seb[tagSei].public]; cons => Char['*]; ENDCASE; Text[" FROM "L]; BEGIN temp, isei: ISEIndex; varRec: RecordSEIndex; FOR isei ← FirstCtxSe[caseCtx], temp UNTIL isei = ISENull DO EOL[]; Indent[nest]; HashVal[isei]; varRec ← seb[isei].idInfo; FOR temp ← NextSe[isei], NextSe[temp] UNTIL temp = ISENull OR seb[temp].idInfo # isei DO Text[", "L]; HashVal[temp]; ENDLOOP; Text[" => "L]; TypedFieldCtx[ ctx: seb[varRec].fieldCtx, pub: pub, nest: nest+1]; Char[',]; ENDLOOP; EOL[]; Indent[nest]; Text["ENDCASE"L]; END; END; sequence => { IF packed THEN Text["PACKED "L]; Text["SEQUENCE "L]; IF ~controlled THEN Text["COMPUTED "L] ELSE {HashVal[tagSei]; Text[": "L]}; IF pub # seb[tagSei].public THEN Text[ IF ~pub THEN "PUBLIC "L ELSE "PRIVATE "L]; PrintType[seb[tagSei].idType, seb[tagSei].public]; Text[" OF "L]; PrintType[componentType, pub]}; relative => BEGIN IF baseType # SENull THEN PrintType[baseType, pub]; Text["RELATIVE "L]; PrintType[offsetType, pub, dosub]; END; subrange => BEGIN org: INTEGER ← origin; size: CARDINAL ← range; type: SEIndex ← rangeType; doit: Sub = BEGIN Text[" ["L]; TypedNum[org, type]; Text[".."L]; IF arraySub AND size = 177777B THEN BEGIN TypedNum[org, type]; Char[')] END ELSE BEGIN TypedNum[org+size, type]; Char[']] END; END; PrintType[rangeType, pub, doit]; END; long => BEGIN Text["LONG "L]; PrintType[rangeType, pub]; END; real => Text["REAL"L]; opaque => { Text["TYPE "L]; IF lengthKnown THEN { Text["["L]; Octal[length/MachineDefs.WordLength]; Char[']]}}; zone => { IF mds THEN Text["MDSZone "L] ELSE {IF ~counted THEN Text["UNCOUNTED "L]; Text["ZONE "L]}}; ENDCASE END; ENDCASE; END; END.