-- BasicControl.mesa
-- edited by Brotz and Hilton, September 22, 1982  4:24 PM
-- edited by Taft, May 6, 1983  4:25 PM
DIRECTORY
  BasicImpDefs,
  BasicOps,
  ImageDefs,
  IODefs,
  LaurelExecDefs,
  Real,
  SegmentDefs USING [memConfig],
  TimeDefs,
  vmD: FROM "VirtualMgrDefs";
BasicControl:  PROGRAM
  IMPORTS  BasicImpDefs, ImageDefs, IODefs, LaurelExecDefs, Real, SegmentDefs,
    TimeDefs, vmD
  EXPORTS BasicImpDefs =
BEGIN
OPEN BasicImpDefs;
isProgramLine: PUBLIC BOOLEAN;
WriteHerald: PROCEDURE =
BEGIN
time: STRING ← [25];
TimeDefs.AppendDayTime[time, TimeDefs.UnpackDT[ImageDefs.BcdVersion[].time]];
IODefs.WriteLine[""L];
IODefs.WriteString["Laurel Basic of "L];
IODefs.WriteLine[time];
IODefs.WriteLine["(CTRL DEL interrupts execution. Type HELP for information.)"L];
IODefs.WriteLine[""];
END;  -- of WriteHerald --
CheckConfig: PROCEDURE RETURNS [ok: BOOLEAN ← FALSE] =
BEGIN OPEN SegmentDefs, IODefs;
sorry: STRING = "Sorry, your machine is incapable of running Basic, because "L;
IF ~memConfig.useXM THEN
  {WriteString[sorry]; WriteLine["there isn’t enough memory."L]; RETURN}; 
IF memConfig.AltoType IN [AltoI..AltoIIXM] AND memConfig.mesaMicrocodeVersion < 41 THEN
  {WriteString[sorry]; WriteLine["the wrong microcode is installed."L]; RETURN}; 
ok ← TRUE;
END;  -- CheckConfig --
-- M A I N   E X E C U T I O N
IF ~CheckConfig[] THEN STOP;
START BasicScanner;
START BasicProgram;
START BasicVariable;
START BasicCommand;
START BasicInterpA;
START BasicInterpB;
START BasicParser;
LaurelExecDefs.MakeMenuCommandCallable[newMail];
LaurelExecDefs.MakeMenuCommandCallable[user];
LaurelExecDefs.MakeMenuCommandCallable[mailFile];
LaurelExecDefs.MakeMenuCommandCallable[display];
LaurelExecDefs.MakeMenuCommandCallable[delete];
LaurelExecDefs.MakeMenuCommandCallable[undelete];
LaurelExecDefs.MakeMenuCommandCallable[moveTo];
LaurelExecDefs.MakeMenuCommandCallable[copy];
WriteHerald[];
Real.InitReals[];
InitCharTable[];
InitBuiltInFunctionRegistry[]; 
DO
  savedIndex,
  programLineNumber: CARDINAL;
  IF autoOn THEN OutputAutoLineNumber[];
  IODefs.ReadLine[inputLine ! IODefs.Rubout => {IODefs.WriteLine[" XXX"L]; LOOP}];
  inputLineIndex ← 0;
  IF GetToken[] THEN
    BEGIN
    savedIndex ← inputLineIndex;
    [isProgramLine, programLineNumber] ← TokenIsLineNumber[];
    vmD.InitComposedMessage[lineCodeCm, ""L];
    IF isProgramLine THEN [] ← GetToken[] ELSE savedIndex ← 0;
    ParseStatement[savedIndex ! ParseErrorSignal => LOOP];
    AppendByte[lineCodeCm, BasicOps.Done];
    IF isProgramLine THEN
      BEGIN
      AllocateAndInsert[programLineNumber, savedIndex];
      autoStart ← programLineNumber;
      END
    ELSE BEGIN
      autoOn ← FALSE;
      InterpretCode[lineCodeCm, 0
        ! QuitSignal => EXIT;
          RunTimeErrorSignal, ParseErrorSignal => LOOP];
      END;
    END;
  ENDLOOP;
VariableCleanUp[];
CommandCleanUp[];
ProgramCleanUp[];
END.  -- of BasicControl --