def pop_and_add(scope_ast, oper, operands): # Pop and create new tree node = Node(None, 'expression') node.leaf = OPER_NAMES[oper] for count in range(get_arity(oper)): node.add_front(operands.pop()) # Work out the type for the resulting expression. type_ast = get_expr_type(node.children[0]) for new_type_expr in node.children[1:]: new_type_ast = get_expr_type(new_type_expr) if infogripper.can_coerce_expr(new_type_expr, type_ast): type_ast = new_type_ast else: raise error.CannotReconcileTypesError(new_type_ast.leaf, type_ast.leaf, scope_ast) # Store a value, if we can. This over-rides the above discovered type. # FIXME: This is a cheesy hack. if type_ast.has_attribute('smallest') and type_ast.has_attribute('largest'): # It's a scalar type, we can play with it. if len(node.children) > 1: result = oper.join(['(%s)' % (child.attribute('value')) for child in node.children]) else: # FIXME: Even cheesier result = "%s%s" % (PYTHON_UNARY[oper] , node.children[0].attribute('value')) try: result = eval(result) node.add_attribute('value', result) except: pass smallest_type_name = smallest_type_hack(result) if smallest_type_name: type_ast = infogripper.getNode(smallest_type_name, scope_ast, 'type') node.add_child(type_ast) operands.append(node)