-- File: Dispatch.mesa edit by:
-- Bruce October 21, 1980 12:46 PM
-- Sandman July 30, 1980 9:47 AM
DIRECTORY
Actions USING [
AsciiDisplay, AsciiRead, AttachImage, AttachLoadState, CallInterpreter, CallNub,
DisplayFrame, DisplayModule, DisplayStack, DoKill, DoProceed, DoQuit, FindVar,
OctalRead, OctalWrite, PrintCoremap, SearchMode, SetOctalContext,
SetProcessContext, StartUser, TeleDebug, TreeMode, UserScreen, WorryMode],
Ascii USING [ControlC, ControlD, ControlN, ControlS, ControlT, DEL, ESC, SP],
BP USING [
AttachCondition, AttachExpression, BreakAllEntries, BreakAllXits, BreakEntry,
BreakExit, ClearAllBreaks, ClearAllEntries, ClearAllXits, ClearBreak, ClearCondition,
ClearDefault, ClearEntryBreak, ClearEntryTrace, ClearExpression, ClearOctal,
ClearXitBreak, ClearXitTrace, Conditionalize, Expressionalize,
List, ListBreak, ListBreaks, OctalBreak, TraceAllEntries, TraceAllXits, TraceEntry,
TraceExit],
CommandList USING [Command, Error],
Commands USING [
Command, Confirm, DispatchChar, Error, Execute, GetComment, GetString, GetTwoStrings,
Login, ModuleBreak, Umbrella, WriteCommand, WriteError],
DContext USING [
DisplayConfig, DisplayCurrent, ListConfigs, Reset, SetConfig, SetModule,SetRootConfig],
DebugOps USING [
Abort, BBHandle, fileSW, InvalidateFileCache, Kill, Proceed, Quit, UserAborted],
DOutput USING [Char, Decimal, EOL, Line, Text],
DPsb USING [
DisplayProcess, DisplayQueue, DisplayReadyList, ListProcesses, ResetCache],
DSyms USING [AttachSymbols],
Dump USING [EvalStack],
Frames USING [FlushFrameCache],
Gf USING [DisplayGFT],
Init USING [CoreSwap, FlushCaches, TopLevel],
MachineDefs USING [CoPilot, FHandle, GFHandle],
Nub USING [DoCommand],
State USING [Get, GetGS, GSHandle, Handle, Pop, Push, top],
String USING [AppendChar, LowerCase],
TextSW USING [BlinkingCaret],
UserInput USING [userAbort],
TajoMisc USING [SetState];
Dispatch: PROGRAM
IMPORTS
Actions, BP, Commands, DContext, DebugOps, DOutput, DPsb, DSyms, Dump,
Frames, Gf, Init, Nub, State, String, UserInput, TajoMisc, TextSW
EXPORTS Commands =
BEGIN OPEN Actions, Commands;
Command: PUBLIC TYPE = CommandList.Command;
Error: PUBLIC TYPE = CommandList.Error;
GFHandle: TYPE = MachineDefs.GFHandle;
FHandle: TYPE = MachineDefs.FHandle;
data: State.GSHandle ← State.GetGS[];
CommandNotAllowed: PUBLIC SIGNAL = CODE;
SmashedContext: ERROR = CODE;
DoExp: PUBLIC PROC [param: DebugOps.BBHandle] =
BEGIN
IF param = NIL THEN RETURN;
IF param.bt.bt = trace THEN {
SendChars[SELECT param.bt.ex FROM
entry => "DSP"L, exit => "DSR"L, ENDCASE => "DSV"L];
[] ← TajoMisc.SetState[on]};
IF param.exp # NIL THEN SendChars[param.exp];
END;
SendChars: PROC [s: STRING] =
BEGIN
FOR i: CARDINAL IN [0..s.length) DO
IF UserInput.userAbort THEN SIGNAL DebugOps.UserAborted;
data.parse[s[i]];
ENDLOOP;
END;
Go: PUBLIC PROCEDURE [bb: DebugOps.BBHandle ← NIL] =
BEGIN
State.Push[];
data.inNub ← FALSE;
IF data.StatePtr = NIL THEN data.initBCD ← TRUE;
DContext.Reset[];
IF data.signal # LOOPHOLE[0] THEN Commands.Umbrella[ucs, 0];
DO
Prompt[];
BEGIN ENABLE
BEGIN
DebugOps.Abort, ABORTED => CONTINUE;
DebugOps.Kill => GOTO kill;
DebugOps.Quit =>
IF data.inNub THEN {LeaveNub[]; CONTINUE} ELSE GOTO abort;
DebugOps.Proceed =>
IF data.inNub THEN {LeaveNub[]; CONTINUE} ELSE EXIT;
UNWIND => State.Pop[];
END;
thisBreak ← bb;
Commands.Umbrella[exp, bb ! ANY => {bb ← NIL; REJECT}];
bb ← NIL;
[] ← TajoMisc.SetState[on];
Commands.Umbrella[notifier,NIL];
EXITS
kill =>
BEGIN
State.Pop[];
Init.CoreSwap[kill ! DebugOps.Abort => LOOP];
SIGNAL DebugOps.Abort;
END;
abort =>
BEGIN
State.Pop[];
Init.CoreSwap[quit ! DebugOps.Abort => LOOP];
SIGNAL DebugOps.Abort;
END;
END;
ENDLOOP;
State.Pop[];
RETURN
END;
thisBreak: DebugOps.BBHandle;
LeaveNub: PROC = {data.nubLevel ← data.nubLevel - 1; data.inNub ← FALSE};
DebuggingMode: PUBLIC PROC = BEGIN data.debugging ← ~data.debugging END;
Invalidate: PROC = {
Frames.FlushFrameCache[];
DPsb.ResetCache[];
Init.FlushCaches[flushSymbols];
DebugOps.InvalidateFileCache[]};
DisplayB: PROC [s: STRING] = {
SELECT TRUE FROM
s.length # 0 => {DOutput.EOL[]; BP.ListBreak[s]};
GetBreak[] => {DOutput.EOL[]; BP.List[thisBreak]};
ENDCASE};
ClearB: PROC [s: STRING] = {
IF s.length # 0 THEN {BP.ClearBreak[s]; thisBreak ← NIL; RETURN};
IF GetBreak[] THEN {BP.ClearDefault[thisBreak]; thisBreak ← NIL}};
ClearC: PROC [s: STRING] = {
IF s.length # 0 THEN {BP.ClearCondition[s]; RETURN};
IF GetBreak[] THEN BP.Conditionalize[thisBreak,NIL]};
ClearE: PROC [s: STRING] = {
IF s.length # 0 THEN {BP.ClearExpression[s]; RETURN};
IF GetBreak[] THEN BP.Expressionalize[thisBreak,NIL]};
GetBreak: PROC RETURNS [BOOLEAN] = {
IF thisBreak = NIL THEN {Commands.WriteError[notAtBreak, FALSE]; DOutput.EOL[]}
ELSE {DOutput.Decimal[thisBreak.num]; DOutput.EOL[]};
RETURN[thisBreak # NIL]};
Prefix: TYPE = {
ba, s, a, as, at, o, l, li, d, se, b, t, ta, top, cl, cla, cle, clx, c, re};
prefix: Prefix ← top;
cs: STRING ← [4];
param: STRING;
GetFrame: PROC [s: STRING] =
{param ← s; IF s # NIL THEN Confirm[null, StartFrame]};
StartFrame: PROC = {StartUser[param]};
GetDebuggee: PROC [s: STRING] =
{param ← s; IF s # NIL THEN Confirm[null, RemoteDebuggee]};
RemoteDebuggee: PROC = {TeleDebug[param]};
DispatchChar: PUBLIC PROCEDURE [char: CHARACTER] =
BEGIN OPEN Ascii, Commands;
c: CHARACTER;
i: [0..4];
IF data.tool THEN RETURN;
IF prefix = top THEN
IF char = ESC THEN
BEGIN
FOR i IN [0..cs.length) DO DispatchChar[cs[i]] ENDLOOP;
RETURN
END
ELSE cs.length ← 0;
String.AppendChar[cs, char];
SELECT (c←String.LowerCase[char]) FROM
'a =>
SELECT prefix FROM
cl => BEGIN prefix ← cla; WriteCommand[all]; DOutput.Char[' ]; END;
b => BEGIN prefix ← ba; WriteCommand[all]; DOutput.Char[' ]; END;
t => BEGIN prefix ← ta; WriteCommand[all]; DOutput.Char[' ]; END;
top => BEGIN prefix ← a; WriteCommand[a];END;
ENDCASE => GOTO what;
'b =>
SELECT prefix FROM
d => GetString[[sId: bbNum, prompt: bbNum], DisplayB, break];
li => Confirm[breaks, BP.ListBreaks];
cl => GetString[[sId: bbNum, prompt: bbNum], ClearB, break];
cla => Confirm[breaks, BP.ClearAllBreaks];
cle =>
GetString[[sId: proc], BP.ClearEntryBreak, breakProc];
clx =>
GetString[[sId: proc], BP.ClearXitBreak, breakProc];
top => BEGIN prefix ← b; WriteCommand[break]; DOutput.Char[SP] END;
ENDCASE => GOTO what;
'c =>
SELECT prefix FROM
at => GetTwoStrings[[sId: bbNum, prompt: bbNum, resetPrompt: FALSE],
[sId: exp, prompt: condition, resetPrompt: FALSE, atom: FALSE],
BP.AttachCondition, Condition];
cl => GetString[[sId: bbNum, prompt: bbNum], ClearC, Condition];
d => Execute[config, DContext.DisplayConfig];
li => Confirm[configs, DContext.ListConfigs];
o => GetTwoStrings[[sId: frame, resetPrompt: FALSE], [
prompt: bytePC, sId: pc, resetPrompt: FALSE],
BP.ClearOctal, clearGlobal];
se => GetString[[sId: config], DContext.SetConfig, config];
top => BEGIN prefix ← c; WriteCommand[c]; END;
ENDCASE => GOTO what;
'd =>
SELECT prefix FROM
as => GetTwoStrings[[sId: num1,resetPrompt: FALSE], [
sId: num2, prompt: n10, resetPrompt: FALSE], AsciiDisplay, display];
top => {WriteCommand[display]; DOutput.Char[SP]; prefix ← d};
ENDCASE => GOTO what;
'e =>
SELECT prefix FROM
d => Execute[evalStack, Dump.EvalStack];
s => BEGIN WriteCommand[set]; DOutput.Char[SP]; prefix ← se END;
b => GetString[[sId: proc], BP.BreakEntry, entryProc];
ba => ModuleBreak[BP.BreakAllEntries, entriesMod];
t => GetString[[sId: proc], BP.TraceEntry, entryProc];
ta => ModuleBreak[BP.TraceAllEntries, entriesMod];
cl => BEGIN WriteCommand[entry]; DOutput.Char[SP]; prefix ← cle END;
cla => GetString[[sId: module], BP.ClearAllEntries, entriesMod];
ENDCASE => GOTO what;
'f =>
SELECT prefix FROM
d =>
GetString[[sId: frame, resetPrompt: FALSE], DisplayFrame, frame];
top => GetString[[sId: var], FindVar, find];
ENDCASE => GOTO what;
'g =>
SELECT prefix FROM
d => Execute[gft, Gf.DisplayGFT];
ENDCASE => GOTO what;
'i =>
SELECT prefix FROM
at => IF MachineDefs.CoPilot THEN GOTO what
ELSE GetString[[sId: image], Actions.AttachImage, image];
l => BEGIN prefix ← li; WriteCommand[list]; DOutput.Char[SP]; END;
ENDCASE => GOTO what;
'k =>
SELECT prefix FROM
at => GetTwoStrings[[sId: bbNum, prompt: bbNum, resetPrompt: FALSE],
[sId: exp, prompt: expression, resetPrompt: FALSE, atom: FALSE],
BP.AttachExpression, Exp];
cl => GetString[[sId: bbNum, prompt: bbNum], ClearE, Exp];
top => Confirm[kill, DoKill];
ENDCASE => GOTO what;
'l =>
SELECT prefix FROM
c => BEGIN prefix ← cl; WriteCommand[clear]; DOutput.Char[SP]; END;
at => IF MachineDefs.CoPilot THEN GOTO what
ELSE GetString[[sId: image], Actions.AttachLoadState, loadstate];
top => BEGIN prefix ← l; WriteCommand[l]; END;
ENDCASE => GOTO what;
'm =>
SELECT prefix FROM
d => GetString[
[sId: module, resetPrompt: FALSE], DisplayModule, module];
se => GetString[[sId: module], DContext.SetModule, moduleCtx];
re => GetString[[sId: temp1, resetPrompt: FALSE], GetDebuggee, remote];
ENDCASE => GOTO what;
'o =>
SELECT prefix FROM
c => IF MachineDefs.CoPilot THEN GOTO what ELSE Confirm[coremap, PrintCoremap];
l => Commands.Login[];
se => GetString[[sId: frame], SetOctalContext, octalCtx];
top => {prefix ← o; WriteCommand[octal]; DOutput.Char[SP]};
ENDCASE => GOTO what;
'p =>
SELECT prefix FROM
d => GetString[
[sId: process, resetPrompt: FALSE], DPsb.DisplayProcess, process];
li => Confirm[processes, DPsb.ListProcesses];
se => GetString[[sId: process], SetProcessContext, processCtx];
top => Confirm[proceed, DoProceed];
ENDCASE => GOTO what;
'q =>
SELECT prefix FROM
d => GetString[
[sId: queue, resetPrompt: FALSE], DPsb.DisplayQueue, queue];
top => Confirm[quit, DoQuit];
ENDCASE => GOTO what;
'r =>
SELECT prefix FROM
as => GetTwoStrings[[sId: num1,resetPrompt: FALSE], [
sId: num2, prompt: n10, resetPrompt: FALSE], AsciiRead, read];
d => Execute[readyList, DPsb.DisplayReadyList, FALSE];
o => GetTwoStrings[[sId: num1, resetPrompt: FALSE], [
prompt: n10, sId: num2, resetPrompt: FALSE], OctalRead, read];
se => GetString[[sId: rconfig], DContext.SetRootConfig, rootCtx];
top => {prefix ← re; WriteCommand[re]};
ENDCASE => GOTO what;
's =>
SELECT prefix FROM
d => Execute[stack, DisplayStack, FALSE];
o => GetTwoStrings[[sId: frame, resetPrompt: FALSE],
[sId: pc, prompt: bytePC, resetPrompt: FALSE],
BP.OctalBreak, breakGlobal];
a => BEGIN prefix ← as; WriteCommand[ascii]; DOutput.Char[SP] END;
at => GetTwoStrings[
[prompt: symbols, sId: frame, resetPrompt: FALSE], [
sId:file, prompt:name, resetPrompt:FALSE], DSyms.AttachSymbols];
re => Confirm[reset, DContext.Reset];
top => BEGIN prefix ← s; WriteCommand[s]; END;
ENDCASE => GOTO what;
't =>
SELECT prefix FROM
top => BEGIN prefix ← t; WriteCommand[trace]; DOutput.Char[SP] END;
cla => Confirm[traces, BP.ClearAllBreaks];
cle => GetString[[sId: proc], BP.ClearEntryTrace, traceProc];
clx =>
GetString[[sId: proc], BP.ClearXitTrace, traceProc];
s => GetString[[sId: frame, resetPrompt: FALSE], GetFrame, start];
a => BEGIN prefix ← at; WriteCommand[attach]; DOutput.Char[SP] END;
ENDCASE => GOTO what;
'u =>
SELECT prefix FROM
c => Execute[current, DContext.DisplayCurrent];
top => Confirm[userscreen, UserScreen];
ENDCASE => GOTO what;
'w =>
SELECT prefix FROM
o => GetTwoStrings[[sId: num1, resetPrompt: FALSE], [
prompt: gets, sId: num2, resetPrompt: FALSE, colon: FALSE],
OctalWrite, write];
top =>
BEGIN
WriteCommand[worry];
Confirm[IF data.worryBreaks THEN off ELSE on, WorryMode];
END;
ENDCASE => GOTO what;
'x =>
SELECT prefix FROM
b => GetString[[sId: proc], BP.BreakExit, xitProc];
ba => ModuleBreak[BP.BreakAllXits, xitsMod];
t => GetString[[sId: proc], BP.TraceExit, xitProc];
ta => ModuleBreak[BP.TraceAllXits, xitsMod];
cl => BEGIN prefix ← clx; WriteCommand[xit]; DOutput.Char[SP]; END;
cla => GetString[[sId:module], BP.ClearAllXits, xitsMod];
ENDCASE => GOTO what;
ENDCASE =>
SELECT TRUE FROM
prefix = top =>
SELECT char FROM
ControlC => {
WriteCommand[check];
Confirm[IF data.debugging THEN off ELSE on, DebuggingMode]};
ControlD => Confirm[debug, CallNub];
ControlN => Confirm[spare2, Invalidate];
ControlS =>
BEGIN
WriteCommand[IF data.search THEN callStack ELSE oneFrame];
Confirm[null, SearchMode];
END;
ControlT =>
BEGIN
WriteCommand[treePrinting];
Confirm[IF data.tree THEN off ELSE on, TreeMode];
END;
SP => CallInterpreter[TRUE];
'- => GetComment[TRUE];
'? => UnknownCommand[firstCommand, kill];
ENDCASE => GOTO what;
char = '? =>
SELECT prefix FROM
ba,ta => UnknownCommand[entriesMod, xitsMod];
re => UnknownCommand[remote, reset];
s => UnknownCommand[start, set];
a => UnknownCommand[ascii, attach];
as => UnknownCommand[adisplay, read];
at => IF MachineDefs.CoPilot THEN UnknownCommand[Symbols, Exp]
ELSE UnknownCommand[image, loadstate];
o => UnknownCommand[read, clearGlobal];
l => UnknownCommand[login, list];
li => UnknownCommand[configs, breaks];
d => UnknownCommand[module, config];
se => UnknownCommand[config, rootCtx];
b,t => UnknownCommand[all, xitProc];
c => UnknownCommand[clear, IF MachineDefs.CoPilot THEN current ELSE coremap];
cl => UnknownCommand[entry, all];
cla => UnknownCommand[breaks, xitsMod];
cle => UnknownCommand[breakProc, traceProc];
clx => UnknownCommand[breakProc, traceProc];
ENDCASE => UnknownCommand[clear, current];
ENDCASE => GOTO what;
RETURN
EXITS what => UnknownChar[char];
END;
UnknownCommand: PROCEDURE [first, last: Command] =
BEGIN OPEN DOutput;
i: Command;
Line[" ?"L];
Text["Your options are: "L];
FOR i IN Command[first..last) DO
WriteCommand[i];
Text[", "L];
ENDLOOP;
WriteCommand[last];
EOL[];
Prompt[];
RETURN
END;
UnknownChar: PROCEDURE [char: CHARACTER] =
BEGIN OPEN DOutput;
IF char = Ascii.DEL THEN WriteCommand[del]
ELSE {Char[char]; Char['?]};
Prompt[];
RETURN
END;
Prompt: PUBLIC PROCEDURE=
BEGIN
inNub: BOOLEAN ← data.inNub;
level: CARDINAL ← IF inNub THEN data.nubLevel ELSE data.level;
h: State.Handle ← State.Get[];
data.resetPrompt ← data.resetParse ← TRUE;
DOutput.EOL[];
THROUGH [1..level] DO DOutput.Char[IF inNub THEN '/ ELSE '>] ENDLOOP;
data.parse ← IF inNub THEN Nub.DoCommand ELSE DispatchChar;
TextSW.BlinkingCaret[DebugOps.fileSW, on];
prefix ← top;
Init.TopLevel[];
h.interpretContext ← SELECT h.howSet FROM
none => NIL,
local => h.lContext,
psb => h.lContext,
global => h.gContext,
state => h.lContext,
ENDCASE => ERROR SmashedContext;
END;
END.