Пример #1
0
 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
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
 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
Пример #5
0
    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
Пример #6
0
 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
Пример #7
0
    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
Пример #8
0
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
Пример #9
0
 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
Пример #10
0
 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
Пример #11
0
    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
Пример #12
0
def empty_slice(pos):
    none = ExprNodes.NoneNode(pos)
    return ExprNodes.SliceNode(pos, start=none, stop=none, step=none)