-- SymbolTester.mesa last modified: Bruce  April 21, 1980  2:08 PM

DIRECTORY
  CompilerUtil: FROM "compilerutil",
  Commands: FROM "commands",
  DContext: FROM "Dcontext",
  DebugOps: FROM "debugops",
  DOutput: FROM "doutput" USING [Char, EOL, Text],
  DSyms: FROM "dsyms" USING [Initialize],
  Heap: FROM "heap",
  ImageDefs: FROM "imagedefs" USING [StopMesa],
  Init: FROM "init",
  IODefs: FROM "iodefs" USING [ReadLine],
  Lookup: FROM "lookup",
  MiscDefs: FROM "miscdefs" USING [DestroyFakeModule],
  Mopcodes: FROM "mopcodes" USING [zPOP, zR0, zW0],
  SegmentDefs: FROM "segmentdefs",
  State: FROM "state" USING [Go, OnYourMark],
  StringDefs: FROM "stringdefs" USING [EquivalentString];

SymbolTester: PROGRAM
  IMPORTS DContext, CompilerUtil, DebugOps, DOutput, DSyms,
    Heap, ImageDefs, Init, IODefs, MiscDefs,
    State, StringDefs
  EXPORTS CompilerUtil, Commands, DebugOps =
  BEGIN

  DispatchChar: PUBLIC PROC [c: CHARACTER] = {DOutput.Char[c]};

  TableSegment: PUBLIC PROCEDURE [id: CompilerUtil.TableId]
      RETURNS [seg: SegmentDefs.FileSegmentHandle] =
    BEGIN OPEN CompilerUtil, Init;
    offset: CARDINAL;
    [seg, offset] ← MiscDefs.DestroyFakeModule[SELECT id FROM
	parse => LOOPHOLE[DIGrammar],
	debug => LOOPHOLE[DebugTab],
	ENDCASE => ERROR];
    IF offset # 0 THEN ERROR;
    RETURN[seg];
    END;

  Lengthen: PUBLIC PROC [p: POINTER] RETURNS [LONG POINTER] ={RETURN[p]};

  LongREAD: PUBLIC PROCEDURE [loc: LONG POINTER] RETURNS [val: UNSPECIFIED] =
    BEGIN OPEN Mopcodes;
    ReadMem: PROCEDURE [LONG POINTER] RETURNS [UNSPECIFIED] =
      MACHINE CODE BEGIN zPOP; zR0 END;
    val ← ReadMem[loc];
    END;

  LongCopyREAD: PUBLIC PROC [
      from: LONG POINTER, nwords: CARDINAL, to: LONG POINTER] =
    BEGIN
    i: CARDINAL;
    FOR i IN [0..nwords) DO
      (to+i)↑ ← LongREAD[from+i];
      ENDLOOP;
    END;

  LongWRITE: PUBLIC PROC [loc: LONG POINTER, val: UNSPECIFIED] =
    BEGIN OPEN Mopcodes;
    WriteMem: PROC [UNSPECIFIED, LONG POINTER] =
      MACHINE CODE BEGIN zPOP; zW0 END;
    WriteMem[val,loc];
    END;

  LongCopyWRITE: PUBLIC PROC [
      from: LONG POINTER, nwords: CARDINAL, to: LONG POINTER] =
    BEGIN
    i: CARDINAL;
    FOR i IN [0..nwords) DO
      LongWRITE[to+i, (from+i)↑];
      ENDLOOP;
    END;

  Done: PROCEDURE RETURNS [BOOLEAN] =
    BEGIN OPEN StringDefs;
    SELECT TRUE FROM 
      EquivalentString[s,"stop"L] => RETURN[TRUE];
      EquivalentString[s,"quit"L] => RETURN[TRUE];
      EquivalentString[s,"q"L] => RETURN[TRUE];
      ENDCASE => RETURN[FALSE]
    END;

  CallSomething: PROCEDURE [s: STRING] RETURNS [BOOLEAN] =
    BEGIN OPEN StringDefs, CompilerUtil;
    SELECT TRUE FROM
      EquivalentString[s,"trees"L] => printTree ← ~printTree;
      EquivalentString[s,"bodies"L] => PrintBodies[];
      EquivalentString[s,"symbols"L] => PrintSymbols[];
      ENDCASE => RETURN[FALSE];
    RETURN[TRUE];
    END;

  s: STRING ← [100];
  printTree: BOOLEAN ← TRUE;

  Error: PROC [type: {invalidNumber, notImpl, syntax, parse}] =
    BEGIN
    DOutput.Char[' ];
    DOutput.Text[SELECT type FROM
      syntax => "Syntax error!"L,
      invalidNumber =>  "invalid number!"L,
      notImpl =>  "not implemented!"L,
      parse =>  "Parse error!"L,
      ENDCASE => ERROR];
    DOutput.EOL[];
    END;

  Show: PROCEDURE [f: DebugOps.Foo] = {DebugOps.Display[f]};

  DoIt: PROCEDURE =
    BEGIN
    State.OnYourMark[];
    State.Go[];
    DSyms.Initialize[];
    DContext.SetRootConfig["Test"L];
    DContext.SetModule["Test"L];
    DO
      s.length ← 0;
      DOutput.Text["Interpret: "L];
      IODefs.ReadLine[s !ANY => CONTINUE];
      IF CallSomething[s] THEN LOOP;
      IF Done[] THEN ImageDefs.StopMesa[];
      DebugOps.Interpret[s, Show !
	DebugOps.InvalidNumber => {Error[invalidNumber]; CONTINUE};
	DebugOps.NotImplemented => 
	  BEGIN DOutput.Text[msg]; Error[notImpl]; CONTINUE END;
	DebugOps.SyntaxError => {Error[syntax]; CONTINUE};
	DebugOps.ParseError => {Error[parse]; CONTINUE}];
      Heap.FreeEverything[];
      ENDLOOP;
    END;

  DoIt[];

  END.