-- file: StackPack.Mesa
-- Edited by:
-- Bruce on October 8, 1980 11:53 AM
-- Barbara on April 4, 1979 7:28 PM
-- Sandman on January 9, 1980 9:22 AM
DIRECTORY
Actions USING [CallInterpreter],
Ascii USING [DEL, SP],
Commands USING [GetComment, GetString, Prompt, Umbrella],
DebugOps USING [fileSW, StringExpToDecimal],
DOutput USING [Char, Decimal, EOL, Text],
DSyms USING [GFHandle, GFrameMdi],
Frames USING [
DisplayLocalsF, DisplayLocalsGF, DisplayParametersF, DisplayParametersGF,
DisplayResultsF, DisplayResultsGF, FlushFrameCache, Invalid],
Gf USING [CheckStarted, Display, Frame, Handle, MainBody, Validate],
Init USING [CheckSymTabLength, TopLevel],
Lf USING [CatchFrame, Display, GF, Handle, NoPrevious, PC, Previous],
MachineDefs USING [FHandle, GFHandle, NullGF],
Pc USING [BytePC, Ep, Exit],
Source USING [Display],
State USING [Get, Handle, ResetParse, SetParse],
String USING [LowerCase],
Symbols USING [MDIndex, MDNull],
SymbolTable USING [Missing],
Table USING [Overflow],
TextSW USING [BlinkingCaret];
StackPack: PROGRAM
IMPORTS Actions, Commands, DebugOps, DOutput, DSyms, Frames, Gf,
Init, Lf, Pc, Source, State, String, SymbolTable, Table, TextSW
EXPORTS Actions, Commands =
BEGIN
FHandle: TYPE = MachineDefs.FHandle;
GFHandle: TYPE = MachineDefs.GFHandle;
DFMsg: TYPE = {
invalid, noSyms, options, gso, del, na, source, npf, dso, catch, lso};
StackOptions: TYPE = {global, local, limited};
options: StackOptions;
WriteMsg: PROCEDURE [msg: DFMsg] =
BEGIN
DOutput.Text[SELECT msg FROM
invalid => " ! Current context invalid."L,
noSyms => "No symbols for "L,
options => "--Options are: "L,
gso =>
""" "", --, List source, Parameters, Quit, Return values, Source, Variables"L,
del => " XXX"L,
na => " not available"L,
source => " Source: "L,
npf => "No previous frame!"L,
dso => ", Globals, Jump, Next"L,
catch => "CatchFrame: "L,
lso => "Jump, Next, Quit >"L,
ENDCASE => "?"L];
END;
DisplayStack: PUBLIC PROCEDURE =
BEGIN
h: State.Handle ← State.Get[];
DOutput.EOL[];
SELECT TRUE FROM
h.lContext # NIL => LocalDump[h.lContext];
h.gContext # NIL => GlobalDump[h.gContext];
ENDCASE => WriteMsg[invalid];
END;
DisplayModule: PUBLIC PROCEDURE [m: STRING] =
BEGIN --dump the global frame named by m
f: MachineDefs.GFHandle ← MachineDefs.NullGF;
f ← Gf.Frame[m ! Frames.Invalid => CONTINUE];
IF f # MachineDefs.NullGF THEN GlobalDump[f];
RETURN
END;
DumpFrame: PUBLIC PROCEDURE [f: UNSPECIFIED] =
BEGIN IF ~Gf.Validate[f] THEN LocalDump[f] ELSE GlobalDump[f] END;
Caret: PROC =
{DOutput.Text[" >"L]; TextSW.BlinkingCaret[DebugOps.fileSW, on]};
GlobalDump: PROCEDURE [gf: GFHandle] =
BEGIN --dump a global frame
f: FHandle ← Gf.MainBody[gf];
mdi: Symbols.MDIndex ← Symbols.MDNull;
IF f # NIL THEN {LocalDump[f]; RETURN};
DOutput.EOL[];
mdi ← DSyms.GFrameMdi[gf ! SymbolTable.Missing => CONTINUE];
DOutput.EOL[];
IF mdi = Symbols.MDNull THEN {
WriteMsg[noSyms]; Gf.Display[gf, NIL]; State.ResetParse[]; RETURN};
Gf.Display[gf, NIL];
State.Get[].h.interpretContext ← gf; options ← global;
State.SetParse[StackCommands];
Caret[];
RETURN
END;
LocalDump: PROCEDURE [f: FHandle] =
BEGIN
mdi: Symbols.MDIndex ← Symbols.MDNull;
DOutput.EOL[];
mdi ← DSyms.GFrameMdi[Lf.GF[f] ! SymbolTable.Missing => CONTINUE];
State.Get[].h.interpretContext ← f;
IF mdi = Symbols.MDNull THEN {WriteMsg[noSyms]; options ← limited}
ELSE options ← local;
IF Lf.CatchFrame[f] THEN WriteMsg[catch];
Lf.Display[f];
State.SetParse[StackCommands];
Caret[];
END;
Jump: PROC [s: STRING] = {DumpJump[DebugOps.StringExpToDecimal[s]]};
DumpJump: PROCEDURE [n: INTEGER] =
BEGIN
i: INTEGER;
frame: FHandle ← State.Get[].h.interpretContext;
FOR i IN [0..n) DO
frame ← Lf.Previous[frame ! Lf.NoPrevious =>
BEGIN OPEN DOutput;
IF i < n-1 THEN BEGIN Char['(]; Decimal[i]; Char[')] END;
EXIT;
END];
IF i MOD 50 = 0 THEN Frames.FlushFrameCache[];
ENDLOOP;
DOutput.EOL[];
LocalDump[frame];
RETURN
END;
DoSource: PROC [frame: POINTER, load: BOOLEAN] = {
SELECT options FROM
local => {
pc: Pc.BytePC ← Lf.PC[frame];
gf: GFHandle ← Lf.GF[frame];
IF Pc.Exit[frame, pc] THEN {
DOutput.Text[" at exit. "L];
pc ← Pc.Ep[pc, gf].start};
Source.Display[gf, pc, load]};
global => Source.Display[frame,[0],load];
ENDCASE => BadChar[]};
prompt: BOOLEAN;
StackCommands: PROCEDURE [char: CHARACTER] = {
prompt ← TRUE;
Init.TopLevel[];
Commands.Umbrella[stack, char];
IF prompt THEN {Caret[]; TextSW.BlinkingCaret[DebugOps.fileSW, on]}};
UDS: PUBLIC PROCEDURE [char: CHARACTER] =
BEGIN ENABLE Table.Overflow => {Init.CheckSymTabLength[]; RETRY};
frame: POINTER ← State.Get[].h.interpretContext;
IF char # Ascii.SP AND char # Ascii.DEL THEN
{DOutput.Char[char]; TextSW.BlinkingCaret[DebugOps.fileSW, off]};
SELECT String.LowerCase[char] FROM
'j =>
IF options # global THEN {
prompt ← FALSE;
Commands.GetString[[sId:temp1, resetPrompt:FALSE],Jump,n10]}
ELSE BadChar[];
'n => IF options # global THEN {
DOutput.EOL[];
LocalDump[Lf.Previous[frame ! Lf.NoPrevious => GOTO npf]];
prompt ← FALSE}
ELSE BadChar[];
'p => SELECT options FROM
local => Frames.DisplayParametersF[frame];
global => {[] ← Gf.CheckStarted[frame]; Frames.DisplayParametersGF[frame]};
ENDCASE => BadChar[];
'v => SELECT options FROM
local => Frames.DisplayLocalsF[frame];
global => {[] ← Gf.CheckStarted[frame]; Frames.DisplayLocalsGF[frame]};
ENDCASE => BadChar[];
'r => SELECT options FROM
local => Frames.DisplayResultsF[frame];
global => {[] ← Gf.CheckStarted[frame]; Frames.DisplayResultsGF[frame]};
ENDCASE => BadChar[];
's => DoSource[frame,TRUE];
'l => DoSource[frame,FALSE];
'g =>
IF options = local THEN Frames.DisplayLocalsGF[Lf.GF[frame]] ELSE BadChar[];
'q, Ascii.DEL => {Commands.Prompt[]; prompt ← FALSE; RETURN};
Ascii.SP => {Actions.CallInterpreter[]; prompt ← FALSE; RETURN};
'- => {Commands.GetComment[FALSE]; prompt ← FALSE; RETURN};
'? => ListOptions[];
ENDCASE => BadChar[];
RETURN;
EXITS
npf => {DOutput.EOL[]; WriteMsg[npf]; prompt ← FALSE; Commands.Prompt[]};
END;
BadChar: PROC = {DOutput.Char['?]};
ListOptions: PROC = {
WriteMsg[options];
IF options = limited THEN WriteMsg[lso]
ELSE {WriteMsg[gso]; IF options = local THEN WriteMsg[dso]};
DOutput.EOL[]};
END.