-- file SLList.mesa
-- last edited by Satterthwaite, September 16, 1982 8:26 am
DIRECTORY
BcdDefs: TYPE USING [VersionStamp],
CBinary: TYPE USING [DebugTab],
CharIO: TYPE USING [PutChar, PutDecimal, PutString],
CompilerUtil: TYPE USING [StreamId, TableId, PrintSymbols, PrintBodies],
Environment: TYPE USING [PageNumber, PageCount],
FileSegment: TYPE USING [Pages, nullPages],
Heap: TYPE USING [systemZone],
ListerOps: TYPE USING [],
ListerUtil: TYPE USING [
CreateStream, LoadBcd, LoadModule, Message, PutFileID, PutVersions,
SetFileName, SetRoutineSymbols, UnknownModule],
LiteralOps: TYPE USING [Initialize, Finalize],
OSMiscOps: TYPE USING [FindFile, FileError],
Runtime: TYPE USING [GetTableBase, GlobalFrame],
Stream: TYPE USING [Handle, Delete],
Strings: TYPE USING [String, AppendString],
SymbolTable: TYPE USING [Acquire, Base, Release, SetCacheSize],
TreeOps: TYPE USING [Finalize, Initialize];
SLList: PROGRAM
IMPORTS
CBinary, CharIO, CompilerUtil, Heap, ListerUtil,
LiteralOps, OSMiscOps, Runtime, Stream, Strings, SymbolTable, TreeOps
EXPORTS CompilerUtil, ListerOps = {
OPEN ListerUtil;
-- output streams
out: Stream.Handle ← NIL;
OpenOutput: PROC [root: Strings.String] = {
outName: STRING ← [40];
ListerUtil.SetFileName[outName, root, "sl"L];
out ← ListerUtil.CreateStream[outName]};
CloseOutput: PROC = {
Stream.Delete[out]; out ← NIL};
-- symbol table bases
symbols: SymbolTable.Base ← NIL;
-- overall control
CommandOption: TYPE = {none, bodies, symbols, both};
MapOptions: ARRAY BOOL OF ARRAY BOOL OF CommandOption = [
[none, bodies], [symbols, both]];
SymbolSeg: TYPE = RECORD [
base: Environment.PageNumber,
pages: Environment.PageCount];
PrintSyms: PROC [
sseg: FileSegment.Pages, option: CommandOption, versions: BOOL] = {
SymbolTable.SetCacheSize[0]; -- flush cache
symbols ← SymbolTable.Acquire[sseg];
ListerUtil.SetRoutineSymbols[symbols];
IF versions THEN {
version, creator: BcdDefs.VersionStamp;
version ← symbols.stHandle.version;
creator ← symbols.stHandle.creator;
ListerUtil.PutVersions[out, @version, @creator]};
TreeOps.Initialize[NIL, NIL]; LiteralOps.Initialize[NIL, Heap.systemZone];
IF option = symbols OR option = both THEN
CompilerUtil.PrintSymbols[NIL, symbols.stHandle.definitionsFile];
IF option = bodies OR option = both THEN CompilerUtil.PrintBodies[NIL];
LiteralOps.Finalize[]; TreeOps.Finalize[];
SymbolTable.Release[symbols]; symbols ← NIL};
MakeBcdFilename: PROC [bcd, root: Strings.String] = {
Strings.AppendString[bcd, root];
FOR i: CARDINAL IN [0..bcd.length) DO IF bcd[i] = '. THEN RETURN ENDLOOP;
Strings.AppendString[bcd, ".bcd"L]};
DoSymbols: PROC [root: Strings.String, option: CommandOption] = {
OPEN ListerUtil;
bcdFile: Strings.String ← [100];
bcdSeg, sSeg: FileSegment.Pages;
MakeBcdFilename[bcdFile, root];
bcdSeg ← LoadBcd[bcdFile];
IF bcdSeg = FileSegment.nullPages THEN GO TO NoFile;
[symbols: sSeg] ← LoadModule[bcdSeg, root ! UnknownModule => {GOTO NoModule}];
IF sSeg = FileSegment.nullPages THEN GO TO NoSymbols;
OpenOutput[root];
ListerUtil.PutFileID[out];
PrintSyms[sSeg, option, FALSE];
CloseOutput[];
EXITS
NoFile => Message["File could not be opened"L];
NoModule => {
Message["File does not contain module "L]; Message[root]};
NoSymbols => Message["Symbols not available"L]};
DoSymbolSegment: PROC [
root: Strings.String, pages: SymbolSeg, option: CommandOption] = {
bcdFile: Strings.String ← [100];
sseg: FileSegment.Pages;
MakeBcdFilename[bcdFile, root];
sseg ← [
file: OSMiscOps.FindFile[bcdFile ! OSMiscOps.FileError => {GO TO NoFile}],
span: [pages.base, pages.pages] --! SwapProblem[] => {GO TO BadSegment}--];
OpenOutput[root];
CharIO.PutString[out, "Symbol Table in file: "L];
CharIO.PutString[out, root];
CharIO.PutString[out, ", base: "L]; CharIO.PutDecimal[out, pages.base];
CharIO.PutString[out, ", pages: "L]; CharIO.PutDecimal[out, pages.pages];
CharIO.PutChar[out, '\n];
PrintSyms[sseg, option, TRUE];
EXITS
NoFile => Message["File not found"L];
--BadSegment => Message["Bad Segment"L]--};
ListSymbols: PUBLIC PROC [root: Strings.String, symbols, trees: BOOL] = {
DoSymbols[root, MapOptions[symbols][trees]]};
-- replacements for compiler utilities
-- CompilerUtil
AcquireTable: PUBLIC PROC [id: CompilerUtil.TableId] RETURNS [LONG POINTER] = {
RETURN[
IF id # $debug THEN NIL
ELSE Runtime.GetTableBase[Runtime.GlobalFrame[CBinary.DebugTab]]]};
ReleaseTable: PUBLIC PROC [CompilerUtil.TableId] = {};
AcquireStream: PUBLIC PROC [id: CompilerUtil.StreamId] RETURNS [Stream.Handle] = {
RETURN[IF id = $log THEN out ELSE NIL]};
ReleaseStream: PUBLIC PROC [CompilerUtil.StreamId] = {};
}.