/// <summary> /// Executes the LOAD comand. /// </summary> /// <param name="tokeniser">Tokeniser to use.</param> public void Execute(ITokeniser tokeniser) { var fileName = _expressionEvaluator.GetExpression().ValueAsString(); int lastProgramLine = 0; try { var program = _fileSystem.File.ReadAllLines(fileName, System.Text.Encoding.UTF8); _programRepository.Clear(); foreach (var line in program) { var programLine = tokeniser.Tokenise(line); if (!programLine.LineNumber.HasValue) { throw new Exception("MISSING LINE NUMBER"); } lastProgramLine = programLine.LineNumber.Value; _programRepository.SetProgramLine(programLine); } } catch (Exception ex) { throw new Exceptions.BasicException($"BAD LOAD {ex.Message}, LAST GOOD LINE WAS {lastProgramLine}", 100); } }
/// <summary> /// Executes the RUN command. /// </summary> /// <param name="tokeniser">Tokeniser used by the load command.</param> public void Execute(ITokeniser tokeniser) { var nextToken = _runEnvironment.CurrentLine.NextToken(); if (nextToken.TokenClass == TokenClass.String) { // Since we have a tokeniser, we can just fake being the executor/interpreter // and create our own LOAD command and call it. var oldLine = _runEnvironment.CurrentLine; _runEnvironment.CurrentLine = tokeniser.Tokenise($"LOAD {nextToken}"); var loadToken = _runEnvironment.CurrentLine.NextToken() as ITokeniserCommand; loadToken.Execute(tokeniser); _runEnvironment.CurrentLine = oldLine; } else { _runEnvironment.CurrentLine.PushToken(nextToken); } _variableRepository.Clear(); _runEnvironment.Clear(); _dataStatementReader.RestoreToLineNumber(null); int?startingLineNumber = _runEnvironment.CurrentLine.GetLineNumber(); _runEnvironment.CurrentLine = startingLineNumber.HasValue ? _programRepository.GetLine(startingLineNumber.Value) : _programRepository.GetFirstLine(); }
/// <summary> /// Executes the interpreter. /// </summary> public void Execute() { bool quit = false; while (!quit) { _teletypeWithPosition.NewLine(); _teletypeWithPosition.Write(">"); var command = _teletypeWithPosition.Read(); if (command == null) { _runEnvironment.KeyboardBreak = false; continue; } try { var parsedLine = _tokeniser.Tokenise(command); if (parsedLine.LineNumber.HasValue) { _programRepository.SetProgramLine(parsedLine); } else { _runEnvironment.CurrentLine = parsedLine; quit = _executor.ExecuteLine(); } } catch (Exceptions.BreakException endError) { if (endError.ErrorMessage != string.Empty) { WriteErrorToTeletype( _runEnvironment.CurrentLine.LineNumber, endError.ErrorMessage); } } catch (Exceptions.BasicException basicError) { WriteErrorToTeletype( _runEnvironment.DataErrorLine ?? _runEnvironment.CurrentLine?.LineNumber, "?" + basicError.ErrorMessage + " ERROR"); } } }
public void ProcessKeyboard(IScreenObject host, Keyboard keyboard, out bool handled) { handled = false; // Program is running -- Use special input handlers. if (BASICExecutor.IsExecuting) { // Break program if (keyboard.IsKeyDown(Keys.C) && (keyboard.IsKeyDown(Keys.LeftControl) || keyboard.IsKeyDown(Keys.RightControl))) { BASICExecutor.Break(); } handled = true; return; } // No program is running, in editor mode. if (keyboard.IsKeyPressed(Keys.Enter)) { var command = Read(); if (command != null) { RunProgramTask = new Task(() => { try { var parsedLine = BASICTokeniser.Tokenise(command.Trim()); if (parsedLine.LineNumber.HasValue) { BASICProgramRepository.SetProgramLine(parsedLine); NewLine(); } else { BASICRunEnvironment.CurrentLine = parsedLine; NewLine(); bool quit = BASICExecutor.ExecuteLine(); if (!BASICExecutor.IsExecuting) { WritePrompt(); } } } catch (BreakException endError) { if (endError.ErrorMessage != string.Empty) { WriteErrorToTeletype( BASICRunEnvironment.CurrentLine.LineNumber, endError.ErrorMessage); } } catch (BasicException basicError) { WriteErrorToTeletype( BASICRunEnvironment.DataErrorLine ?? BASICRunEnvironment.CurrentLine?.LineNumber, "?" + basicError.ErrorMessage + " ERROR"); } }); RunProgramTask.Start(); } handled = true; } }
public void ValidCode() { var result = _tokeniser.Tokenise("20IFI<>10THENPRINT\"HELLO\""); Assert.AreEqual(20, result.LineNumber.Value); TokenCheck(result.NextToken(), "IF", TokenClass.Statement); TokenCheck(result.NextToken(), "I", TokenClass.Variable); TokenCheck(result.NextToken(), "<", TokenClass.Seperator); TokenCheck(result.NextToken(), ">", TokenClass.Seperator); TokenCheck(result.NextToken(), "10", TokenClass.Number); TokenCheck(result.NextToken(), "THEN", TokenClass.Statement); TokenCheck(result.NextToken(), "PRINT", TokenClass.Statement); TokenCheck(result.NextToken(), "HELLO", TokenClass.String); Assert.IsTrue(result.EndOfLine); }
public void EvaluatorDoesNotOverParse() { _runEnvironment.CurrentLine = _tokeniser.Tokenise("10 \"Hello\":A=A+1"); var value = _expressionEvaluator.GetExpression(); Assert.AreEqual("Hello", value.ValueAsString()); Assert.AreEqual(TokenType.Colon, _runEnvironment.CurrentLine.NextToken().Seperator); }
public void TokeniserRecognisesCommonVariable() { var results = _sut.Tokenise(2, "my house"); _errorHandler.Verify(eh => eh.ReportError(It.IsAny <int>(), It.IsAny <ErrorCode>()), Times.Never); Assert.AreEqual(1, results.Count); Assert.AreEqual(TokenClass.CommonVariable, results.First().Class); Assert.AreEqual("my house", results.First().Text); }