-- file TestCompilerImpl.Mesa
-- last edited by Satterthwaite, June 30, 1982 11:55 am

DIRECTORY
  Ascii: TYPE USING [CR],
  Exec: TYPE USING [AddCommand, commandLine],
  ExecOps: TYPE USING [Command],
  Feedback: TYPE USING [FinishItemProc, Handle, NoteProgressProc, Procs, ProcsHandle],
  Heap: TYPE USING [MakeNode, FreeNode],
  TemporarySpecialExecOps: TYPE USING [CompileUsingFeedback],
  UserTerminal: TYPE USING [
    Coordinate, CursorArray, GetCursorPattern, SetCursorPattern, SetMousePosition,
    mouse, screenHeight, screenWidth];
  
TestCompilerImpl: PROGRAM
    IMPORTS Exec, Heap, TemporarySpecialExecOps, UserTerminal = {

  Main: PROC = {
    nChars: CARDINAL = (Exec.commandLine.s.length - Exec.commandLine.i) + 1;
    command: ExecOps.Command ← Heap.MakeNode[n: (nChars+1)/2];
    cursorBits: UserTerminal.CursorArray ← ALL[177777b];
    cursorCoord: UserTerminal.Coordinate ← [64, 64];

    L1: WORD = 147777b;
    R1: WORD = 177763b;
    M1: WORD = 177177b;
    Two: WORD = 147763b;

    ClearCursor: PROC = {
      cursorBits ← ALL[177777b]; UserTerminal.SetCursorPattern[cursorBits]};

    SetCursor: PROC [position: {upper, middle, lower}, row: WORD] = {
      SELECT position FROM
	upper => cursorBits[2] ← cursorBits[3] ← row;
	middle => cursorBits[7] ← cursorBits[8] ← row;
	lower => cursorBits[12] ← cursorBits[13] ← row;
	ENDCASE};

    ChangeCursor: Feedback.NoteProgressProc = {
      ClearCursor[];
      SELECT state FROM
	1 => SetCursor[middle, M1];
	2 => {SetCursor[upper, L1]; SetCursor[lower, R1]};
	3 => {SetCursor[upper, R1]; SetCursor[middle, M1]; SetCursor[lower, L1]};
	4 => {SetCursor[upper, Two]; SetCursor[lower, Two]};
	5 => {SetCursor[upper, Two]; SetCursor[middle, M1]; SetCursor[lower, Two]};
	6 => {SetCursor[upper, Two]; SetCursor[middle, Two]; SetCursor[lower, Two]}
	ENDCASE;
      UserTerminal.SetCursorPattern[cursorBits]};

    StepCursor: Feedback.FinishItemProc = {
      IF (cursorCoord.y ← cursorCoord.y + 16) > UserTerminal.screenHeight - 64 THEN
        cursorCoord.y ← 64;
      IF (outcome = errors) OR (outcome = errorsAndWarnings) THEN {
	cursorCoord.x ← cursorCoord.x + 16;
	IF cursorCoord.x > UserTerminal.screenWidth - 64 THEN cursorCoord.x ← 64};
      UserTerminal.SetMousePosition[cursorCoord]};

    saveCursor: UserTerminal.CursorArray = UserTerminal.GetCursorPattern[];
    saveCoord: UserTerminal.Coordinate = UserTerminal.mouse↑;
    fProcs: Feedback.Procs ← [noteProgress: ChangeCursor, finishItem: StepCursor];
    j: CARDINAL ← 0;
    FOR i: CARDINAL IN [Exec.commandLine.i..Exec.commandLine.s.length) DO
      command[j] ← Exec.commandLine.s[i];  j ← j+1;
      ENDLOOP;
    command[j] ← Ascii.CR;
    UserTerminal.SetCursorPattern[cursorBits]; UserTerminal.SetMousePosition[cursorCoord];
    [] ← TemporarySpecialExecOps.CompileUsingFeedback[command, @fProcs];
    UserTerminal.SetCursorPattern[saveCursor]; UserTerminal.SetMousePosition[saveCoord];
    Heap.FreeNode[p: command]};
    
  Init: PROC = {Exec.AddCommand["TestCompiler.~"L, Main]};
  
  Init[];
  }.