def visit_binopnode(self, node, context): """ Returns the result of the binary operation. :param node: Node which houses two children Nodes. :param context: Context of the caller. :return: Result of the binary operation on both child Nodes. """ result, error = None, None runtime_result = RuntimeResult() left_node = runtime_result.register(self.visit(node.left_node, context)) right_node = runtime_result.register( self.visit(node.right_node, context)) if runtime_result.should_return(): return runtime_result if node.op_token.type == TP_PLUS: result, error = left_node.add_to(right_node) elif node.op_token.type == TP_MINUS: result, error = left_node.subtract_by(right_node) elif node.op_token.type == TP_POWER: result, error = left_node.power_by(right_node) elif node.op_token.type == TP_MUL: result, error = left_node.multiply_by(right_node) elif node.op_token.type == TP_DIV: result, error = left_node.divide_by(right_node) elif node.op_token.type == TP_MODULO: result, error = left_node.modulo_by(right_node) elif node.op_token.type == TP_CLEAN_DIV: result, error = left_node.divide_by(right_node, clean=True) elif node.op_token.type == TP_NE: result, error = left_node.get_comparison_ne(right_node) elif node.op_token.type == TP_EE: result, error = left_node.get_comparison_ee(right_node) elif node.op_token.type == TP_LT: result, error = left_node.get_comparison_lt(right_node) elif node.op_token.type == TP_LTE: result, error = left_node.get_comparison_lte(right_node) elif node.op_token.type == TP_GT: result, error = left_node.get_comparison_gt(right_node) elif node.op_token.type == TP_GTE: result, error = left_node.get_comparison_gte(right_node) elif node.op_token.matches(TP_KEYWORD, 'AND'): result, error = left_node.anded_by(right_node) elif node.op_token.matches(TP_KEYWORD, 'OR'): result, error = left_node.ored_by(right_node) if runtime_result.should_return(): return runtime_result.failure(runtime_result) if error: return runtime_result.failure(error) return runtime_result.success( result.set_position(node.start_pos, node.end_pos))
def visit_varaccessnode(self, node, context): """ Accesses the value of variables in the stream. :param node: Node with which to fetch the variable. :param context: Context of the caller. :return: Value of fetching a variable's value and executing it. """ runtime_result = RuntimeResult() var_name = node.var_name.value var_value = context.symbol_table.get(var_name) if var_value is None: runtime_result.failure( ActiveRuntimeError('VAR "{}" not defined'.format(var_name), node.start_pos, node.end_pos, context)) var_value = var_value.copy().set_position( node.start_pos, node.end_pos).set_context(context) return runtime_result.success(var_value)
def check_args(self, arg_names, args): """ Checks that correct number of args are present. :param arg_names: List of argument names. :param args: List of arguments passed into func. :return: None, if there are no issues. """ runtime_result = RuntimeResult() if len(args) > len(arg_names): return runtime_result.failure( ActiveRuntimeError( 'Too many arguments'.format(len(args) - len(arg_names)), self.start_pos, self.end_pos, self.context)) if len(args) < len(arg_names): return runtime_result.failure( ActiveRuntimeError( 'Too few arguments'.format(len(arg_names) - len(args)), self.start_pos, self.end_pos, self.context)) return runtime_result.success(None)
def visit_unaryopnode(self, node, context): """ Returns result of the unary operator on the node. :param node: Node with which to perform a unary operation. :param context: Context of the caller. :return: Result of the unary operation on the node. """ error = None runtime_result = RuntimeResult() number = runtime_result.register(self.visit(node.right_node, context)) if runtime_result.should_return(): return runtime_result if node.op_token.type == TP_MINUS: number, error = number.multiply_by(Number(-1)) elif node.op_token.matches(TP_KEYWORD, 'NOT'): number, error = number.notted() if error: return runtime_result.failure(error) return runtime_result.success( number.set_position(node.start_pos, node.end_pos))