def visit_Compare(self, node):
        node = self.generic_visit(node)
        if len(node.ops) > 1:
            # in case we have more than one compare operator
            # we generate an auxiliary function
            # that lazily evaluates the needed parameters
            imported_ids = self.gather(ImportedIds, node)
            imported_ids = sorted(imported_ids)
            binded_args = [ast.Name(i, ast.Load(), None) for i in imported_ids]

            # name of the new function
            forged_name = "{0}_compare{1}".format(self.prefix,
                                                  len(self.compare_functions))

            # call site
            call = ast.Call(
                ast.Name(forged_name, ast.Load(), None),
                binded_args,
                [])

            # new function
            arg_names = [ast.Name(i, ast.Param(), None) for i in imported_ids]
            args = ast.arguments(arg_names, None, [], [], None, [])

            body = []  # iteratively fill the body (yeah, feel your body!)

            if is_trivially_copied(node.left):
                prev_holder = node.left
            else:
                body.append(ast.Assign([ast.Name('$0', ast.Store(), None)],
                                       node.left))
                prev_holder = ast.Name('$0', ast.Load(), None)

            for i, exp in enumerate(node.comparators):
                if is_trivially_copied(exp):
                    holder = exp
                else:
                    body.append(ast.Assign([ast.Name('${}'.format(i+1),
                                                     ast.Store(), None)],
                                           exp))
                    holder = ast.Name('${}'.format(i+1), ast.Load(), None)
                cond = ast.Compare(prev_holder,
                                   [node.ops[i]],
                                   [holder])
                body.append(ast.If(cond,
                                   [ast.Pass()],
                                   [ast.Return(path_to_attr(('__builtin__', 'False')))]))
                prev_holder = holder

            body.append(ast.Return(path_to_attr(('__builtin__', 'True'))))

            forged_fdef = ast.FunctionDef(forged_name, args, body, [], None)
            self.compare_functions.append(forged_fdef)

            return call
        else:
            return node
Beispiel #2
0
    def visit_Compare(self, node):
        node = self.generic_visit(node)
        if len(node.ops) > 1:
            # in case we have more than one compare operator
            # we generate an auxiliary function
            # that lazily evaluates the needed parameters
            imported_ids = self.passmanager.gather(ImportedIds, node, self.ctx)
            imported_ids = sorted(imported_ids)
            binded_args = [ast.Name(i, ast.Load(), None) for i in imported_ids]

            # name of the new function
            forged_name = "{0}_compare{1}".format(self.prefix,
                                                  len(self.compare_functions))

            # call site
            call = ast.Call(ast.Name(forged_name, ast.Load(), None),
                            binded_args, [])

            # new function
            arg_names = [ast.Name(i, ast.Param(), None) for i in imported_ids]
            args = ast.arguments(arg_names, None, [], [], None, [])

            body = []  # iteratively fill the body (yeah, feel your body!)

            if is_trivially_copied(node.left):
                prev_holder = node.left
            else:
                body.append(
                    ast.Assign([ast.Name('$0', ast.Store(), None)], node.left))
                prev_holder = ast.Name('$0', ast.Load(), None)

            for i, exp in enumerate(node.comparators):
                if is_trivially_copied(exp):
                    holder = exp
                else:
                    body.append(
                        ast.Assign(
                            [ast.Name('${}'.format(i + 1), ast.Store(), None)],
                            exp))
                    holder = ast.Name('${}'.format(i + 1), ast.Load(), None)
                cond = ast.Compare(prev_holder, [node.ops[i]], [holder])
                body.append(
                    ast.If(
                        cond, [ast.Pass()],
                        [ast.Return(path_to_attr(('__builtin__', 'False')))]))
                prev_holder = holder

            body.append(ast.Return(path_to_attr(('__builtin__', 'True'))))

            forged_fdef = ast.FunctionDef(forged_name, args, body, [], None)
            self.compare_functions.append(forged_fdef)

            return call
        else:
            return node
Beispiel #3
0
    def inlineFixedSizeArrayCompare(self, node):
        if len(node.comparators) != 1:
            return node

        node_right = node.comparators[0]

        alike = ast.Num, ast.List, ast.Tuple
        if isinstance(node.left, alike) and isinstance(node_right, alike):
            return node

        lbase, lsize = self.fixedSizeArray(node.left)
        rbase, rsize = self.fixedSizeArray(node_right)
        if not lbase or not rbase:
            return node

        if rsize != 1 and lsize != 1 and rsize != lsize:
            raise PythranSyntaxError("Invalid numpy broadcasting", node)

        self.update = True

        operands = [
            ast.Compare(self.make_array_index(lbase, lsize,
                                              i), [type(node.ops[0])()],
                        [self.make_array_index(rbase, rsize, i)])
            for i in range(max(lsize, rsize))
        ]
        res = ast.Call(path_to_attr(('numpy', 'array')),
                       [ast.Tuple(operands, ast.Load())], [])
        self.aliases[res.func] = {path_to_node(('numpy', 'array'))}
        return res
Beispiel #4
0
    def visit_Name(self, node):
        """
        Replace name with full expanded name.

        Examples
        --------
        >> from numpy.linalg import det

        >> det(a)

        Becomes

        >> numpy.linalg.det(a)
        """
        if node.id in self.symbols:
            symbol = path_to_node(self.symbols[node.id])
            if not getattr(symbol, 'isliteral', lambda: False)():
                parent = self.ancestors[node][-1]
                blacklist = (ast.Tuple,
                             ast.List,
                             ast.Set,
                             ast.Return)
                if isinstance(parent, blacklist):
                    raise PythranSyntaxError(
                        "Unsupported module identifier manipulation",
                        node)
            new_node = path_to_attr(self.symbols[node.id])
            new_node.ctx = node.ctx
            ast.copy_location(new_node, node)
            return new_node
        return node
    def visit_ListComp(self, node):
        def makeattr(*args):
            r = ast.Attribute(value=ast.Name(id='builtins',
                                             ctx=ast.Load(),
                                             annotation=None,
                                             type_comment=None),
                              attr='map',
                              ctx=ast.Load())
            r = ast.Call(r, list(args), [])
            r = ast.Call(
                ast.Attribute(ast.Name('builtins', ast.Load(), None, None),
                              'list', ast.Load()), [r], [])
            return r

        if isinstance(node.elt, ast.Constant) and len(node.generators) == 1:
            gen = node.generators[0]
            if not gen.ifs and isinstance(gen.iter, ast.Call):
                try:
                    path = attr_to_path(gen.iter.func)[1]
                    range_path = 'pythonic', 'builtins', 'functor', 'range'
                    if path == range_path and len(gen.iter.args) == 1:
                        self.update = True
                        return ast.BinOp(
                            ast.List([node.elt], ast.Load()), ast.Mult(),
                            ast.Call(path_to_attr(('builtins', 'len')),
                                     [gen.iter], []))
                except TypeError:
                    pass

        return self.visitComp(node, makeattr)
Beispiel #6
0
    def inlineFixedSizeArrayBinOp(self, node):

        alike = ast.List, ast.Tuple, ast.Constant
        if isinstance(node.left, alike) and isinstance(node.right, alike):
            return node

        lbase, lsize = self.fixedSizeArray(node.left)
        rbase, rsize = self.fixedSizeArray(node.right)
        if not lbase or not rbase:
            return node

        if rsize != 1 and lsize != 1 and rsize != lsize:
            raise PythranSyntaxError("Invalid numpy broadcasting", node)

        self.update = True

        operands = [
            ast.BinOp(self.make_array_index(lbase, lsize, i),
                      type(node.op)(), self.make_array_index(rbase, rsize, i))
            for i in range(max(lsize, rsize))
        ]
        res = ast.Call(path_to_attr(('numpy', 'array')),
                       [ast.Tuple(operands, ast.Load())], [])
        self.aliases[res.func] = {path_to_node(('numpy', 'array'))}
        return res
Beispiel #7
0
    def visit_Name(self, node):
        """
        Replace name with full expanded name.

        Examples
        --------
        >> from numpy.linalg import det

        >> det(a)

        Becomes

        >> numpy.linalg.det(a)
        """
        if node.id in self.symbols:
            symbol = path_to_node(self.symbols[node.id])
            if not getattr(symbol, 'isliteral', lambda: False)():
                parent = self.ancestors[node][-1]
                blacklist = (ast.Tuple, ast.List, ast.Set, ast.Return)
                if isinstance(parent, blacklist):
                    raise PythranSyntaxError(
                        "Unsupported module identifier manipulation", node)
            new_node = path_to_attr(self.symbols[node.id])
            new_node.ctx = node.ctx
            ast.copy_location(new_node, node)
            return new_node
        return node
    def visit_Call(self, node):
        """Replace function call by its correct iterator if it is possible."""
        if node in self.potential_iterator:
            matched_path = self.find_matching_builtin(node)
            if matched_path is None:
                return self.generic_visit(node)

            # Special handling for map which can't be turn to imap with None as
            # a parameter as map(None, [1, 2]) == [1, 2] while
            # list(imap(None, [1, 2])) == [(1,), (2,)]
            if (matched_path[1] == "map" and MODULES["builtins"]["None"]
                    in self.aliases[node.args[0]]):
                return self.generic_visit(node)

            # if a dtype conversion is implied
            if matched_path[1] in ('array', 'asarray') and len(node.args) != 1:
                return self.generic_visit(node)

            path = EQUIVALENT_ITERATORS[matched_path]
            if path:
                node.func = path_to_attr(path)
                self.use_itertools |= path[0] == 'itertools'
            else:
                node = node.args[0]

            self.update = True
        return self.generic_visit(node)
    def inlineFixedSizeArrayCompare(self, node):
        if len(node.comparators) != 1:
            return node

        node_right = node.comparators[0]

        alike = ast.Num, ast.List, ast.Tuple
        if isinstance(node.left, alike) and isinstance(node_right, alike):
            return node

        lbase, lsize = self.fixedSizeArray(node.left)
        rbase, rsize = self.fixedSizeArray(node_right)
        if not lbase or not rbase:
            return node

        if rsize != 1 and lsize != 1 and rsize != lsize:
            raise PythranSyntaxError("Invalid numpy broadcasting", node)

        self.update = True

        operands = [ast.Compare(self.make_array_index(lbase, lsize, i),
                                [type(node.ops[0])()],
                                [self.make_array_index(rbase, rsize, i)])
                    for i in range(max(lsize, rsize))]
        res = ast.Call(path_to_attr(('numpy', 'array')),
                       [ast.Tuple(operands, ast.Load())],
                       [])
        self.aliases[res.func] = {path_to_node(('numpy', 'array'))}
        return res
Beispiel #10
0
 def visit_Call(self, node):
     """ Replace function call by its correct iterator if it is possible."""
     if node in self.potential_iterator:
         match_keyword = self.find_matching_builtin(node)
         if match_keyword:
             node.func = path_to_attr(EQUIVALENT_ITERATORS[match_keyword])
             self.update = True
     return self.generic_visit(node)
Beispiel #11
0
 def visit_Call(self, node):
     """ Replace function call by its correct iterator if it is possible."""
     if node in self.potential_iterator:
         match_keyword = self.find_matching_builtin(node)
         if match_keyword:
             node.func = path_to_attr(EQUIVALENT_ITERATORS[match_keyword])
             self.update = True
     return self.generic_visit(node)
Beispiel #12
0
    def convert(self, node):
        self.update = True

        if isinstance(node, ast.Call):
            if not node.args:
                node = ast.Tuple([])
            else:
                node = node.args[0]
        elif isinstance(node, ast.List):
            node = ast.Tuple(node.elts, ast.Load())

        return ast.Call(path_to_attr(('__builtin__', 'pythran', 'static_list')),
                        [node], [])
    def convert(self, node):
        self.update = True

        if isinstance(node, ast.Call):
            if not node.args:
                node = ast.Tuple([])
            else:
                node = node.args[0]
        elif isinstance(node, ast.List):
            node = ast.Tuple(node.elts, ast.Load())

        return ast.Call(path_to_attr(('__builtin__', 'pythran', 'static_list')),
                        [node], [])
Beispiel #14
0
 def visit_Call(self, node):
     """Replace function call by its correct iterator if it is possible."""
     if node in self.potential_iterator:
         match_keyword = self.find_matching_builtin(node)
         # Special handling for map which can't be turn to imap with None as
         # a parameter as map(None, [1, 2]) == [1, 2] while
         # list(imap(None, [1, 2])) == [(1,), (2,)]
         if (match_keyword == "map" and
                 MODULES["__builtin__"]["None"] in
                 self.aliases[node.args[0]]):
             return self.generic_visit(node)
         if match_keyword:
             node.func = path_to_attr(EQUIVALENT_ITERATORS[match_keyword])
             self.update = True
     return self.generic_visit(node)
Beispiel #15
0
    def inlineFixedSizeArrayUnaryOp(self, node):

        if isinstance(node.operand, (ast.Num, ast.List, ast.Tuple)):
            return node

        base, size = self.fixedSizeArray(node.operand)
        if not base:
            return node

        self.update = True

        operands = [
            ast.UnaryOp(type(node.op)(), self.make_array_index(base, size, i))
            for i in range(size)
        ]
        res = ast.Call(path_to_attr(('numpy', 'array')),
                       [ast.Tuple(operands, ast.Load())], [])
        self.aliases[res.func] = {path_to_node(('numpy', 'array'))}
        return res
Beispiel #16
0
    def visit_Call(self, node):
        """Replace function call by its correct iterator if it is possible."""
        if node in self.potential_iterator:
            matched_path = self.find_matching_builtin(node)
            if matched_path is None:
                return self.generic_visit(node)

            # if any kind of specific (~ with more arg) behavior is required
            if len(node.args) != 1:
                return self.generic_visit(node)

            path = EQUIVALENT_ITERATORS[matched_path]
            if path:
                node.func = path_to_attr(path)
            else:
                node = node.args[0]

            self.update = True
        return self.generic_visit(node)
    def inlineFixedSizeArrayUnaryOp(self, node):

        if isinstance(node.operand, (ast.Num, ast.List, ast.Tuple)):
            return node

        base, size = self.fixedSizeArray(node.operand)
        if not base:
            return node

        self.update = True

        operands = [ast.UnaryOp(type(node.op)(),
                                self.make_array_index(base, size, i))
                    for i in range(size)]
        res = ast.Call(path_to_attr(('numpy', 'array')),
                       [ast.Tuple(operands, ast.Load())],
                       [])
        self.aliases[res.func] = {path_to_node(('numpy', 'array'))}
        return res
Beispiel #18
0
    def visit_Name(self, node):
        """
        Replace name with full expanded name.

        Examples
        --------
        >> from numpy.linalg import det

        >> det(a)

        Becomes

        >> numpy.linalg.det(a)
        """
        if node.id in self.symbols:
            new_node = path_to_attr(self.symbols[node.id])
            new_node.ctx = node.ctx
            ast.copy_location(new_node, node)
            return new_node
        return node
Beispiel #19
0
    def visit_Name(self, node):
        """
        Replace name with full expanded name.

        Examples
        --------
        >> from numpy.linalg import det

        >> det(a)

        Becomes

        >> numpy.linalg.det(a)
        """
        if node.id in self.symbols:
            new_node = path_to_attr(self.symbols[node.id])
            new_node.ctx = node.ctx
            ast.copy_location(new_node, node)
            return new_node
        return node
Beispiel #20
0
 def visit_List(self, node):
     # because global lists in pythran are static lists
     return ast.Call(
         path_to_attr(('builtins', 'pythran', 'static_list')),
         [ast.Tuple([self.visit(elt)
                     for elt in node.elts], ast.Load())], [])