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
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
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)
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
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)