def render_BoolOp(self, node): values = [] for subnode in node.values: subnode.parent = node subnode = self.render_node(subnode) values.append(subnode) node.values = values node.dtype = 'boolean' for subnode in node.values: if subnode.dtype!='boolean': raise TypeError("Boolean operator acting on non-booleans") node.scalar = logical_all(subnode.scalar for subnode in node.values) node.complexity = 1+sum(subnode.complexity for subnode in node.values) node.stateless = logical_all(subnode.stateless for subnode in node.values) return node
def render_Compare(self, node): node.left = self.render_node(node.left) comparators = [] for subnode in node.comparators: subnode.parent = node subnode = self.render_node(subnode) comparators.append(subnode) node.comparators = comparators node.dtype = 'boolean' comparators = [node.left]+node.comparators node.scalar = logical_all(subnode.scalar for subnode in comparators) node.complexity = 1+sum(subnode.complexity for subnode in comparators) node.stateless = node.left.stateless and all(c.stateless for c in node.comparators) return node
def render_Call(self, node): if len(node.keywords): raise ValueError("Keyword arguments not supported.") elif getattr(node, 'starargs', None) is not None: raise ValueError("Variable number of arguments not supported") elif getattr(node, 'kwargs', None) is not None: raise ValueError("Keyword arguments not supported") args = [] for subnode in node.args: subnode.parent = weakref.proxy(node) subnode = self.render_node(subnode) args.append(subnode) node.args = args node.dtype = 'float' # default dtype # Condition for scalarity of function call: stateless and arguments are scalar node.scalar = False if node.func.id in self.variables: funcvar = self.variables[node.func.id] # sometimes this attribute doesn't exist, if so assume it's not stateless node.stateless = getattr(funcvar, 'stateless', False) node.auto_vectorise = getattr(funcvar, 'auto_vectorise', False) if node.stateless and not node.auto_vectorise: node.scalar = logical_all(subnode.scalar for subnode in node.args) # check that argument types are valid node_arg_types = [subnode.dtype for subnode in node.args] for subnode, argtype in zip(node.args, funcvar._arg_types): if argtype != 'any' and argtype != subnode.dtype: raise TypeError( "Function %s takes arguments with types %s but " "received %s" % (node.func.id, funcvar._arg_types, node_arg_types)) # compute return type return_type = funcvar._return_type if return_type == 'highest': return_type = dtype_hierarchy[max(dtype_hierarchy[nat] for nat in node_arg_types)] node.dtype = return_type else: node.stateless = False # we leave node.func because it is an ast.Name object that doesn't have a dtype # TODO: variable complexity for function calls? node.complexity = 20 + sum(subnode.complexity for subnode in node.args) return node