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); } }
private void PrintAttributes(ICodeNode node) { string save = indentation; node.ForeachAttribute((k, v) => PrintAttribute(k.ToString(), v)); indentation = save; }
private void SendSourceLineMessage(ICodeNode node) { object line_number = node.GetAttribute(ICodeKey.LINE); // send the SourceLine message if (line_number != null) { var args = (Tuple<int>)Tuple.Create((int)line_number); Message msg = new Message(MessageType.SourceLine, args); Send(msg); } }
private void SendMessage(ICodeNode node, string variable_name, object value) { object line_number = node.GetAttribute(ICodeKey.LINE); // Send an ASSIGN message. if (line_number != null) { var args = Tuple.Create((int)line_number, variable_name, (object)value); Message msg = new Message(MessageType.Assign, args); Send(msg); } }
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) { // send a message about the current source line SendSourceLineMessage(node); switch (node.Type) { case ICodeNodeType.COMPOUND: { CompoundInterpreter compound_interpreter = CompoundInterpreter.CreateWithObservers(observers); return compound_interpreter.Execute(node, ref exec_count); } case ICodeNodeType.ASSIGN: { AssignmentInterpreter assign_interpreter = AssignmentInterpreter.CreateWithObservers(observers); return assign_interpreter.Execute(node, ref exec_count); } case ICodeNodeType.LOOP: { LoopInterpreter loop_interpreter = LoopInterpreter.CreateWithObservers(observers); return loop_interpreter.Execute(node, ref exec_count); } case ICodeNodeType.IF: { IfInterpreter if_interpreter = IfInterpreter.CreateWithObservers(observers); return if_interpreter.Execute(node, ref exec_count); } case ICodeNodeType.SELECT: { SelectInterpreter select_interpreter = SelectInterpreter.CreateWithObservers(observers); return select_interpreter.Execute(node, ref exec_count); } case ICodeNodeType.NO_OP: return null; default: RuntimeErrorHandler.Flag(node, RuntimeErrorCode.UNIMPLEMENTED_FEATURE, this); return null; } }
public static void Flag(ICodeNode node, RuntimeErrorCode error_code, MessageProducer backend) { //string line_number = null; while (node != null && node.GetAttribute(ICodeKey.LINE) == null) { node = node.Parent; } // notify observers var args = (Tuple<string, int>)Tuple.Create(error_code.Message, (int)node.GetAttribute(ICodeKey.LINE)); Message msg = new Message(MessageType.RuntimeError, args); backend.Send(msg); if (++Errors > MAX_ERRORS) { Console.WriteLine("*** ABORTED AFTER TOO MANY RUNTIME ERRORS.*"); Environment.Exit(-1); } }
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 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. }
private void PrintTypeSpec(ICodeNode node) { }
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(); }
public ICodeNode Add(ICodeNode node) { Contract.Requires(!children.Contains(node)); if (node != null) { children.Add(node); node.Parent = this; } return node; }
private void SetLineNumber(ICodeNode node, int line) { node.SetAttribute(ICodeKey.LINE, line); }
public void ParseList(Token token, ICodeNode parent, TokenType terminator, ErrorCode error) { var terminator_set = new HashSet<TokenType>(STMT_START_SET); terminator_set.Add(terminator); while(!token.IsEof && token.TokenType != terminator) { // parse a statement. The parent node adopts the statement node. ICodeNode statement_node = Parse(token); parent.Add(statement_node); token = InternalScanner.CurrentToken; // look for the semicolon between the statements. if (token.TokenType == TokenType.SEMICOLON) { token = InternalScanner.GetNextToken(); } else if (STMT_START_SET.Contains(token.TokenType)) { ErrorHandler.Flag(token, ErrorCode.MISSING_SEMICOLON, this); } // Synchronize at the start of the next statement // or at the terminator. token = Parser.Synchronize(terminator_set, InternalScanner, this); } // look for the terminator token if (token.TokenType == terminator) { token = InternalScanner.GetNextToken(); } else { ErrorHandler.Flag(token, error, this); } }
private void ParseConstantList(Token token, ICodeNode constants_node, HashSet<object> constant_set) { // loop to parse each constant. while (CONSTANT_START_SET.Contains(token.TokenType)) { // the constants list node adopts the constant node. constants_node.Add(ParseConstant(token, constant_set)); // synchronize at the comma between constants. token = Parser.Synchronize(COMMA_SET, InternalScanner, this); // look for the COMMA if (token.TokenType == TokenType.COMMA) { token = InternalScanner.GetNextToken(); // consume the , } else if (CONSTANT_START_SET.Contains(token.TokenType)) { ErrorHandler.Flag(token, ErrorCode.MISSING_COMMA, this); } } }