-- State.mesa  last edit, Johnsson  September 16, 1980  5:06 PM
  -- Bruce on Oct 10, 1980 2:58 PM
  
DIRECTORY
  BcdDefs USING [CTIndex, CTNull],
  Commands USING [CommandRec, Prompt, StringId],
  DebugOps USING [Foo, FooProc],
  MachineDefs USING [CFP, ConfigIndex, ExternalStateVector, FHandle, FileHandle, GFHandle, NullConfig, NullGF, nullPHandle, 
  PHandle, SVPointer],
  PrincOps USING [SignalDesc],
  UserInput USING [StringProcType];
  
State: DEFINITIONS IMPORTS Commands =
  BEGIN OPEN MachineDefs;
  
  WritePrompt: PROC = INLINE {IF gs.resetPrompt THEN Commands.Prompt[]};
  
  -- parsing
  ParseProc: TYPE = PROCEDURE [CHARACTER];
  SetParse: PROCEDURE [proc: ParseProc];
  ResetParse: PROCEDURE;
  StringProc: UserInput.StringProcType;
  
  -- global state
  StringId: TYPE = Commands.StringId;
  StringArray: TYPE = ARRAY StringId OF STRING;
  Strings: TYPE = DESCRIPTOR FOR StringArray;
  
  strings: Strings;
  AllStrings: PROCEDURE RETURNS [Strings] = INLINE BEGIN RETURN[strings] END;
  GetString: PROCEDURE [id: StringId] RETURNS [STRING] =
    INLINE BEGIN RETURN[strings[id]] END;
  SetString: PROCEDURE [id: StringId, val: STRING];
  
  gs: GSHandle;
  GetGS, GetSet: PROCEDURE RETURNS [gsh: GSHandle] = INLINE BEGIN RETURN[gs] END;
  
  Msg: TYPE = {none, interrupt, punt, bootloaded, maplog, invalid};
  
  GSHandle: TYPE = POINTER TO GState;
  GState: TYPE = RECORD [
    parse: ParseProc ← LOOPHOLE[0],
    worryBreaks: BOOLEAN ← FALSE,
    level: INTEGER ← 0,
    tree: BOOLEAN ← FALSE,
    nubLevel: CARDINAL ← 1, 
    search: BOOLEAN ← FALSE,
    nubFrame, sigGF: GFHandle ← MachineDefs.NullGF,
    debugging: BOOLEAN ← FALSE,
    frame, gf, bytePC, acount, ocount: UNSPECIFIED ← 0,
    spare1: BOOLEAN ← FALSE,
    aread, oread, owrite: LONG POINTER ← NIL,
    restartMsg: Msg ← none,
    loggedIn: BOOLEAN ← FALSE,
    initBCD: BOOLEAN ← FALSE,
    worryEntry: BOOLEAN ← FALSE,
    inNub: BOOLEAN ← FALSE,
    ready: BOOLEAN ← FALSE,
    teledebugging: BOOLEAN ← FALSE,
    -- used by GetString
    firstChar: BOOLEAN ← TRUE,
    resetPrompt: BOOLEAN ← TRUE,
    resetParse: BOOLEAN ← TRUE,
    tool: BOOLEAN ← FALSE,
    currentId: Commands.StringId ← NULL,
    currentString: STRING ← NIL,
    com2: Commands.CommandRec ← NULL,
    s1: STRING ← NIL,
    cr: BOOLEAN ← NULL,
    call0: PROC ← LOOPHOLE[1],
    call1: PROC [STRING] ← LOOPHOLE[0],
    call2: PROC [STRING, STRING] ← LOOPHOLE[0],
    term: PROC [CHARACTER] RETURNS [BOOLEAN] ← LOOPHOLE[0],
    spare2: BOOLEAN ← FALSE,
    ESV: ExternalStateVector ← NULL,
    StatePtr: SVPointer ← NIL,
    signal: PrincOps.SignalDesc ← LOOPHOLE[0],
    breakFrame: FHandle ← NIL,
    mds: CARDINAL ← 0,
    debuggerFP, debuggeeFP, selfFP: CFP ← NULL,
    selfFH, debuggeeFH: FileHandle ← NIL];
    
  -- level dependent state
  top: PRIVATE Handle;
  
  Push: PROCEDURE;
  Pop: PROCEDURE;
  Get: PROCEDURE RETURNS [h: Handle] = INLINE
    BEGIN IF top = NIL THEN ERROR OutOfState; RETURN[top] END;
    
  LF: PROC RETURNS [FHandle] = INLINE
    BEGIN IF top = NIL THEN ERROR OutOfState; RETURN[top.lContext] END;
  GF: PROC RETURNS [GFHandle] = INLINE
    BEGIN IF top = NIL THEN ERROR OutOfState; RETURN[top.gContext] END;
  PSB: PROC RETURNS [PHandle] = INLINE
    BEGIN IF top = NIL THEN ERROR OutOfState; RETURN[top.pContext] END;
    
  DNode: TYPE = RECORD [link: NodeHandle, node: POINTER];
  NodeHandle: TYPE = POINTER TO DNode;
  NodeType: TYPE = {fobs};
  ContextType: TYPE = {none, local, psb, global, state, break};
  
  Handle: TYPE = POINTER TO Context;
  Context: TYPE = RECORD [
    prev: Handle ← NIL,
    lContext: FHandle ← NIL,
    gContext: GFHandle ← NIL,
    pContext: PHandle ← nullPHandle,
    interpretContext: POINTER ← NIL,
    reentrantParse: ParseProc ← LOOPHOLE[0],
    howSet: ContextType ← none,
    cti: BcdDefs.CTIndex ← BcdDefs.CTNull,
    config: ConfigIndex ← NullConfig,
    fobs: NodeHandle ← NIL,
    proc: DebugOps.FooProc ← LOOPHOLE[0],
    fooStack: POINTER TO Stack ← NIL];
    
  Stack: TYPE = RECORD [link: POINTER TO Stack, foo: DebugOps.Foo];
  
  -- Signals and utilities
  OnYourMark, Go: PROCEDURE;
  OutOfState: ERROR;
  
  END.