public void Execute(Context context, params string[] args) { using (var input = new MemoryStream()) using (var output = new MemoryStream()) { if (args.Any()) { var writer = new StreamWriter(input); writer.Write(args.First()); writer.Flush(); input.Position = 0; } var prn = PrnComposer.GetPrn(context.TokenSequence, context.Labels, context.Variables); foreach (var identifier in prn.OfType <IdentifierToken>()) { context.Variables[identifier] = new ConstantToken <float>(0); } var prnExecutor = new PrnExpressionExecutor(input, output, Logger); prnExecutor.Output += s => Output?.Invoke(s); prnExecutor.ComputationStep += (s, i, stack) => ComputationStep?.Invoke(s, i, stack); prnExecutor.ComputeExpression(prn, context.Variables); } }
public float?ComputeExpression(IList <Token> prn, VariableStore identifierValues) { var stack = new Stack <Token>(); var context = new ExecutorContext(stack, identifierValues, prn) { InputStream = InputStream, OutputStream = OutputStream, Logger = Logger }; for (var index = 0; index < prn.Count; index++) { ComputationStep?.Invoke(prn, index, stack); var token = prn[index]; var operation = token as IOperation; if (operation != null) { var nextIndex = index + 1; operation.Execute(context); if (context.NextPosition != null) { nextIndex = context.NextPosition.Value; context.NextPosition = null; } if (context.WrittenString != null) { Output?.Invoke(context.WrittenString); context.WrittenString = null; } index = nextIndex - 1; continue; } if (token.Substring == ":") { continue; } ProcessIndentifiersConstants(token, stack); ProcessUnarySubtraction(identifierValues, token, stack); ProcessBoolean(identifierValues, token, stack); ProcessArithmeticOperations(identifierValues, token, stack); ProcessLogics(identifierValues, token, stack); ProcessAssignment(identifierValues, token, stack); } if (stack.Any()) { var popped = stack.Pop(); if (popped is ConstantToken <float> || popped is IdentifierToken) { return((popped as ConstantToken <float>)?.Value ?? identifierValues[popped as IdentifierToken].Value); } } return(null); }