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