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; } }
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; } }