-- file CrossBinderImpl.mesa
-- last edited by Satterthwaite, October 28, 1982 11:43 am

DIRECTORY
  Exec: TYPE USING [AddCommand, commandLine, w],
  ExecOps: TYPE USING [Command],
  Feedback: TYPE USING [
    BeginItemProc, CreateProc, FinishItemProc, Handle, NoteProgressProc, Procs],
  Heap: TYPE USING [MakeNode, FreeNode],
  TemporarySpecialExecOps: TYPE USING [BindUsingFeedback],
  TTY: TYPE USING [Handle, PutChar];
  
CrossBinderImpl: PROGRAM IMPORTS Exec, Heap, TemporarySpecialExecOps, TTY = {

  PutLine: PROC [s: LONG STRING] ~ {
    IF s # NIL THEN
      FOR i: CARDINAL IN [0..s.length) DO (Exec.w).PutChar[s[i]] ENDLOOP};
    
  Main: PROC ~ {
    nChars: CARDINAL ~ (Exec.commandLine.s.length - Exec.commandLine.i) + 1;
    command: ExecOps.Command ← Heap.MakeNode[n~(nChars+1)/2];

    PrintHerald: Feedback.CreateProc ~ {PutLine[herald]; (Exec.w).PutChar['\n]; RETURN [NIL]};
    PrintItem: Feedback.BeginItemProc ~ {PutLine[item]};
    PrintDot: Feedback.NoteProgressProc ~ {(Exec.w).PutChar['.]};
    PrintSummary: Feedback.FinishItemProc ~ {PutLine[trailer]; (Exec.w).PutChar['\n]};

    fProcs: Feedback.Procs ← [
      create~PrintHerald, beginItem~PrintItem, noteProgress~PrintDot, finishItem~PrintSummary];
    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] ← '\n;
    [] ← TemporarySpecialExecOps.BindUsingFeedback[command, @fProcs];
    Heap.FreeNode[p~command]};
    
  Init: PROC ~ {Exec.AddCommand["CrossBinder.~"L, Main]};
  
  Init[];
  }.