-- file SakuraReader.Mesa
-- last modified by Satterthwaite, January 12, 1981  4:55 PM
-- last edit by Russ Atkinson,  9-Jul-81 14:48:46
-- last edited by Suzuki: 30-Sep-81 11:33:04

DIRECTORY
  CBinary: TYPE USING [MesaTab, DebugTab],
  Convert: TYPE USING [MapValue],
  IOStream: TYPE USING [Handle, PutChar],
  PPCommentTable: TYPE USING [Reset],
  SakuraOps: TYPE USING [TableId],
  SakuraUtil: TYPE USING [PrettyPrint, PrintTree],
  PPComData: TYPE USING [Init],
  Runtime: TYPE USING [GetTableBase],
  PPP1: TYPE USING [Parse],
  ShowTime: TYPE USING [Microseconds, GetMark, Show],
  SakuraCommon: TYPE USING [tty],
  SakuraTree: TYPE USING [Link, Null],
  SakuraTreeOps: TYPE USING [Finalize, Initialize, PopTree],
  Rope: TYPE USING [Map, Ref],
  TTY: TYPE USING [Handle, PutChar, PutCR];

SakuraReader: PROGRAM
    IMPORTS
      Convert, IOStream, ShowTime, P1: PPP1, SakuraCommon, TreeOps: SakuraTreeOps, PPComData,
      CBinary, SakuraUtil, Runtime, CT: PPCommentTable, Rope, TTY
    EXPORTS SakuraOps, SakuraUtil = 
  BEGIN OPEN Tree: SakuraTree;

  -- Put routines
  
  PutDecimal: PUBLIC PROC [st: IOStream.Handle, x: LONG INTEGER] = {
    OPEN Convert, IOStream;
    PC1: PROC [c: CHARACTER] = {PutChar[st, c]};
    MapValue[PC1, [signed[x]]];
    };
    
  PutRope: PUBLIC PROC [st: IOStream.Handle, r: Rope.Ref] = {
    OPEN IOStream, Rope;
    PC2: PROC [c: CHARACTER] RETURNS [BOOLEAN] = {PutChar[st, c]; RETURN [FALSE]};
    [] ← Map[base: r, action: PC2]};
  
-- stream management

  Source: Rope.Ref ← NIL;
  GetSource: PUBLIC PROC RETURNS [Rope.Ref] = {RETURN[Source]};

  Log: IOStream.Handle ← NIL;
  GetLog: PUBLIC PROC RETURNS [IOStream.Handle] = {RETURN[Log]};
  SetLog: PUBLIC PROC [log: IOStream.Handle] = { Log ← log};

  Microseconds: TYPE = ShowTime.Microseconds;
    
  Report: PROC [from: Microseconds, msg: STRING ← NIL] = {
    OPEN TTY;
    Put1: PROC [c: CHARACTER] RETURNS [BOOLEAN] = {
      PutChar[tty, c]; RETURN [FALSE]};
    PutChar[tty, ' ];
    PutChar[tty, ' ];
    ShowTime.Show[from, Put1];
    PutChar[tty, ':];
    PutChar[tty, ' ];
    IF msg # NIL THEN FOR i: CARDINAL IN [0..msg.length) DO
      PutChar[tty, msg[i]]; ENDLOOP;
    PutCR[tty]};
    
  tty: TTY.Handle ← SakuraCommon.tty;

-- table segment management

  TableHandle: PUBLIC TYPE = LONG POINTER;
  tableSegment: ARRAY SakuraOps.TableId [parse..debug] OF TableHandle;

  AcquireTable: PUBLIC PROC [id: SakuraOps.TableId] RETURNS [TableHandle] = {
    RETURN [tableSegment[id]]};

  ReleaseTable: PUBLIC PROC [id: SakuraOps.TableId] = {
    };

-- compiler sequencing

  ParseStream:
      PUBLIC PROC
         [source: Rope.Ref ← NIL, log: IOStream.Handle ← NIL,
	  pretty, times: BOOLEAN ← TRUE, debug: BOOLEAN ← FALSE] 
      RETURNS [root: Tree.Link] = {
    start,mark: Microseconds ← ShowTime.GetMark[];
    Source ← source;
    Log ← log;
    TreeOps.Initialize[];
    CT.Reset[];
    mark ← ShowTime.GetMark[];
    {complete: BOOLEAN ← TRUE;
     nTokens,nErrors: CARDINAL ← 0;
     [complete, nTokens, nErrors] ← P1.Parse[];
     root ← IF complete THEN TreeOps.PopTree[] ELSE Tree.Null;
     IF times THEN
        Report[mark, IF nErrors = 0 THEN "parsing" ELSE "parsing (errors)"]};
    mark ← ShowTime.GetMark[];
    IF debug THEN SakuraUtil.PrintTree[root];
    IF pretty THEN
       {SakuraUtil.PrettyPrint[root];
        IF times THEN Report[mark, "output"];
        mark ← ShowTime.GetMark[];
        IF times THEN Report[start, "total time"]};
    TreeOps.Finalize[];
    Source ← NIL;
    Log ← NIL};


-- initialization code

  tableSegment[parse] ← Runtime.GetTableBase[LOOPHOLE[CBinary.MesaTab]];
  tableSegment[debug] ← Runtime.GetTableBase[LOOPHOLE[CBinary.DebugTab]];

  PPComData.Init[];

  END.