public object Execute(ICodeNode node, ref int exec_count) { // get the SELECT node's children var children = node.GetChildren(); ICodeNode expr_node = children[0]; // evaluate SELECT expression ExpressionInterpreter expr_interpreter = ExpressionInterpreter.CreateWithObservers(observers); object value = expr_interpreter.Execute(expr_node, ref exec_count); // attempt to select a SELECT_BRANCH. ICodeNode selected_branch = SearchBranches(value, children.Skip(1)); // if there was a selection, execute the SELECT_BRANCH's statement if (selected_branch != null) { ICodeNode stmnt_node = selected_branch.GetChildren().ElementAt(1); StatementInterpreter stmnt_interpreter = StatementInterpreter.CreateWithObservers(observers); stmnt_interpreter.Execute(stmnt_node, ref exec_count); } ++exec_count; return null; }
public object Execute(ICodeNode node, ref int exec_count) { // get the IF node's children var children = node.GetChildren(); ICodeNode expr_node = children[0]; ICodeNode then_node = children[1]; ICodeNode else_node = children.Count > 2 ? children[2] : null; ExpressionInterpreter expr_interpreter = ExpressionInterpreter.CreateWithObservers(observers); StatementInterpreter stmt_interpreter = StatementInterpreter.CreateWithObservers(observers); // evaluate the expression to determine which statement to execute. bool b = (bool)expr_interpreter.Execute(expr_node, ref exec_count); if (b) { stmt_interpreter.Execute(then_node, ref exec_count); } else { stmt_interpreter.Execute(else_node, ref exec_count); } ++exec_count; return null; }
public object Execute(ICodeNode node, ref int exec_count) { switch (node.Type) { case ICodeNodeType.VARIABLE: { // Get the variable's symbol table entry and return its value. SymbolTableEntry entry = (SymbolTableEntry)node.GetAttribute(ICodeKey.ID); return entry.GetAttribute(SymbolTableKey.DataValue); } case ICodeNodeType.INTEGER_CONSTANT: { // Return the integer value. return node.GetAttribute(ICodeKey.VALUE); } case ICodeNodeType.REAL_CONSTANT: { // Return the integer value. return node.GetAttribute(ICodeKey.VALUE); } case ICodeNodeType.STRING_CONSTANT: { // Return the integer value. return node.GetAttribute(ICodeKey.VALUE); } case ICodeNodeType.NEGATE: { // Get the NEGATE node's expression node child. List<ICodeNode> children = node.GetChildren(); ICodeNode expression = children[0]; // Execute the expression and return the negative of its value. object value = Execute(expression, ref exec_count); if (value is int) { return -(int)value; } else if (value is double) { return -(double)value; } else { return null; } } case ICodeNodeType.NOT: { // Get the NOT node's expression node child. List<ICodeNode> children = node.GetChildren(); ICodeNode expression = children[0]; // Execute the expression and return the "not" of its value bool value = (bool)Execute(expression, ref exec_count); return !value; } default: // must be a binary operator return ExecuteBinaryOperator(node, ref exec_count); } }
public object Execute(ICodeNode node, ref int exec_count) { // loop and execute each child StatementInterpreter stmnt_interpreter = StatementInterpreter.CreateWithObservers(observers); foreach (var child in node.GetChildren()) { stmnt_interpreter.Execute(child, ref exec_count); } return null; }
public object Execute(ICodeNode node, ref int exec_count) { // The ASSIGN node's children are the target variable // and the expression. List<ICodeNode> children = node.GetChildren(); ICodeNode variable = children[0]; ICodeNode expression = children[1]; // Expression the expression and get its value. ExpressionInterpreter expr_interpreter = ExpressionInterpreter.CreateWithObservers(observers); object value = expr_interpreter.Execute(expression, ref exec_count); // Set the value as an attribute of the variable's symbol table entry. SymbolTableEntry variable_id = (SymbolTableEntry)variable.GetAttribute(ICodeKey.ID); variable_id.SetAttribute(SymbolTableKey.DataValue, value); SendMessage(node, variable_id.Name, value); ++exec_count; return null; }
public object Execute(ICodeNode node, ref int exec_count) { bool exit_loop = false; ICodeNode expr_node = null; List<ICodeNode> loop_children = node.GetChildren(); ExpressionInterpreter expr_interpreter = ExpressionInterpreter.CreateWithObservers(observers); StatementInterpreter stmt_interpreter = StatementInterpreter.CreateWithObservers(observers); // loop until the TEST expression value is true while (!exit_loop) { ++exec_count; // execute the children of the LOOP node. foreach (var child in loop_children) { if (child.Type == ICodeNodeType.TEST) { if (expr_node == null) { expr_node = child.GetChildren().ElementAt(0); } exit_loop = (bool)expr_interpreter.Execute(expr_node, ref exec_count); } else { stmt_interpreter.Execute(child, ref exec_count); } if (exit_loop) { break; } } } return null; }
private bool SearchConstants(object value, ICodeNode child) { // are the values integer or string? bool integer_mode = value is int; // get the list of SELECT_CONSTANTS values ICodeNode constants_node = child.GetChildren().ElementAt(0); var all_constants = constants_node.GetChildren(); // search the list of constants if (integer_mode) { int v = (int)value; foreach (var constant in all_constants) { int con = (int)constant.GetAttribute(ICodeKey.VALUE); if (v == con) { return true; } } } else { string v = (string)value; foreach (var constant in all_constants) { string con = (string)constant.GetAttribute(ICodeKey.VALUE); if (v == con) { return true; } } } return false; }
private void PrintNode(ICodeNode node) { // opening tag Append(indentation); Append("<" + node.ToString()); PrintAttributes(node); PrintTypeSpec(node); List<ICodeNode> children = node.GetChildren(); if (children.Count > 0) { Append(">"); PrintLine(); PrintChildNodes(children); Append(indentation); Append("</" + node.ToString() + ">"); } else { Append(" "); Append("/>"); } PrintLine(); }
private object ExecuteBinaryOperator(ICodeNode node, ref int exec_count) { // Get the two operand children of the operator node. List<ICodeNode> children = node.GetChildren(); ICodeNode operand_node1 = children[0]; ICodeNode operand_node2 = children[1]; // Operands. object operand1 = Execute(operand_node1, ref exec_count); object operand2 = Execute(operand_node2, ref exec_count); bool integer_mode = (operand1 is int) && (operand2 is int); // ==================== // Arithmetic operators // ==================== if (ARITH_OPS.Contains(node.Type)) { if (integer_mode) { int value1 = (int)operand1; int value2 = (int)operand2; // Integer operation switch (node.Type) { case ICodeNodeType.ADD: return value1 + value2; case ICodeNodeType.SUBTRACT: return value1 - value2; case ICodeNodeType.MULTIPLY: return value1 * value2; case ICodeNodeType.FLOAT_DIVIDE: // check for division by error: if (value2 != 0) { return (double)value1 / (double)value2; } else { RuntimeErrorHandler.Flag(node, RuntimeErrorCode.DIVISION_BY_ZERO, this); return 0; } case ICodeNodeType.INTEGER_DIVIDE: // check for division by error: if (value2 != 0) { return value1 / value2; } else { RuntimeErrorHandler.Flag(node, RuntimeErrorCode.DIVISION_BY_ZERO, this); return 0; } case ICodeNodeType.MOD: // check for division by error: if (value2 != 0) { return value1 % value2; } else { RuntimeErrorHandler.Flag(node, RuntimeErrorCode.DIVISION_BY_ZERO, this); return 0; } } } else { double value1 = operand1 is int ? (int)operand1 : (double)operand1; double value2 = operand2 is int ? (int)operand2 : (double)operand2; // float operations switch (node.Type) { case ICodeNodeType.ADD: return value1 + value2; case ICodeNodeType.SUBTRACT: return value1 - value2; case ICodeNodeType.MULTIPLY: return value1 * value2; case ICodeNodeType.FLOAT_DIVIDE: // check for division by zero if (value2 != 0.0f) { return value1 / value2; } else { RuntimeErrorHandler.Flag(node, RuntimeErrorCode.DIVISION_BY_ZERO, this); return 0.0f; } } } } else if (node.Type == ICodeNodeType.AND || node.Type == ICodeNodeType.OR) { bool value1 = (bool)operand1; bool value2 = (bool)operand2; switch (node.Type) { case ICodeNodeType.AND: return value1 && value2; case ICodeNodeType.OR: return value1 || value2; } } else if (integer_mode) { int value1 = (int)operand1; int value2 = (int)operand2; // integer operands switch (node.Type) { case ICodeNodeType.EQ: return value1 == value2; case ICodeNodeType.NE: return value1 != value2; case ICodeNodeType.LT: return value1 < value2; case ICodeNodeType.LE: return value1 <= value2; case ICodeNodeType.GT: return value1 > value2; case ICodeNodeType.GE: return value1 >= value2; } } else { double value1 = operand1 is int ? (int)operand1 : (double)operand1; double value2 = operand2 is int ? (int)operand2 : (double)operand2; // float operands switch (node.Type) { case ICodeNodeType.EQ: return value1 == value2; case ICodeNodeType.NE: return value1 != value2; case ICodeNodeType.LT: return value1 < value2; case ICodeNodeType.LE: return value1 <= value2; case ICodeNodeType.GT: return value1 > value2; case ICodeNodeType.GE: return value1 <= value2; } } return 0; // should never get here. }