-- SMControlImpl.mesa
-- last edit by Schmidt, July 2, 1982 11:35 am
-- last edit by Satterthwaite, May 27, 1983 10:54 am

DIRECTORY
  IO: TYPE USING [GetChar, GetSequence, Handle, Put, string],
  Process: TYPE USING [Detach],
  Rope: TYPE USING [Cat, Length, ROPE],
  SMEval: TYPE USING [Eval],
  SMOps: TYPE USING [MS, NewModel],
  SMUtil: TYPE USING [ParseStream, PrettyPrint, PrintTree],
  SMTree: TYPE Tree USING [Link, null],
  SMTreeOps: TYPE --TreeOps-- USING [Initialize, Finalize],
  TypeScript: TYPE USING [Create, TS--, UserAbort--],
  ViewerIO: TYPE USING [CreateViewerStreams];

SMControlImpl: CEDAR PROGRAM 
    IMPORTS IO, Process, Rope, SMEval, SMOps, SMUtil, SMTreeOps, TypeScript, ViewerIO ~ {
  OPEN Tree~~SMTree, TreeOps~~SMTreeOps;
  
 -- mds usage
  model: SMOps.MS;
 -- end of mds

  debugLevel: NAT ← NAT.LAST;
    -- <= 1: parse trees
    -- <= 2: id lookup
    -- no debugging is default
  
  Main: PROC ~ {
    ENABLE ABORTED => {GOTO out};
    cycle: BOOL ← TRUE;
    line, val: Rope.ROPE;
    in, out: IO.Handle;
    ts: TypeScript.TS ~ TypeScript.Create[info~[name~"SMInterpreter.Log", iconic~FALSE]];
    [in, out] ← ViewerIO.CreateViewerStreams[viewer~ts, name~NIL];
    model ← SMOps.NewModel[in, out, out];
    (model.tm).Initialize;
    WHILE cycle DO
--    IF TypeScript.UserAbort[model.typeScript] THEN EXIT;
      model.out.Put[IO.string["\n\n\n? "L]];
      val ← NIL;
      DO
--	IF TypeScript.UserAbort[model.typeScript] THEN EXIT;
	line ← (model.in).GetSequence;
	[] ← (model.in).GetChar;	-- discard '\n
	IF line.Length = 0 THEN EXIT;
	val ← Rope.Cat[val, "\n", line];
	ENDLOOP;
      model.topTree ← SMUtil.ParseStream[m~model, source~val,  
			pretty~FALSE, times~FALSE, debug~FALSE];
      IF model.topTree # Tree.null THEN {
        IF debugLevel <= 1 THEN SMUtil.PrintTree[model, model.topTree];
        SMUtil.PrettyPrint[model, model.topTree]};
      IF model.topTree # Tree.null THEN {
        val: Tree.Link ← SMEval.Eval[model, model.topTree, NIL];
        model.out.Put[IO.string["\n\n"L]];
        IF debugLevel <= 2 THEN SMUtil.PrintTree[model, val];
        SMUtil.PrettyPrint[model, val]};
      ENDLOOP;
    (model.tm).Finalize;
    EXITS
      out => NULL;
    };
	

  Init: PROC ~ TRUSTED {Process.Detach[FORK Main[]]};

  Init[];
  }.