-- CGenDebugCommands.mesa  Edited by Bruce,  October 14, 1980  4:24 PM

DIRECTORY
  Ascii USING [CR, SP, TAB],
  CGenDebugCommandDefs USING [ParamIndex],
  CGenDebugDefs USING [
    CCCur, CCFirst, GoFwd, PrintNextLine, PrintPrevLine, PutAsCC, 
    PutAsComponent, PutAsFopcode, PutAsLabelInfoIndex, 
    PutAsStack, PutAsVar, PutCurrentBody, PutCurrentExpr, 
    PutCurrentSource, PutCurrentStmt, PutLabelState, PutNextCC, PutPrevCC, 
    PutRecentCC, PutStackDown, PutStackState, PutStackUp, PutTempState, 
    StackTop],
  FormSW USING [ProcType],
  Inline USING [LongNumber],
  MsgSW USING [Clear, Post],
  Put USING [Char, Text],
  RESOut USING [PCr, POctal, PString, WindowsHandle],
  Selection USING [LongNumber],
  STDebugDefs USING [
    NextSe, PutAsBti, PutAsCti, PutAsHti, PutAsMdi, PutAsMopcode, PutAsSei, PutAsTree,
    PutAsVariousRep],
  String USING [InvalidNumber],
  UserInput USING [ResetUserAbort, userAbort];

CGenDebugCommands: PROGRAM 
  IMPORTS 
    CGenDebugDefs, MsgSW, Put,
    RESOut, Selection, STDebugDefs, String, UserInput
  EXPORTS CGenDebugDefs, RESOut =
  BEGIN OPEN CGenDebugDefs, STDebugDefs;

  handle: PUBLIC RESOut.WindowsHandle ← NIL;

  cancelAction: PUBLIC ERROR [endLine: BOOLEAN ← FALSE] = CODE;

  ParamNotify: PUBLIC FormSW.ProcType =
    BEGIN OPEN CGenDebugCommandDefs;
    ENABLE cancelAction =>  
      BEGIN
      IF endLine THEN Put.Text[handle.fileSW, " XXX"L];
      GO TO done;
      END;
    Complain[""L]; UserInput.ResetUserAbort[];
    SELECT LOOPHOLE[index, ParamIndex] FROM
      tree => PutAsTree[GetSelectionValue[]];
      asCC => PutAsCC[GetSelectionValue[]];
      var => 
	BEGIN
	RESOut.PCr[];
	PutAsVar[GetSelectionValue[]];
	END;
      vcomp => 
	BEGIN OPEN RESOut;
	val: UNSPECIFIED ← GetSelectionValue[];
	PCr[];
	POctal[val]; PString["↑ = "L];
	PutAsComponent[val];
	END;

      first => PutAsCC[CCFirst[]];
      cur => PutAsCC[CCCur[]];
      next => PutNextCC[];
      prev => PutPrevCC[];
      fwd => GoFwd[GetSelectionValue[]];
      rcnt => PutRecentCC[GetSelectionValue[]];

      temp => PutTempState[];
      allStack => PutStackState[];
      stack => PutAsStack[GetSelectionValue[]];
      tos => PutAsStack[StackTop[]];
      down => PutStackDown[];
      up => PutStackUp[];
      lbl => PutLabelState[];
      lii => PutAsLabelInfoIndex[GetSelectionValue[]];

      sei => PutAsSei[GetSelectionValue[]];
      nextse => NextSe[];
      hti => PutAsHti[GetSelectionValue[]];
      cti => PutAsCti[GetSelectionValue[]];
      bti => PutAsBti[GetSelectionValue[]];
      mdi => PutAsMdi[GetSelectionValue[]];

      mop => PutAsMopcode[GetSelectionValue[]];
      fop => PutAsFopcode[GetSelectionValue[]];
      rep => PutAsVariousRep[GetSelectionValue[]];

      body => PutCurrentBody[];
      stmt => PutCurrentStmt[];
      expr => PutCurrentExpr[];

      source => PutCurrentSource[];
      srcbk => PrintPrevLine[];
      srcfwd => PrintNextLine[];
      ENDCASE;
    EXITS
      done => NULL;
    END;

  GetSelectionValue: PUBLIC PROCEDURE RETURNS [val: UNSPECIFIED] =
    BEGIN
    num: Inline.LongNumber;
    num.lc ← GetLongSelectionValue[];
    SELECT num.highbits FROM
      0, 177777B => NULL;
      ENDCASE => {Complain["number too big"L]; ERROR cancelAction};
    RETURN[num.lowbits];
    END;

  GetLongSelectionValue: PUBLIC PROCEDURE RETURNS [val: LONG UNSPECIFIED] =
    BEGIN
    val ← Selection.LongNumber[radix: 10 !
	String.InvalidNumber => GO TO noNumber];
    RETURN;
    EXITS
      noNumber =>
	BEGIN
	Complain["Select a number first"L];
	ERROR cancelAction;
	END;
    END;

  Complain: PUBLIC PROCEDURE [msg: STRING, clear: BOOLEAN ← TRUE] =
    BEGIN
    IF handle.msgSW = NIL THEN RETURN;
    IF clear THEN MsgSW.Clear[handle.msgSW];
    MsgSW.Post[sw: handle.msgSW, string: msg, prefix: FALSE, endOfMsg: FALSE];
    END;

-- log writing procedures

  charsOnLine: CARDINAL ← 0;

  PChar: PUBLIC PROCEDURE [c: CHARACTER] =
    BEGIN
    IF UserInput.userAbort THEN ERROR cancelAction[TRUE];
    Put.Char[handle.fileSW, c];
    charsOnLine ← SELECT c FROM
      Ascii.TAB  => ((charsOnLine+8)/8)*8,
      Ascii.CR => 0,
      ENDCASE => charsOnLine + 1;
    END;

  MakeRoom: PUBLIC PROCEDURE [chars, indent: CARDINAL] 
      RETURNS [was: BOOLEAN]=
    BEGIN
    charsPerLine: CARDINAL = handle.fileSW.box.dims.w/7-4;
    IF charsOnLine + chars <= charsPerLine THEN RETURN [TRUE];
    PChar[Ascii.CR];
    THROUGH [0..indent/8) DO PChar[Ascii.TAB]; ENDLOOP;
    THROUGH [0..indent MOD 8) DO PChar[Ascii.SP]; ENDLOOP;
    RETURN[FALSE];
    END;

  END.