public void AddInstruction(T1Instruction instruction) { Instructions.Add(instruction); }
private void RunInstruction(T1Instruction instruction) { switch (instruction.Type) { // Variable table should contain scope pointer as well as variable id case T1InstructionType.Assignment: EvaluateExpression(((T1InstructionAssignment)instruction).Expression); if (((T1InstructionAssignment)instruction).Variable.VariableType != ExpressionType) { throw new Exception("Runtime error: Variable type mismatch in expression"); } ((T1InstructionAssignment)instruction).Variable.Scope.VariableTable[((T1InstructionAssignment)instruction).Variable.VariableId] = new T1Variable(((T1InstructionAssignment)instruction).Variable.VariableType, ExpressionResult); break; case T1InstructionType.ConditionalJump: EvaluateExpression(((T1InstructionConditionalJump)instruction).Expression); if ((int)ExpressionResult != 0) { instructionPointer = LabelTable[((T1InstructionConditionalJump)instruction).LabelId] + 1; } break; case T1InstructionType.ExpressionEvaluation: EvaluateExpression(((T1InstructionEvaluateExpression)instruction).Expression); break; case T1InstructionType.FunctionCall: T1Scope newScope = (T1Scope)SubScopes[((T1InstructionFunctionCall)instruction).FunctionId]; // .Clone(); newScope.ParentScope = this; // Variable assignments for arguments for (int i = 0; i < ((T1InstructionFunctionCall)instruction).Arguments.Count; i++) { newScope.VariableTable[i + 1] = new T1Variable(((T1InstructionFunctionCall)instruction).Arguments[i].VariableType, ((T1InstructionFunctionCall)instruction).Arguments[i].Operand); } newScope.Run(); break; case T1InstructionType.FunctionDeclaration: T1Scope subScope = ((T1InstructionFunctionDeclaration)instruction).FunctionScope; // Return value T1Variable returnValue = null; switch (((T1InstructionFunctionDeclaration)instruction).ReturnType) { case T1VariableType.Void: returnValue = new T1Variable(T1VariableType.Void); break; case T1VariableType.Byte: returnValue = new T1Variable(T1VariableType.Byte); break; case T1VariableType.Double: returnValue = new T1Variable(T1VariableType.Double); break; case T1VariableType.Int: returnValue = new T1Variable(T1VariableType.Int); break; case T1VariableType.String: returnValue = new T1Variable(T1VariableType.String); break; } subScope.VariableTable.Add(returnValue); // Arguments for (int i = 0; i < ((T1InstructionFunctionDeclaration)instruction).Arguments.Count; i++) { T1Variable newArgument = null; switch (((T1InstructionFunctionDeclaration)instruction).Arguments[i].VariableType) { case T1VariableType.Void: newArgument = new T1Variable(T1VariableType.Void); break; case T1VariableType.Byte: newArgument = new T1Variable(T1VariableType.Byte); break; case T1VariableType.Double: newArgument = new T1Variable(T1VariableType.Double); break; case T1VariableType.Int: newArgument = new T1Variable(T1VariableType.Int); break; case T1VariableType.String: newArgument = new T1Variable(T1VariableType.String); break; } subScope.VariableTable.Add(newArgument); } SubScopes.Add(subScope); break; case T1InstructionType.Import: break; case T1InstructionType.Jump: instructionPointer = LabelTable[((T1InstructionJump)instruction).LabelId] + 1; break; case T1InstructionType.LabelSet: LabelTable.Add(instructionPointer); break; case T1InstructionType.VariableDeclaration: T1Variable newVariable = null; switch (((T1InstructionVariableDeclaration)instruction).VariableType) { case T1VariableType.Void: newVariable = new T1Variable(T1VariableType.Void, VariableTable.Count); break; case T1VariableType.Byte: newVariable = new T1Variable(T1VariableType.Byte, VariableTable.Count); break; case T1VariableType.Double: newVariable = new T1Variable(T1VariableType.Double, VariableTable.Count); break; case T1VariableType.Int: newVariable = new T1Variable(T1VariableType.Int, VariableTable.Count); break; case T1VariableType.String: newVariable = new T1Variable(T1VariableType.String, VariableTable.Count); break; } VariableTable.Add(newVariable); break; case T1InstructionType.Return: instructionPointer = Instructions.Count; break; } }
private void CompileScript() { List <string> primitiveTypes = new List <string>() { "void", "int", "string", "byte", "double" }; List <string> statements = new List <string>() { "for", "if", "while", "return" }; VariableTableItems = new List <T1TableItem>(); FunctionTableItems = new List <T1TableItem>(); T1Instruction CurrentInstruction = null; T1Scope CurrentScope = new T1Scope(); CurrentLine = 1; CurrentToken = 0; string token; while (CurrentToken < Tokens.Count) { token = GetNextToken(); if (primitiveTypes.Contains(token)) { string typeName = token; // function or variable declaration string identifierName = GetNextToken(); // test whether identifier stands in any of the tables if (TableContains(VariableTableItems, identifierName) || TableContains(FunctionTableItems, identifierName)) { throw new Exception("Identifier redeclared: " + identifierName + " [" + CurrentLine + "]"); } token = GetNextToken(); T1VariableType variableType = GetVariableTypeFromToken(token); if (token == "(") { // this seems to be a function declaration FunctionTableItems.Add(new T1TableItem(identifierName, FunctionTableItems.Count - 1, CurrentScope)); token = GetNextToken(); List <T1InstructionVariableDeclaration> arguments = new List <T1InstructionVariableDeclaration>(); while (token != ")") { if (primitiveTypes.Contains(token)) { typeName = token; identifierName = GetNextToken(); arguments.Add(new T1InstructionVariableDeclaration(GetVariableTypeFromToken(typeName))); if (TableContains(VariableTableItems, identifierName)) { throw new Exception("Argumant redeclared: " + identifierName + " [" + CurrentLine + "]"); } token = GetNextToken(); if (token == ",") { token = GetNextToken(); } } token = GetNextToken(); } token = GetNextToken(); if (token != "{") { throw new Exception("{ expected [" + CurrentLine + "]"); } T1Scope functionScope = new T1Scope(); AddInstruction(new T1InstructionFunctionDeclaration(arguments, T1VariableType.Int, 0, functionScope)); token = GetNextToken(); while (token != "}") { // is it a function call? if (TableContains(FunctionTableItems, token)) { } // is it an assignment? else if (TableContains(VariableTableItems, token)) { } // is it a variable declaration? else if (primitiveTypes.Contains(token)) { } // is it a statement? else if (statements.Contains(token)) { if (token == "if") { } else if (token == "for") { token = GetNextToken(); if (token != "(") { throw new Exception("\"(\" expected but " + token + " found"); } } else if (token == "while") { token = GetNextToken(); if (token != "(") { throw new Exception("\"(\" expected but " + token + " found"); } } else if (token == "return") { } else { throw new Exception("Undexpected statement or keyword: " + token + " [" + CurrentLine + "]"); } } else { throw new Exception("Unexpected statement starter: " + token + " [" + CurrentLine + "]"); } token = GetNextToken(); } } else if (token == "=" || token == ";") { // this seems to be a variable declaration if (token == "=") { CompileExpression(); } else { VariableTableItems.Add(new T1TableItem(identifierName, VariableTableItems.Count - 1, CurrentScope)); CurrentInstruction = new T1InstructionVariableDeclaration(variableType); CurrentScope.AddInstruction(CurrentInstruction); } } else { throw new Exception("Unexpected identifier: " + token + " [" + CurrentLine + "]"); } } else if (token == "\n") { CurrentLine++; } else if (token == ";") { // skip to the next statement } else { throw new Exception("Unexpected identifier: " + token + " [" + CurrentLine + "]"); } CurrentToken++; } }