-- DOutModule.mesa Edited by
  -- Bruce on May 14, 1980  3:19 PM
  -- Mark on April 16, 1980  7:06 PM

DIRECTORY
  Ascii: FROM "Ascii" USING [CR, NUL, SP],
  CharIO: FROM "chario",
  DebugFormat: FROM "DebugFormat" USING [LongSubString, NumberFormat],
  DebugOps: FROM "debugOps",
  DebugUsefulDefs: FROM "DebugUsefulDefs",
  DOutput: FROM "DOutput",
  Format: FROM "Format",
  Init: FROM "init" USING [myPlace],
  InlineDefs: FROM "inlinedefs" USING [LowHalf],
  IODefs: FROM "iodefs",
  NubOps: FROM "nubops",
  StreamDefs: FROM "StreamDefs" USING [StreamHandle],
  StringDefs: FROM "StringDefs" USING [
    SubString, SubStringDescriptor],
  TextSW: FROM "TextSW" USING [InsertChar, InsertString,
    InsertSubString],
  UserInput: FROM "userinput" USING [userAbort];

DOutModule: PROGRAM
  IMPORTS DebugOps, Format, Init, InlineDefs, TextSW, UserInput
  EXPORTS CharIO, DebugOps, DebugUsefulDefs, DOutput, IODefs, NubOps =
  PUBLIC BEGIN OPEN DebugFormat;

UserAborted: PUBLIC SIGNAL = CODE;

WhereAmI: PROC RETURNS [NubOps.Place] = {RETURN[Init.myPlace]};

-- CharIO
PutString: PROC [d: StreamDefs.StreamHandle, s: STRING] = {Text[s]};
PutSubString: PROC [d: StreamDefs.StreamHandle, s: StringDefs.SubString] =
  {SubString[s]};
PutDecimal: PROC [d: StreamDefs.StreamHandle, n: INTEGER] = {Decimal[n]};
PutOctal: PROC [d: StreamDefs.StreamHandle, n: UNSPECIFIED] = {Octal[n]};

-- DOutput
newLine: BOOLEAN ← TRUE;

OutChar: PROC [c: CHARACTER] =
  BEGIN TextSW.InsertChar[DebugOps.fileSW,c] END;

NewLine: PROCEDURE RETURNS [BOOLEAN] = BEGIN RETURN[newLine] END;

EOL: PROCEDURE =
  BEGIN
  IF ~newLine THEN OutChar[Ascii.CR];
  newLine ← TRUE;
  END;

Blanks: PROCEDURE [n: CARDINAL] =
  BEGIN
  THROUGH [0..n) DO OutChar[Ascii.SP] ENDLOOP;
  IF n # 0 THEN newLine ← FALSE;
  END;

WriteChar, Char: PROCEDURE [c: CHARACTER] =
  BEGIN
  IF c # Ascii.NUL THEN OutChar[c];
  newLine ← c = Ascii.CR;
  END;

WriteString, Text: PROCEDURE [s: STRING] =
  BEGIN
  IF UserInput.userAbort THEN SIGNAL UserAborted;
  TextSW.InsertString[DebugOps.fileSW,s];
  IF s.length # 0 THEN newLine ← s[s.length-1] = Ascii.CR;
  RETURN
  END;

SubString: PROCEDURE [s: StringDefs.SubString] =
  BEGIN
  IF UserInput.userAbort THEN SIGNAL UserAborted;
  TextSW.InsertSubString[DebugOps.fileSW,s];
  IF s.length # 0 THEN newLine ← s.base[s.length-1] = Ascii.CR;
  END;

LongSubString: PROCEDURE [s: DebugFormat.LongSubString] =
  BEGIN
  ss: StringDefs.SubStringDescriptor ← 
    [base: InlineDefs.LowHalf[s.base], offset: s.offset, length: s.length];
  SubString[@ss]
  END;

WriteLine, Line: PROCEDURE [s: STRING] = BEGIN Text[s]; Char[Ascii.CR] END;

WriteNumber, Number: PROCEDURE [n: UNSPECIFIED, f: NumberFormat] =
  BEGIN Format.Number[n,f,Text] END;

LongNumber: PROCEDURE [n: LONG CARDINAL, f: NumberFormat] =
  BEGIN Format.LongNumber[n, f, Text]; END;

WriteDecimal, Decimal: PROCEDURE [n: INTEGER] = {Format.Decimal[n,Text]};
WriteOctal, Octal: PROCEDURE [n: UNSPECIFIED] = {Format.Octal[n, Text]};

LongDecimal: PROCEDURE [n: LONG INTEGER] = {Format.LongDecimal[n, Text]};
LongOctal: PROCEDURE [n: LONG CARDINAL] = {Format.LongOctal[n, Text]};

Put: PROC [s: StreamDefs.StreamHandle, c: UNSPECIFIED] = {Char[c]};

END.