-- 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.