/// <summary> /// Executes a user defined function. /// </summary> /// <param name="parameter">new parameter value.</param> /// <param name="runEnvironment">Run evironment.</param> /// <param name="expressionEvaluator">Expression evaluator.</param> /// <param name="variableRepository">Variable repository.</param> /// <returns>Value of function.</returns> public Accumulator Execute( Accumulator parameter, IRunEnvironment runEnvironment, IExpressionEvaluator expressionEvaluator, IVariableRepository variableRepository) { // Save the variable and program line. var savedVariable = variableRepository.GetOrCreateVariable(VariableName, new short[] { }).GetValue(); var savedProgramLine = runEnvironment.CurrentLine; // Change the variable to be our parameter. variableRepository.GetOrCreateVariable(VariableName, new short[] { }).SetValue(parameter); runEnvironment.CurrentLine = Line; runEnvironment.CurrentLine.CurrentToken = LineToken; // Evaluate the expression. var returnValue = expressionEvaluator.GetExpression(); // Restore the variable and program line. variableRepository.GetOrCreateVariable(VariableName, new short[] { }).SetValue(savedVariable); runEnvironment.CurrentLine = savedProgramLine; // return the value. return(returnValue); }
public void GetWorksWithStringVariable() { SetupSut(); _mockTeletypeWithPosition.Setup(mtwp => mtwp.ReadChar()).Returns('1'); var variableReference = _variableRepository.GetOrCreateVariable("A$", new short[] { }); _mockExpressionEvaluator.Setup(mee => mee.GetLeftValue()).Returns(variableReference); _sut.Execute(); Assert.AreEqual("1", variableReference.GetValue().ValueAsString()); }
public void ReadTest() { SetupSut(); var variableA = _variableRepository.GetOrCreateVariable("A", new short[] { }); _runEnvironment.CurrentLine = new ProgramLine(10, new List <IToken>()); _mockExpressionEvaluator.SetupSequence(mee => mee.GetLeftValue()) .Returns(variableA); _sut.Execute(); _mockReadInputParser.Verify(mrip => mrip.ReadVariables(new List <VariableReference> { variableA }), Times.Once); }
private void SetupSut() { _runEnvironment = new RunEnvironment(); _mockExpressionEvaluator = new Mock <IExpressionEvaluator>(); _variableRepository = new VariableRepository(); _variableReference = _variableRepository.GetOrCreateVariable("A", new short[] { }); _mockExpressionEvaluator.Setup(mre => mre.GetLeftValue()).Returns(_variableReference); _mockExpressionEvaluator.Setup(mre => mre.GetExpression()).Returns(new Accumulator(3.0)); _sut = new Let(_runEnvironment, _mockExpressionEvaluator.Object); }
/// <summary> /// Execute the NEXT command. /// </summary> public void Execute() { StackEntry currentLoop = null; while (true) { currentLoop = FindForEntry(currentLoop); var loopVar = _variableRepository.GetOrCreateVariable(currentLoop.VariableName, new short[] { }); loopVar.SetValue(new Accumulator(loopVar.GetValue().ValueAsDouble() + currentLoop.Step)); bool finished; if (currentLoop.Step > 0.0) { finished = loopVar.GetValue().ValueAsDouble() > currentLoop.Target; } else { finished = loopVar.GetValue().ValueAsDouble() < currentLoop.Target; } if (!finished) { _runEnvironment.CurrentLine = currentLoop.Line; _runEnvironment.CurrentLine.CurrentToken = currentLoop.LineToken; return; } _runEnvironment.ProgramStack.Pop(); var token = _runEnvironment.CurrentLine.NextToken(); if (token.Seperator != TokenType.Comma) { _runEnvironment.CurrentLine.PushToken(token); return; } token = _runEnvironment.CurrentLine.NextToken(); if (token.TokenClass == TokenClass.Variable) { _runEnvironment.CurrentLine.PushToken(token); } else { throw new Exceptions.SyntaxErrorException(); } } }
private void SetupSut() { _inputQueue = new Queue <string>(); _sut = new ReadInputParser(() => _inputQueue.Dequeue()); _sut.Clear(); _variableRepository = new VariableRepository(); _numericVariables[0] = _variableRepository.GetOrCreateVariable("A", new short[] { }); _numericVariables[1] = _variableRepository.GetOrCreateVariable("B", new short[] { }); _numericVariables[2] = _variableRepository.GetOrCreateVariable("C", new short[] { }); _stringVariables[0] = _variableRepository.GetOrCreateVariable("A$", new short[] { }); _stringVariables[1] = _variableRepository.GetOrCreateVariable("B$", new short[] { }); _stringVariables[2] = _variableRepository.GetOrCreateVariable("C$", new short[] { }); }
private void SetupSut() { _mockProgramRepository = new Mock <IProgramRepository>(); _runEnvironment = new RunEnvironment(); _sut = new DataStatementReader(_runEnvironment, _mockProgramRepository.Object); _variableRepository = new VariableRepository(); _numericVariables[0] = _variableRepository.GetOrCreateVariable("A", new short[] { }); _numericVariables[1] = _variableRepository.GetOrCreateVariable("B", new short[] { }); _numericVariables[2] = _variableRepository.GetOrCreateVariable("C", new short[] { }); _stringVariables[0] = _variableRepository.GetOrCreateVariable("A$", new short[] { }); _stringVariables[1] = _variableRepository.GetOrCreateVariable("B$", new short[] { }); _stringVariables[2] = _variableRepository.GetOrCreateVariable("C$", new short[] { }); }
/// <summary> /// Executes the FOR command. /// </summary> public void Execute() { var stackEntry = new StackEntry(); // We need the name and the classic MS interpreter only supports // non-array double variables, so we'll do the same. var token = _runEnvironment.CurrentLine.NextToken(); if (token.TokenClass != TokenClass.Variable) { throw new Exceptions.SyntaxErrorException(); } stackEntry.VariableName = token.Text; var variableRef = _variableRepository.GetOrCreateVariable(token.Text, new short[] { }); token = _runEnvironment.CurrentLine.NextToken(); if (token.Seperator != TokenType.Equal) { throw new Exceptions.SyntaxErrorException(); } Accumulator startValue = _expressionEvaluator.GetExpression(); variableRef.SetValue(startValue); token = _runEnvironment.CurrentLine.NextToken(); if (token.Statement != TokenType.To) { throw new Exceptions.SyntaxErrorException(); } stackEntry.Target = _expressionEvaluator.GetExpression().ValueAsDouble(); token = _runEnvironment.CurrentLine.NextToken(); if (token.Statement != TokenType.Step) { _runEnvironment.CurrentLine.PushToken(token); stackEntry.Step = 1.0; } else { stackEntry.Step = _expressionEvaluator.GetExpression().ValueAsDouble(); } stackEntry.Line = _runEnvironment.CurrentLine; stackEntry.LineToken = _runEnvironment.CurrentLine.CurrentToken; bool doDelete = false; foreach (var entry in _runEnvironment.ProgramStack) { // Gosub / Return stop searching if (entry.VariableName == null) { break; } // Name matches we should overwrite. if (entry.VariableName == stackEntry.VariableName) { doDelete = true; break; } } if (doDelete) { // Pop entries off the stack until we find us. while (_runEnvironment.ProgramStack.Pop().VariableName != stackEntry.VariableName) { } } _runEnvironment.ProgramStack.Push(stackEntry); _runEnvironment.TestForStackOverflow(); }
public void ForNextTest() { SetupSut(); var forCmd = new For(_runEnvironment, _mockExpressionEvaluator.Object, _variableRepository); var nextCmd = new Next(_runEnvironment, _variableRepository); _mockExpressionEvaluator.SetupSequence(mee => mee.GetExpression()) .Returns(new Accumulator(1.0)) .Returns(new Accumulator(3.0)); var line10 = new ProgramLine(10, new List <IToken> { new Token("A"), _equalToken, _toToken, _colonToken }); var line20 = new ProgramLine(20, new List <IToken> { new Token("A"), new Token("1") }); _runEnvironment.CurrentLine = line10; forCmd.Execute(); Assert.AreEqual(1.0, _variableRepository.GetOrCreateVariable("A", new short[] { }).GetValue().ValueAsDouble()); Assert.AreEqual(1, _runEnvironment.ProgramStack.Count); var loopBackToken = _runEnvironment.CurrentLine.CurrentToken; // Execute next, line20.CurrentToken = 0; _runEnvironment.CurrentLine = line20; nextCmd.Execute(); // variable should be 2 Assert.AreEqual(2.0, _variableRepository.GetOrCreateVariable("A", new short[] { }).GetValue().ValueAsDouble()); // Should be back to just after for loop. Assert.AreEqual(10, _runEnvironment.CurrentLine.LineNumber.Value); Assert.AreEqual(loopBackToken, _runEnvironment.CurrentLine.CurrentToken); // Execute next, variable should be 3 line20.CurrentToken = 0; _runEnvironment.CurrentLine = line20; nextCmd.Execute(); Assert.AreEqual(3.0, _variableRepository.GetOrCreateVariable("A", new short[] { }).GetValue().ValueAsDouble()); Assert.AreEqual(10, _runEnvironment.CurrentLine.LineNumber.Value); Assert.AreEqual(loopBackToken, _runEnvironment.CurrentLine.CurrentToken); // Execute next line20.CurrentToken = 0; _runEnvironment.CurrentLine = line20; nextCmd.Execute(); // So we have exited the loop Assert.AreEqual(20, _runEnvironment.CurrentLine.LineNumber.Value); // Did we leave behind the token. var token = _runEnvironment.CurrentLine.NextToken(); Assert.AreEqual("1", token.Text); // Variable should be 4.0 Assert.AreEqual(4.0, _variableRepository.GetOrCreateVariable("A", new short[] { }).GetValue().ValueAsDouble()); Assert.AreEqual(0, _runEnvironment.ProgramStack.Count); }
/// <summary> /// Gets a variable reference which can be used a LValue for assignments. /// </summary> /// <returns>Reference to a variable.</returns> public VariableReference GetLeftValue() { string name = GetVariableName(); return(_variableRepository.GetOrCreateVariable(name, GetIndexes())); }
public void InputParsesNumbersAndStrings() { SetupSut(); var tokens = new List <IToken> { new Token("A"), _comma, new Token("B"), _dollar, _comma, new Token("C"), _dollar }; _runEnvironment.CurrentLine = new ProgramLine(10, tokens); _teletype.Input.Enqueue("23,\"456,abc\",456 abc"); _sut.Execute(); Assert.AreEqual("?", _teletype.Output.Dequeue()); Assert.AreEqual(23.0, _variableRepository.GetOrCreateVariable("A", new short[] { }).GetValue().ValueAsDouble()); Assert.AreEqual("456,abc", _variableRepository.GetOrCreateVariable("B$", new short[] { }).GetValue().ValueAsString()); Assert.AreEqual("456 abc", _variableRepository.GetOrCreateVariable("C$", new short[] { }).GetValue().ValueAsString()); }
public void EvaluatorGetsDoubleVariable() { _variableRepository.GetOrCreateVariable("B", new short[] { }).SetValue(new Accumulator(5.5)); _runEnvironment.CurrentLine = _tokeniser.Tokenise("10 PRINT B"); _runEnvironment.CurrentLine.NextToken(); // Eat the print var result = _expressionEvaluator.GetExpression(); Assert.AreEqual(5.5, result.ValueAsDouble()); }