<> <> <> <> <> DIRECTORY Literals USING [ LitIndex, LTIndex, LTRecord, ltType, STIndex, STNull, STRecord, stType], RESOut USING [ Handle, Log10, Log8, PChar, PCr, PNext, PNextUnsigned, POctal, PRope, PUnsigned], STDebugDefs USING [ HashForSei, PSTString, PutHashString, PutNodeName, ShowLinks, STCopyRead, STRead, TableBase, TreeDepth], Symbols USING [HTIndex], Table USING [Base], Tree USING [Index, Link, Node, Null, treeType]; STDebugTrees: PROGRAM IMPORTS RESOut, STDebugDefs EXPORTS STDebugDefs = BEGIN OPEN RESOut, STDebugDefs; Handle: TYPE = RESOut.Handle; PutAsTree: PUBLIC PROC [h: Handle, t: Tree.Link] = BEGIN PutSubTree[h, t, 0, TreeDepth[h]]; END; PutSubTree: PROC [h: Handle, t: Tree.Link, depth, remaining: CARDINAL] = BEGIN OPEN Tree; overflow: CARDINAL = 2*depth+1; PCr[h]; THROUGH [0.. depth) DO PRope[h, " "] ENDLOOP; WITH tt: t SELECT FROM literal => BEGIN PutLiteral[h, tt, overflow]; IF ShowLinks[h] THEN BEGIN extra: CARDINAL _ 6 + Log10[(WITH tt.index SELECT FROM word => LOOPHOLE[lti], string => LOOPHOLE[sti], ENDCASE => ERROR)]; PNext[h, "(", extra, overflow]; WITH tt.index SELECT FROM word => BEGIN PRope[h, "lti: "]; PUnsigned[h, LOOPHOLE[lti]] END; string => BEGIN PRope[h, "sti: "]; PUnsigned[h, LOOPHOLE[sti]] END; ENDCASE; PChar[h, ')]; END; END; -- of literal arm symbol => BEGIN hti: Symbols.HTIndex _ HashForSei[h, tt.index]; PutHashString[h, hti]; IF ShowLinks[h] THEN BEGIN extra: CARDINAL _ Log10[LOOPHOLE[tt.index]]+1; PNext[h, "(sei: ", extra, overflow]; PUnsigned[h, LOOPHOLE[tt.index]]; PChar[h, ')]; END; END; -- of symbol arm hash => BEGIN PutHashString[h, tt.index]; IF ShowLinks[h] THEN BEGIN extra: CARDINAL _ Log10[tt.index]+1; PNext[h, "(hti: ", extra, overflow]; PUnsigned[h, tt.index]; PChar[h, ')]; END; END; -- of hash arm subtree => IF t = Tree.Null THEN PRope[h, ""] ELSE BEGIN tb: Table.Base _ TableBase[h, treeType]; tn: Tree.Node; STCopyRead[h: h, to: @tn, from: @tb[tt.index], nwords: SIZE [Tree.Node]]; PChar[h, '[]; PUnsigned[h, LOOPHOLE[tt.index]]; PRope[h, "] "]; IF tn.free THEN BEGIN PRope[h, "FREE!"]; GO TO done END; PutNodeName[h, tn.name]; PNextUnsigned[h, "info", tn.info, overflow]; IF tn.attr1 OR tn.attr2 OR tn.attr3 THEN BEGIN PNext[h, "attr: ", 3, overflow]; IF tn.attr1 THEN PChar[h, '1]; IF tn.attr2 THEN PChar[h, '2]; IF tn.attr3 THEN PChar[h, '3]; END; IF tn.shared THEN PNext[h, "shared",,overflow]; IF remaining # 0 THEN BEGIN endIndex: Tree.Index = LAST[Tree.Index]; endMark: Tree.Link = [subtree[index: endIndex]]; son: Tree.Link; p: LONG POINTER _ @tb[tt.index].son[1]; IF tn.name # list OR tn.nSons # 0 THEN THROUGH [0..tn.nSons) DO STCopyRead[h: h, from: p, to: @son, nwords: SIZE[Tree.Link]]; PutSubTree[h, son, depth+1, remaining-1]; p _ p + SIZE[Tree.Link]; ENDLOOP ELSE DO STCopyRead[h: h, from: p, to: @son, nwords: SIZE[Tree.Link]]; IF son = endMark THEN EXIT; PutSubTree[h, son, depth+1, remaining-1]; p _ p + SIZE[Tree.Link]; ENDLOOP; END; EXITS done => NULL; END; -- of subtree arm ENDCASE; END; PutAsLti: PUBLIC PROC [h: Handle, lti: Literals.LitIndex] = BEGIN PCr[h]; WITH lti SELECT FROM word => BEGIN PRope[h, "ltb["]; PUnsigned[h, LOOPHOLE[lti]] END; string => BEGIN PRope[h, "stb["]; PUnsigned[h, LOOPHOLE[sti]] END; ENDCASE; PRope[h, "] = "]; PutLiteral[h, [literal[lti]], 2]; END; PutLiteral: PROC[h: Handle, t: literal Tree.Link, overflow: CARDINAL] = BEGIN OPEN Literals; WITH t.index SELECT FROM word => PutWordLiteral[h, lti, overflow]; string => PutStringLiteral[h, sti]; ENDCASE; END; PutWordLiteral: PROC [h: Handle, lti: Literals.LTIndex, overflow: CARDINAL] = BEGIN OPEN Literals; ltr: LTRecord; ltb: Table.Base; ltb _ TableBase[h, ltType]; STCopyRead[h: h, to: @ltr, from: @ltb[lti], nwords: SIZE[LTRecord]]; WITH ltr SELECT FROM short => POctal[h, value]; long => BEGIN i, w: CARDINAL; p: LONG POINTER _ @(LOOPHOLE[ltb[lti], long LTRecord]).value; PChar[h, '[]; FOR i IN [0..length) DO w _ STRead[h, p+i]; IF i # 0 THEN PNext[h, "", Log8[w], overflow]; POctal[h, w]; ENDLOOP; PChar[h, ']]; END; ENDCASE; END; PutStringLiteral: PROC [h: Handle, sti: Literals.STIndex] = BEGIN OPEN Literals; stb: Table.Base; str: STRecord _ [copy[FALSE, LOOPHOLE[STNull]]]; stb _ TableBase[h, stType]; DO -- until a master string (at most twice) STCopyRead[h: h, to: @str, from: @stb[sti], nwords: SIZE[STRecord]]; WITH str SELECT FROM copy => sti _ link; master => BEGIN PChar[h, '"]; PSTString[h, @(LOOPHOLE[ stb[sti], master STRecord]).string]; PChar[h, '"]; IF local THEN PChar[h, 'L]; EXIT; END; ENDCASE; ENDLOOP; END; END.