public void Run() { instructionPointer = 0; ExpressionResult = null; ExpressionType = T1VariableType.Int; // pass 1: LabelSet while (instructionPointer < Instructions.Count) { if (Instructions[instructionPointer].Type == T1InstructionType.LabelSet) { RunInstruction(Instructions[instructionPointer]); } instructionPointer++; } // pass 2: Run all instructionPointer = 0; while (instructionPointer < Instructions.Count) { if (Instructions[instructionPointer].Type == T1InstructionType.LabelSet) { instructionPointer++; continue; } RunInstruction(Instructions[instructionPointer++]); } }
public T1InstructionFunctionDeclaration(List <T1InstructionVariableDeclaration> arguments, T1VariableType returnType, int functionId, T1Scope functionScope) : base(functionId) { type = T1InstructionType.FunctionDeclaration; this.arguments = arguments; this.returnType = returnType; this.functionId = functionId; this.functionScope = functionScope; }
private void EvaluateExpression(object expression) { if (expression is T1ExpressionItem) { EvaluateExpressionItem((T1ExpressionItem)expression); } else if (expression is T1RuntimeVairableReference) { EvaluateExpressionReference((T1RuntimeVairableReference)expression); } else if (expression is T1ExpressionOperand) { switch (((T1ExpressionOperand)expression).Type) { case T1OperandType.Constant: ExpressionResult = ((T1ExpressionOperand)expression).Value; if (ExpressionResult.GetType().Name.Contains("Int32")) { ExpressionType = T1VariableType.Int; } else if (ExpressionResult.GetType().Name.Contains("Double")) { ExpressionType = T1VariableType.Double; } else if (ExpressionResult.GetType().Name.Contains("Byte")) { ExpressionType = T1VariableType.Byte; } else if (ExpressionResult.GetType().Name.Contains("String")) { ExpressionType = T1VariableType.String; } else { ExpressionType = T1VariableType.Void; } break; case T1OperandType.Expression: EvaluateExpressionItem((T1ExpressionItem)((T1ExpressionOperand)expression).Value); break; case T1OperandType.Variable: EvaluateExpressionReference((T1RuntimeVairableReference)((T1ExpressionOperand)expression).Value); break; case T1OperandType.Function: throw new Exception("not implemented 108"); } } else { throw new Exception("Internal error 902"); } }
private void EvaluateExpressionReference(T1RuntimeVairableReference expression) { if (expression.Scope.VariableTable[expression.VariableId].VariableType != expression.VariableType) { throw new Exception("Runtime error: type mismatch"); } ExpressionType = expression.VariableType; ExpressionResult = expression.Scope.VariableTable[expression.VariableId].Value; }
private T1VariableType GetVariableTypeFromToken(string typeName) { T1VariableType variableType = T1VariableType.Int; if (typeName == "void") { variableType = T1VariableType.Void; } else if (typeName == "string") { variableType = T1VariableType.String; } else if (typeName == "byte") { variableType = T1VariableType.Byte; } else { variableType = T1VariableType.Double; } return(variableType); }
private void EvaluateExpressionItem(T1ExpressionItem expression) { switch (expression.Operator) { case T1Operator.DirectByte: if (expression.OperandLeft.Value is byte) { ExpressionResult = (byte)expression.OperandLeft.Value; } else if (expression.OperandLeft.Value is T1ExpressionItem) { EvaluateExpression(expression.OperandLeft); } else { throw new Exception("Runtime error: type mismatch"); } ExpressionType = T1VariableType.Byte; break; case T1Operator.DirectInt: if (expression.OperandLeft.Value is int) { ExpressionResult = (int)expression.OperandLeft.Value; } else if (expression.OperandLeft.Value is T1ExpressionItem) { EvaluateExpression(expression.OperandLeft); } else { throw new Exception("Runtime error: type mismatch"); } ExpressionType = T1VariableType.Int; break; case T1Operator.DirectNumeric: if (expression.OperandLeft.Value is double) { ExpressionResult = (double)expression.OperandLeft.Value; } else if (expression.OperandLeft.Value is T1ExpressionItem) { EvaluateExpression(expression.OperandLeft); } else { throw new Exception("Runtime error: type mismatch"); } ExpressionType = T1VariableType.Double; break; case T1Operator.DirectString: if (expression.OperandLeft.Value is string) { ExpressionResult = (string)expression.OperandLeft.Value; } else if (expression.OperandLeft.Value is T1ExpressionItem) { EvaluateExpression(expression.OperandLeft); } else { throw new Exception("Runtime error: type mismatch"); } ExpressionType = T1VariableType.String; break; case T1Operator.Dereference: T1Variable variable = ((T1RuntimeVairableReference)expression.OperandLeft.Value).Scope.VariableTable[((T1RuntimeVairableReference)expression.OperandLeft.Value).VariableId]; switch (variable.VariableType) { case T1VariableType.Byte: ExpressionResult = (byte)variable.Value; break; case T1VariableType.Double: ExpressionResult = (double)variable.Value; break; case T1VariableType.Int: ExpressionResult = (int)variable.Value; break; case T1VariableType.String: ExpressionResult = (string)variable.Value; break; } ExpressionType = variable.VariableType; break; case T1Operator.Concatanate: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); ExpressionResult = ExpressionStackPopString() + (string)ExpressionResult; ExpressionType = T1VariableType.String; break; case T1Operator.Add: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); switch (ExpressionType) { case T1VariableType.Int: ExpressionResult = ExpressionStackPopInt() + (int)ExpressionResult; break; case T1VariableType.Byte: ExpressionResult = ExpressionStackPopByte() + (byte)ExpressionResult; break; case T1VariableType.Double: ExpressionResult = ExpressionStackPopDouble() + (double)ExpressionResult; break; default: throw new Exception("Runtime error: Invalid type in math"); } break; case T1Operator.Subtract: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); switch (ExpressionType) { case T1VariableType.Int: ExpressionResult = ExpressionStackPopInt() - (int)ExpressionResult; break; case T1VariableType.Byte: ExpressionResult = ExpressionStackPopByte() - (byte)ExpressionResult; break; case T1VariableType.Double: ExpressionResult = ExpressionStackPopDouble() - (double)ExpressionResult; break; default: throw new Exception("Runtime error: Invalid type in math"); } break; case T1Operator.Multiply: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); switch (ExpressionType) { case T1VariableType.Int: ExpressionResult = ExpressionStackPopInt() * (int)ExpressionResult; break; case T1VariableType.Byte: ExpressionResult = ExpressionStackPopByte() * (byte)ExpressionResult; break; case T1VariableType.Double: ExpressionResult = ExpressionStackPopDouble() * (double)ExpressionResult; break; default: throw new Exception("Runtime error: Invalid type in math"); } break; case T1Operator.Divide: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); switch (ExpressionType) { case T1VariableType.Int: ExpressionResult = ExpressionStackPopInt() / (int)ExpressionResult; break; case T1VariableType.Byte: ExpressionResult = ExpressionStackPopByte() / (byte)ExpressionResult; break; case T1VariableType.Double: ExpressionResult = ExpressionStackPopDouble() / (double)ExpressionResult; break; default: throw new Exception("Runtime error: Invalid type in math"); } break; case T1Operator.Mod: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); switch (ExpressionType) { case T1VariableType.Int: ExpressionResult = ExpressionStackPopInt() % (int)ExpressionResult; break; case T1VariableType.Byte: ExpressionResult = ExpressionStackPopByte() % (byte)ExpressionResult; break; case T1VariableType.Double: ExpressionResult = ExpressionStackPopDouble() % (double)ExpressionResult; break; default: throw new Exception("Runtime error: Invalid type in math"); } break; case T1Operator.ShiftLeft: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); ExpressionResult = ExpressionStackPopInt() << (int)ExpressionResult; break; case T1Operator.Power: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); ExpressionResult = (int)Math.Pow(ExpressionStackPopInt(), (int)ExpressionResult); break; case T1Operator.ShiftRight: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); ExpressionResult = ExpressionStackPopInt() >> (int)ExpressionResult; break; case T1Operator.OrLogical: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); ExpressionResult = (ExpressionStackPopDouble() == 1) || ((double)ExpressionResult == 1); break; case T1Operator.OrBitwise: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); ExpressionResult = (ExpressionStackPopDouble() == 1) | ((double)ExpressionResult == 1); break; case T1Operator.AndLogical: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); ExpressionResult = (ExpressionStackPopDouble() == 1) && ((double)ExpressionResult == 1); break; case T1Operator.AndBitwise: EvaluateExpression(expression.OperandLeft); ExpressionStackPush(); EvaluateExpression(expression.OperandRight); ExpressionResult = (ExpressionStackPopDouble() == 1) & ((double)ExpressionResult == 1); break; } }
public T1Variable(T1VariableType variableType, object value) { this.variableType = variableType; this.value = value; }
public T1Variable(T1VariableType variableType) { this.variableType = variableType; value = null; }
public T1RuntimeVairableReference(T1Scope scope, int variableId, T1VariableType variableType) { this.scope = scope; this.variableId = variableId; this.variableType = variableType; }
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++; } }
public T1InstructionVariableDeclaration(T1VariableType variableType) : base(T1InstructionType.VariableDeclaration, variableType) { this.variableType = variableType; }