Ejemplo n.º 1
0
    def can_use_c_for(self, node):
        """
        Check if a for loop can use classic C syntax.

        To use C syntax:
            - target should not be assign in the loop
            - range should be use as iterator
            - order have to be known at compile time
        """
        assert isinstance(node.target, ast.Name)
        pattern_range = ast.Call(func=ast.Attribute(value=ast.Name(
            'builtins', ast.Load(), None, None),
                                                    attr='range',
                                                    ctx=ast.Load()),
                                 args=AST_any(),
                                 keywords=[])
        is_assigned = set()
        for stmt in node.body:
            is_assigned.update({n.id for n in self.gather(IsAssigned, stmt)})

        nodes = ASTMatcher(pattern_range).search(node.iter)
        if node.iter not in nodes or node.target.id in is_assigned:
            return False

        args = node.iter.args
        if len(args) < 3:
            return True
        if isnum(args[2]):
            return True
        return False
Ejemplo n.º 2
0
    def can_use_c_for(self, node):
        """
        Check if a for loop can use classic C syntax.

        To use C syntax:
            - target should not be assign in the loop
            - xrange should be use as iterator
            - order have to be known at compile time
        """
        assert isinstance(node.target, ast.Name)
        pattern = ast.Call(func=ast.Attribute(value=ast.Name(id='__builtin__',
                                                             ctx=ast.Load(),
                                                             annotation=None),
                                              attr='xrange',
                                              ctx=ast.Load()),
                           args=AST_any(),
                           keywords=[])
        is_assigned = {node.target.id: False}
        [
            is_assigned.update(self.passmanager.gather(IsAssigned, stmt))
            for stmt in node.body
        ]

        if (node.iter not in ASTMatcher(pattern).search(node.iter)
                or is_assigned[node.target.id]):
            return False

        args = node.iter.args
        if len(args) < 3:
            return True
        if isinstance(args[2], ast.Num):
            return True
        return False
Ejemplo n.º 3
0
    def generic_visit(self, node):
        if isinstance(node, ast.expr) and node in self.constant_expressions:
            fake_node = ast.Expression(node)
            code = compile(ast.gast_to_ast(fake_node),
                           '<constant folding>', 'eval')
            try:
                value = eval(code, self.env)
                new_node = to_ast(value)
                if not ASTMatcher(node).match(new_node):
                    self.update = True
                    return new_node
            except DamnTooLongPattern as e:
                print("W: ", e, " Assume no update happened.")
            except ConversionError as e:
                print('error in constant folding: ', e)
                raise
            except ToNotEval:
                pass
            except AttributeError as e:
                # this may miss a few optimization
                logger.info('During constant folding, bailing out due to: ' +
                            e.args[0])
            except NameError as e:
                # FIXME dispatched function are not processed by constant
                # folding
                if "__dispatch__" in e.args[0]:
                    return Transformation.generic_visit(self, node)
                # this may miss a few optimization
                logger.info('During constant folding, bailing out due to: ' +
                            e.args[0])
            except Exception as e:
                raise PythranSyntaxError(str(e), node)

        return Transformation.generic_visit(self, node)
Ejemplo n.º 4
0
    def can_use_c_for(self, node):
        """
        Check if a for loop can use classic C syntax.

        To use C syntax:
            - target should not be assign in the loop
            - xrange should be use as iterator
            - order have to be known at compile time
        """
        assert isinstance(node.target, ast.Name)
        if sys.version_info.major == 3:
            range_name = 'range'
        else:
            range_name = 'xrange'
        pattern_range = ast.Call(func=ast.Attribute(value=ast.Name(
            id='__builtin__', ctx=ast.Load(), annotation=None),
                                                    attr=range_name,
                                                    ctx=ast.Load()),
                                 args=AST_any(),
                                 keywords=[])
        is_assigned = set()
        for stmt in node.body:
            is_assigned.update(self.gather(IsAssigned, stmt))

        nodes = ASTMatcher(pattern_range).search(node.iter)
        if node.iter not in nodes or node.target.id in is_assigned:
            return False

        args = node.iter.args
        if len(args) < 3:
            return True
        if isinstance(args[2], ast.Num):
            return True
        return False
Ejemplo n.º 5
0
 def generic_visit(self, node):
     if node in self.constant_expressions:
         try:
             fake_node = ast.Expression(
                 node.value if isinstance(node, ast.Index) else node)
             code = compile(ast.gast_to_ast(fake_node),
                            '<constant folding>', 'eval')
             value = eval(code, self.env)
             new_node = to_ast(value)
             if(isinstance(node, ast.Index) and
                not isinstance(new_node, ast.Index)):
                 new_node = ast.Index(new_node)
             try:
                 if not ASTMatcher(node).search(new_node):
                     self.update = True
                     return new_node
             except DamnTooLongPattern as e:
                 print("W: ", e, " Assume no update happened.")
             return Transformation.generic_visit(self, node)
         except ConversionError as e:
             print('error in constant folding: ', e)
             raise
         except ToNotEval:
             return Transformation.generic_visit(self, node)
         except AttributeError as e:
             # FIXME union_ function is not handle by constant folding
             if "union_" in e.args[0]:
                 return Transformation.generic_visit(self, node)
             elif "pythran" in e.args[0]:
                 # FIXME: Can be fix giving a Python implementation for
                 # these functions.
                 return Transformation.generic_visit(self, node)
             raise
         except NameError as e:
             # FIXME dispatched function are not processed by constant
             # folding
             if "__dispatch__" in e.args[0]:
                 return Transformation.generic_visit(self, node)
             raise
         except Exception as e:
             raise PythranSyntaxError(str(e), node)
     else:
         return Transformation.generic_visit(self, node)