def visit_BinOp(self, node): node = self.generic_visit(node) if not isinstance(node.op, ast.Mod): return node right_range = self.range_values[node.right] left_range = self.range_values[node.left] if right_range.low < 0 or isinf(right_range.high): return node if left_range.low < -right_range.low: return node if left_range.high > right_range.high * 2: return node cleft0, cleft1 = deepcopy(node.left), deepcopy(node.left) cright = deepcopy(node.right) self.update = True return ast.IfExp(ast.Compare(node.left, [ast.Lt()], [node.right]), cleft0, ast.BinOp(cleft1, ast.Sub(), cright))
ast.Call(func=ast.Attribute(value=ast.Name(id='__builtin__', ctx=ast.Load(), annotation=None), attr="xrange", ctx=ast.Load()), args=[Placeholder(0)], keywords=[]) ], keywords=[]), lambda: ast.Call(func=ast.Attribute(value=ast.Name( id='__builtin__', ctx=ast.Load(), annotation=None), attr="xrange", ctx=ast.Load()), args=[ ast.BinOp(left=Placeholder(0), op=ast.Sub(), right=ast.Num(n=1)), ast.Num(n=-1), ast.Num(n=-1) ], keywords=[])), # X * X => X ** 2 (ast.BinOp(left=Placeholder(0), op=ast.Mult(), right=Placeholder(0)), lambda: ast.BinOp(left=Placeholder(0), op=ast.Pow(), right=ast.Num(n=2))), # a + "..." + b => "...".join((a, b)) (ast.BinOp(left=ast.BinOp(left=Placeholder(0), op=ast.Add(), right=ast.Str(Placeholder(1))), op=ast.Add(),
def visit_BinOp(self, node): if isinstance(node.op, gast.Add): node.op = gast.Sub() return self.generic_visit(node)
def visit_BinOp(self, node): if not isinstance(node.op, ast.Mod): return self.generic_visit(node) # check that right is a name defined once outside of loop # TODO: handle expression instead of names if not isinstance(node.right, ast.Name): return self.generic_visit(node) right_def = self.single_def(node.right) if not right_def: return self.generic_visit(node) if self.range_values[node.right.id].low < 0: return self.generic_visit(node) # same for lhs if not isinstance(node.left, ast.Name): return self.generic_visit(node) head = self.single_def(node.left) if not head: return self.generic_visit(node) # check lhs is the actual index of a loop head = head['name'] loop = self.ancestors[head][-1] if not isinstance(loop, ast.For): return self.generic_visit(node) if not isinstance(loop.iter, ast.Call): return self.generic_visit(node) # make sure rhs is defined out of the loop if loop in self.ancestors[right_def['name']]: return self.generic_visit(node) # gather range informations range_ = None for alias in self.aliases[loop.iter.func]: if alias is MODULES['__builtin__']['range']: range_ = alias elif alias is MODULES['__builtin__']['xrange']: range_ = alias else: break if range_ is None: return self.generic_visit(node) # everything is setup for the transformation! new_id = node.left.id + '_m' i = 0 while new_id in self.identifiers: new_id = '{}_m{}'.format(node.left.id, i) i += 1 rargs = range_.args.args lower = rargs[0] if len(rargs) > 1 else ast.Num(0) header = ast.Assign([ast.Name(new_id, ast.Store(), None)], ast.BinOp( ast.BinOp(deepcopy(lower), ast.Sub(), ast.Num(1)), ast.Mod(), deepcopy(node.right))) incr = ast.BinOp(ast.Name(new_id, ast.Load(), None), ast.Add(), ast.Num(1)) step = ast.Assign([ast.Name(new_id, ast.Store(), None)], ast.IfExp( ast.Compare(incr, [ast.Eq()], [deepcopy(node.right)]), ast.Num(0), deepcopy(incr))) self.loops_mod.setdefault(loop, []).append((header, step)) self.update = True return ast.Name(new_id, ast.Load(), None)
ctx=ast.Load(), annotation=None), attr="reversed", ctx=ast.Load()), args=[ast.Call( func=ast.Attribute( value=ast.Name(id='__builtin__', ctx=ast.Load(), annotation=None), attr="xrange", ctx=ast.Load()), args=[Placeholder(0)], keywords=[])], keywords=[]), lambda: ast.Call( func=ast.Attribute(value=ast.Name(id='__builtin__', ctx=ast.Load(), annotation=None), attr="xrange", ctx=ast.Load()), args=[ast.BinOp(left=Placeholder(0), op=ast.Sub(), right=ast.Num(n=1)), ast.Num(n=-1), ast.Num(n=-1)], keywords=[])), # X * X => X ** 2 (ast.BinOp(left=Placeholder(0), op=ast.Mult(), right=Placeholder(0)), lambda: ast.BinOp(left=Placeholder(0), op=ast.Pow(), right=ast.Num(n=2))), # a + "..." + b => "...".join((a, b)) (ast.BinOp(left=ast.BinOp(left=Placeholder(0), op=ast.Add(), right=ast.Str(Placeholder(1))), op=ast.Add(), right=Placeholder(2)), lambda: ast.Call(func=ast.Attribute( ast.Attribute(