public void Run() { ConsoleWriter.WriteLine("New interpreter run " + programContext); Tree <Token> instruction = programContext.GetNextInstruction(); while (instruction != null) { TokenType tokenType = instruction.Root.Value.TokenType; switch (tokenType) { case TokenType.Variable: programContext.Memory.Declare(instruction.Root.Value.Lexeme); break; case TokenType.Delimiter: case TokenType.ProgramSplitter: break; case TokenType.Unknown: // Done at runtime rather than in Lexer to allow for ALS if (programContext.Operators.IsOperator(instruction.Root.Value.Lexeme)) { instruction.Root.Value.TokenType = TokenType.Operator; } RunCommand(instruction, programContext); break; case TokenType.Operator: RunCommand(instruction, programContext); break; case TokenType.Value: default: throw new RuntimeException("Invalid root token: " + instruction.Root.Value + ". At instruction - " + instruction.ToString() + ". Context - " + programContext.ToString()); } instruction = programContext.GetNextInstruction(); } }
public ProgramContext RunCommand(Tree <Token> instruction, ProgramContext context) { ConsoleWriter.WriteLine(Environment.NewLine + "Instruction: " + instruction); ConsoleWriter.WriteLine(context.ToString()); Ops op = context.Operators.ToOp(instruction.Root.Value.Lexeme); ConsoleWriter.WriteLine("Run: " + instruction); switch (op) { case Ops.ADD: Add(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.SUB: Sub(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.MUL: Mul(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.DIV: Div(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.MOD: Mod(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.PUT: Put(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.GET: Get(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.SWI: Swi(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.BRK: Brk(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.ALS: AddAlias(context, instruction); break; case Ops.OUT: Out(context, instruction); break; case Ops.LOD: Lod(context, instruction); break; case Ops.SIN: Sin(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme); break; case Ops.COS: Cos(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme); break; case Ops.TAN: Tan(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme); break; case Ops.POW: Pow(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme, instruction.Root.Children[2].Value.Lexeme); break; case Ops.REA: Rea(context, instruction.Root.Children[0].Value.Lexeme); break; case Ops.CLR: Clr(context, instruction.Root.Children[0].Value.Lexeme); break; case Ops.LEN: Len(context, instruction.Root.Children[0].Value.Lexeme, instruction.Root.Children[1].Value.Lexeme); break; case Ops.NUL: break; default: throw new NotImplementedException("Op " + op + " has not been implemented in the interpreter"); } return(context); }
private void Lod(ProgramContext context, Tree <Token> instruction) { string fileName = instruction.Root.Children[0].Value.Lexeme; string stdPrefix = "std::"; if (fileName.Contains(stdPrefix)) { string execuatbleLocation = new Uri(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)).LocalPath; fileName = execuatbleLocation + @"\std\" + fileName.Split(stdPrefix, StringSplitOptions.RemoveEmptyEntries)[0]; } Interpreter moduleInterpreter; try { moduleInterpreter = new Interpreter(fileName); Node <Token> passedValToken = instruction.Root.Children[1]; if (passedValToken.Value.TokenType == TokenType.PassableArray) { string varName = passedValToken.Value.Lexeme.Split(Lexer.passableArrayModifier)[1]; // In this case, pass the entire array into the first variable of the loaded module moduleInterpreter.ProgramContext.Memory.SetPassedValue(context.Memory.ResolveToValue(varName)); } else { // In this case, each element of the value into each declared variable in turn moduleInterpreter.ProgramContext.Memory.SetPassedValues(context.Memory.ResolveToValue(passedValToken.Value.Lexeme)); } } catch (Exception ex) { throw new ModuleLoadException("Could not resolve module " + fileName + ". With context - " + context.ToString(), ex); } try { moduleInterpreter.Run(); context.Memory.SetVarValue(instruction.Root.Children[2].Value.Lexeme, moduleInterpreter.ProgramContext.Memory.GetFullValue("return")); } catch (Exception ex) { throw new RuntimeException("Module " + fileName + " caused exception with context - " + moduleInterpreter.ProgramContext.ToString(), ex); } }