def get_type(self, env=None): if isinstance(self.op, Op.ArrayRef): if isinstance(self.left, SymbolRef) and env is not None \ and env._has_key(self.left.name): type = env._lookup(self.left.name)._dtype_ return get_c_type_from_numpy_dtype(type)() # FIXME: integer promotions and stuff like that if hasattr(self.left, 'get_type'): left_type = self.left.get_type() elif isinstance(self.left, SymbolRef) and env is not None \ and env._has_key(self.left.name): left_type = env._lookup(self.left.name) elif hasattr(self.left, 'type'): left_type = self.left.type else: left_type = None if hasattr(self.right, 'get_type'): right_type = self.right.get_type() elif isinstance(self.right, SymbolRef) and env is not None \ and env._has_key(self.right.name): right_type = env._lookup(self.right.name) elif hasattr(self.right, 'type'): right_type = self.right.type else: right_type = None if isinstance(self.op, Op.ArrayRef): ptr_type = left_type._type_ return ptr_type() if hasattr(ptr_type, '__call__') else left_type return get_common_ctype( filter(lambda x: x is not None, [right_type, left_type]))
def get_type(self, env=None): if isinstance(self.op, Op.ArrayRef): if isinstance(self.left, SymbolRef) and env is not None \ and env._has_key(self.left.name): type = env._lookup(self.left.name)._dtype_ return get_c_type_from_numpy_dtype(type)() # FIXME: integer promotions and stuff like that if hasattr(self.left, 'get_type'): left_type = self.left.get_type() elif isinstance(self.left, SymbolRef) and env is not None \ and env._has_key(self.left.name): left_type = env._lookup(self.left.name) elif hasattr(self.left, 'type'): left_type = self.left.type else: left_type = None if hasattr(self.right, 'get_type'): right_type = self.right.get_type() elif isinstance(self.right, SymbolRef) and env is not None \ and env._has_key(self.right.name): right_type = env._lookup(self.right.name) elif hasattr(self.right, 'type'): right_type = self.right.type else: right_type = None return get_common_ctype(filter(lambda x: x is not None, [right_type, left_type]))
def get_type(self, env=None): # FIXME: integer promotions and stuff like that if hasattr(self.left, 'get_type'): left_type = self.left.get_type() elif isinstance(self.left, SymbolRef) and env is not None \ and env._has_key(self.left.name): left_type = env._lookup(self.left.name) elif hasattr(self.left, 'type'): left_type = self.left.type else: left_type = None if hasattr(self.right, 'get_type'): right_type = self.right.get_type() elif isinstance(self.right, SymbolRef) and env is not None \ and env._has_key(self.right.name): right_type = env._lookup(self.right.name) elif hasattr(self.right, 'type'): right_type = self.right.type else: right_type = None return get_common_ctype( filter(lambda x: x is not None, [right_type, left_type]))
def test_coercion(self): types = (ctypes.c_long, ctypes.c_double, ctypes.c_int) self.assertEqual(get_common_ctype(types), ctypes.c_double)
def visit_List(self, node): elts = [self.visit(elt) for elt in node.elts] types = [get_type(elt) for elt in elts] array_type = get_common_ctype(types) return Array(type=ctypes.POINTER(array_type)(), body=elts)
def visit_For(self, node): """restricted, for now, to range as iterator with long-type args""" if isinstance(node, ast.For) and \ isinstance(node.iter, ast.Call) and \ isinstance(node.iter.func, ast.Name) and \ node.iter.func.id in ('range', 'xrange'): Range = node.iter nArgs = len(Range.args) if nArgs == 1: stop = self.visit(Range.args[0]) start, step = Constant(0), Constant(1) elif nArgs == 2: start, stop = map(self.visit, Range.args) step = Constant(1) elif nArgs == 3: start, stop, step = map(self.visit, Range.args) else: raise Exception("Cannot convert a for...range with %d args." % nArgs) # check no-op conditions. if all(isinstance(item, Constant) for item in (start, stop, step)): if step.value == 0: raise ValueError("range() step argument must not be zero") elif start.value == stop.value or \ (start.value < stop.value and step.value < 0) or \ (start.value > stop.value and step.value > 0): return None if not all( isinstance(item, CtreeNode) for item in (start, stop, step)): node.body = list(map(self.visit, node.body)) return node # TODO allow any expressions castable to Long type target_types = [c_long] for el in (stop, start, step): # typed item to try and guess type off of. Imperfect right now. if hasattr(el, 'get_type'): # TODO take the proper class instead of the last; if start, # end are doubles, but step is long, target is double t = el.get_type() assert any( isinstance(t, klass) for klass in [c_byte, c_int, c_long, c_short] ), "Can only convert ranges with integer/long \ start/stop/step values" target_types.append(type(t)) target_type = get_common_ctype(target_types)() target = SymbolRef(node.target.id, target_type) op = Lt if hasattr(start, 'value') and hasattr(stop, 'value') and \ start.value > stop.value: op = Gt for_loop = For( Assign(target, start), op(target.copy(), stop), AddAssign(target.copy(), step), [self.visit(stmt) for stmt in node.body], ) return for_loop node.body = list(map(self.visit, node.body)) return node
def visit_For(self, node): """restricted, for now, to range as iterator with long-type args""" if ( isinstance(node, ast.For) and isinstance(node.iter, ast.Call) and isinstance(node.iter.func, ast.Name) and node.iter.func.id in ("range", "xrange") ): Range = node.iter nArgs = len(Range.args) if nArgs == 1: stop = self.visit(Range.args[0]) start, step = Constant(0), Constant(1) elif nArgs == 2: start, stop = map(self.visit, Range.args) step = Constant(1) elif nArgs == 3: start, stop, step = map(self.visit, Range.args) else: raise Exception("Cannot convert a for...range with %d args." % nArgs) # check no-op conditions. if all(isinstance(item, Constant) for item in (start, stop, step)): if step.value == 0: raise ValueError("range() step argument must not be zero") elif ( start.value == stop.value or (start.value < stop.value and step.value < 0) or (start.value > stop.value and step.value > 0) ): return None if not all(isinstance(item, CtreeNode) for item in (start, stop, step)): node.body = list(map(self.visit, node.body)) return node # TODO allow any expressions castable to Long type target_types = [c_long] for el in (stop, start, step): # typed item to try and guess type off of. Imperfect right now. if hasattr(el, "get_type"): # TODO take the proper class instead of the last; if start, # end are doubles, but step is long, target is double t = el.get_type() assert any( isinstance(t, klass) for klass in [c_byte, c_int, c_long, c_short] ), "Can only convert ranges with integer/long \ start/stop/step values" target_types.append(type(t)) target_type = get_common_ctype(target_types)() target = SymbolRef(node.target.id, target_type) op = Lt if hasattr(start, "value") and hasattr(stop, "value") and start.value > stop.value: op = Gt for_loop = For( Assign(target, start), op(target.copy(), stop), AddAssign(target.copy(), step), [self.visit(stmt) for stmt in node.body], ) return for_loop node.body = list(map(self.visit, node.body)) return node