def visit_ForInStatNode(self, node): # TODO: Remove redundancy with range optimization... is_special = False sequence = node.iterator.sequence if isinstance(sequence, ExprNodes.SimpleCallNode): function = sequence.function if sequence.self is None and function.is_name: if function.name in ('range', 'xrange'): is_special = True for arg in sequence.args[:2]: self.mark_assignment(node.target, arg) if len(sequence.args) > 2: self.mark_assignment( node.target, ExprNodes.binop_node(node.pos, '+', sequence.args[0], sequence.args[2])) if not is_special: # A for-loop basically translates to subsequent calls to # __getitem__(), so using an IndexNode here allows us to # naturally infer the base type of pointers, C arrays, # Python strings, etc., while correctly falling back to an # object type when the base type cannot be handled. self.mark_assignment(node.target, ExprNodes.IndexNode( node.pos, base = sequence, index = ExprNodes.IntNode(node.pos, value = '0'))) self.visitchildren(node) return node
def visit_ForInStatNode(self, node): # TODO: Remove redundancy with range optimization... is_special = False sequence = node.iterator.sequence target = node.target if isinstance(sequence, ExprNodes.SimpleCallNode): function = sequence.function if sequence.self is None and function.is_name: entry = self.current_env().lookup(function.name) if not entry or entry.is_builtin: if function.name == 'reversed' and len(sequence.args) == 1: sequence = sequence.args[0] elif function.name == 'enumerate' and len(sequence.args) == 1: if target.is_sequence_constructor and len(target.args) == 2: iterator = sequence.args[0] if iterator.is_name: iterator_type = iterator.infer_type(self.current_env()) if iterator_type.is_builtin_type: # assume that builtin types have a length within Py_ssize_t self.mark_assignment( target.args[0], ExprNodes.IntNode(target.pos, value='PY_SSIZE_T_MAX', type=PyrexTypes.c_py_ssize_t_type)) target = target.args[1] sequence = sequence.args[0] if isinstance(sequence, ExprNodes.SimpleCallNode): function = sequence.function if sequence.self is None and function.is_name: entry = self.current_env().lookup(function.name) if not entry or entry.is_builtin: if function.name in ('range', 'xrange'): is_special = True for arg in sequence.args[:2]: self.mark_assignment(target, arg) if len(sequence.args) > 2: self.mark_assignment( target, ExprNodes.binop_node(node.pos, '+', sequence.args[0], sequence.args[2])) if not is_special: # A for-loop basically translates to subsequent calls to # __getitem__(), so using an IndexNode here allows us to # naturally infer the base type of pointers, C arrays, # Python strings, etc., while correctly falling back to an # object type when the base type cannot be handled. self.mark_assignment(target, ExprNodes.IndexNode( node.pos, base = sequence, index = ExprNodes.IntNode(node.pos, value = '0'))) self.visitchildren(node) return node
def visit_ForFromStatNode(self, node): condition_block = self.flow.nextblock() next_block = self.flow.newblock() # Condition with iterator self.flow.loops.append(LoopDescr(next_block, condition_block)) self.visit(node.bound1) self.visit(node.bound2) if node.step is not None: self.visit(node.step) # Target assignment self.flow.nextblock() self.mark_assignment(node.target, node.bound1) if node.step is not None: self.mark_assignment(node.target, ExprNodes.binop_node(node.pos, "+", node.bound1, node.step)) # Body block self.flow.nextblock() self.visit(node.body) self.flow.loops.pop() # Loop it if self.flow.block: self.flow.block.add_child(condition_block) # Else clause if node.else_clause: self.flow.nextblock(parent=condition_block) self.visit(node.else_clause) if self.flow.block: self.flow.block.add_child(next_block) else: condition_block.add_child(next_block) if next_block.parents: self.flow.block = next_block else: self.flow.block = None return node
def visit_ForFromStatNode(self, node): self.mark_assignment(node.target, node.bound1) if node.step is not None: self.mark_assignment( node.target, ExprNodes.binop_node(node.pos, '+', node.bound1, node.step)) self.visitchildren(node) return node
def visit_ForInStatNode(self, node): # TODO: Remove redundancy with range optimization... is_special = False sequence = node.iterator.sequence target = node.target if isinstance(sequence, ExprNodes.SimpleCallNode): function = sequence.function if sequence.self is None and function.is_name: entry = self.current_env().lookup(function.name) if not entry or entry.is_builtin: if function.name == "reversed" and len(sequence.args) == 1: sequence = sequence.args[0] elif function.name == "enumerate" and len(sequence.args) == 1: if target.is_sequence_constructor and len(target.args) == 2: iterator = sequence.args[0] if iterator.is_name: iterator_type = iterator.infer_type(self.current_env()) if iterator_type.is_builtin_type: # assume that builtin types have a length within Py_ssize_t self.mark_assignment( target.args[0], ExprNodes.IntNode( target.pos, value="PY_SSIZE_T_MAX", type=PyrexTypes.c_py_ssize_t_type ), ) target = target.args[1] sequence = sequence.args[0] if isinstance(sequence, ExprNodes.SimpleCallNode): function = sequence.function if sequence.self is None and function.is_name: entry = self.current_env().lookup(function.name) if not entry or entry.is_builtin: if function.name in ("range", "xrange"): is_special = True for arg in sequence.args[:2]: self.mark_assignment(target, arg) if len(sequence.args) > 2: self.mark_assignment( target, ExprNodes.binop_node(node.pos, "+", sequence.args[0], sequence.args[2]) ) if not is_special: # A for-loop basically translates to subsequent calls to # __getitem__(), so using an IndexNode here allows us to # naturally infer the base type of pointers, C arrays, # Python strings, etc., while correctly falling back to an # object type when the base type cannot be handled. self.mark_assignment( target, ExprNodes.IndexNode( node.pos, base=sequence, index=ExprNodes.IntNode(target.pos, value="PY_SSIZE_T_MAX", type=PyrexTypes.c_py_ssize_t_type), ), ) self.visitchildren(node) return node
def visit_ForFromStatNode(self, node): self.mark_assignment(node.target, node.bound1) if node.step is not None: self.mark_assignment(node.target, ExprNodes.binop_node(node.pos, '+', node.bound1, node.step)) self.visitchildren(node) return node
def macro_call_node(numpy_macro_name): array_node = node.obj func_entry = numpy_pxd_scope.entries[numpy_macro_name] function_name_node = ExprNodes.NameNode( name=EncodedString(numpy_macro_name), pos=pos, entry=func_entry, is_called=1, type=func_entry.type, cf_maybe_null=False, cf_is_null=False) call_node = ExprNodes.SimpleCallNode( pos=pos, function=function_name_node, name=EncodedString(numpy_macro_name), args=[array_node], type=func_entry.type.return_type, analysed=True) return call_node
def numpy_transform_attribute_node(node): assert isinstance(node, ExprNodes.AttributeNode) if node.obj.type.objstruct_cname != 'PyArrayObject': return node pos = node.pos numpy_pxd_scope = node.obj.entry.type.scope.parent_scope def macro_call_node(numpy_macro_name): array_node = node.obj func_entry = numpy_pxd_scope.entries[numpy_macro_name] function_name_node = ExprNodes.NameNode( name=EncodedString(numpy_macro_name), pos=pos, entry=func_entry, is_called=1, type=func_entry.type, cf_maybe_null=False, cf_is_null=False) call_node = ExprNodes.SimpleCallNode( pos=pos, function=function_name_node, name=EncodedString(numpy_macro_name), args=[array_node], type=func_entry.type.return_type, analysed=True) return call_node if node.attribute == u'ndim': result = macro_call_node(u'PyArray_NDIM') elif node.attribute == u'data': call_node = macro_call_node(u'PyArray_DATA') cast_node = ExprNodes.TypecastNode(pos, type=PyrexTypes.c_char_ptr_type, operand=call_node) result = cast_node elif node.attribute == u'shape': result = macro_call_node(u'PyArray_DIMS') elif node.attribute == u'strides': result = macro_call_node(u'PyArray_STRIDES') else: result = node return result
def visit_ForInStatNode(self, node): # TODO: Remove redundancy with range optimization... is_special = False sequence = node.iterator.sequence if isinstance(sequence, ExprNodes.SimpleCallNode): function = sequence.function if sequence.self is None and function.is_name: if function.name in ('range', 'xrange'): is_special = True for arg in sequence.args[:2]: self.mark_assignment(node.target, arg) if len(sequence.args) > 2: self.mark_assignment( node.target, ExprNodes.binop_node(node.pos, '+', sequence.args[0], sequence.args[2])) if not is_special: self.mark_assignment(node.target, object_expr) self.visitchildren(node) return node
def visit_ForInStatNode(self, node): # TODO: Remove redundancy with range optimization... is_special = False sequence = node.iterator.sequence if isinstance(sequence, ExprNodes.SimpleCallNode): function = sequence.function if sequence.self is None and function.is_name: if function.name in ('range', 'xrange'): is_special = True for arg in sequence.args[:2]: self.mark_assignment(node.target, arg) if len(sequence.args) > 2: self.mark_assignment( node.target, ExprNodes.binop_node(node.pos, '+', sequence.args[0], sequence.args[2])) if not is_special: self.mark_assignment(node.target, object_expr) self.visitchildren(node) return node
def visit_ForFromStatNode(self, node): condition_block = self.flow.nextblock() next_block = self.flow.newblock() # Condition with iterator self.flow.loops.append(LoopDescr(next_block, condition_block)) self._visit(node.bound1) self._visit(node.bound2) if node.step is not None: self._visit(node.step) # Target assignment self.flow.nextblock() self.mark_assignment(node.target, node.bound1) if node.step is not None: self.mark_assignment( node.target, ExprNodes.binop_node(node.pos, '+', node.bound1, node.step)) # Body block self.flow.nextblock() self._visit(node.body) self.flow.loops.pop() # Loop it if self.flow.block: self.flow.block.add_child(condition_block) # Else clause if node.else_clause: self.flow.nextblock(parent=condition_block) self._visit(node.else_clause) if self.flow.block: self.flow.block.add_child(next_block) else: condition_block.add_child(next_block) if next_block.parents: self.flow.block = next_block else: self.flow.block = None return node
def empty_slice(pos): none = ExprNodes.NoneNode(pos) return ExprNodes.SliceNode(pos, start=none, stop=none, step=none)