def test_For(self): got = ast.For(None, None, self.simple_stmt(), self.simple_stmt()) want = ast.For(None, None, self.simple_stmt(), []) self.check_transform(got, want) got = ast.For(None, None, self.fancy_stmts(), self.fancy_stmts()) want = ast.For(None, None, [self.func], [self.func]) self.check_transform(got, want)
def visit_For(self, node): #in testing:) #add more convincing junk for loop(random choice of a few seemingly important code lines that dont do anything) fortarget = self.visit( ast.Name(id=''.join([ random.choice(string.ascii_letters) for i in range(random.randint(3, 8)) ]), ctx=ast.Load)) junkfor = [ ast.Assign(targets=[self.visit(node.target)], ctx=ast.Store(), value=self.visit( ast.Num(n=id(''.join([ random.choice(string.ascii_letters) for i in range(random.randint(3, 8)) ]))))), ast.If(test=ast.Compare(left=self.visit(node.target), ops=[ast.Eq()], comparators=[ ast.Call(func=ast.Name(id='id', ctx=ast.Load()), args=[fortarget], keywords=[], starargs=None, kwargs=None) ]), body=[ ast.Assign(targets=[self.visit(node.target)], ctx=ast.Store(), value=ast.BinOp(left=self.visit(node.target), op=ast.Sub(), right=self.visit( ast.Num(n=1)))), ast.Assign(targets=[fortarget], ctx=ast.Store(), value=ast.BinOp(left=self.visit(node.target), op=ast.Add(), right=self.visit( node.target))) ], orelse=[]) ] return ast.For( target=fortarget, iter=ast.Call( func=ast.Name(id='range', ctx=ast.Load()), args=[self.visit(ast.Num(n=random.randint(10, 100)))], keywords=[], starargs=None, kwargs=None), body=junkfor, orelse=[ ast.For(target=self.visit(node.target), iter=self.visit(node.iter), body=[self.visit(i) for i in node.body], orelse=[self.visit(i) for i in node.orelse]) ])
def test_empty_For(self): for_ = ast.For(ast.Name('X', ast.Store()), ast.Str('a'), [], []) self._test_empty_body(for_) # An empty 'else' clause should just go away for_else = ast.For(ast.Name('X', ast.Store()), ast.Str('a'), [ast.Pass()], [ast.Pass()]) expect = ast.For(ast.Name('X', ast.Store()), ast.Str('a'), [ast.Pass()], []) self.check_transform(for_else, expect)
def test_for(self): x = ast.Name("x", ast.Store()) y = ast.Name("y", ast.Load()) p = ast.Pass() self.stmt(ast.For(x, y, [], []), "empty body on For") self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []), "must have Store context") self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []), "must have Load context") e = ast.Expr(ast.Name("x", ast.Store())) self.stmt(ast.For(x, y, [e], []), "must have Load context") self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
def p_iteration_statement_3(self, p): """ iteration_statement \ : FOR LPAREN expr_noin_opt SEMI expr_opt SEMI expr_opt RPAREN \ statement | FOR LPAREN VAR variable_declaration_list_noin SEMI expr_opt SEMI\ expr_opt RPAREN statement """ if len(p) == 10: p[0] = ast.For(init=p[3], cond=p[5], count=p[7], statement=p[9]) else: init = ast.VarStatement(p[4]) p[0] = ast.For(init=init, cond=p[6], count=p[8], statement=p[10])
def parse_generator(nodes): """Transform the generator into a for loop. """ node = nodes[0] tempnode = ast.For() tempnode.target = node.target tempnode.iter = node.iter if len(nodes) == 1: append_node = ast.parse("%s.append(foo)" % iden).body[0] append_node.value.args[0] = elt body = [append_node] else: body = [parse_generator(nodes[1:])] if len(node.ifs) == 1: ifnode = _ast.If(test=node.ifs[0], body=body, orelse=[]) tempnode.body = [ifnode] elif len(node.ifs) > 1: ifnode = _ast.If(test=_ast.BoolOp(op=_ast.And(), values=node.ifs), body=body, orelse=[]) tempnode.body = [ifnode] else: tempnode.body = body tempnode.orelse = None return tempnode
def compile_for_expression(self, expression): with self.is_returnable(False): expression.pop(0) # for name, iterable = expression.pop(0) target = self._storeize(self.compile_symbol(name)) orelse = [] # (foreach [] body (else …)) if expression and expression[-1][0] == HySymbol("else"): else_expr = expression.pop() if len(else_expr) > 2: raise HyTypeError( else_expr, "`else' statement in `foreach' is too long") elif len(else_expr) == 2: orelse = self._code_branch(self.compile(else_expr[1]), else_expr[1].start_line, else_expr[1].start_column) ret = ast.For(lineno=expression.start_line, col_offset=expression.start_column, target=target, iter=self.compile(iterable), body=self._code_branch( [self.compile(x) for x in expression], expression.start_line, expression.start_column), orelse=orelse) return ret
def p_loop_stmt(t): #'''stmt : expression IDENTIFIER IDENTIFIER IDENTIFIER LOOP suite''' #use_loop_before = False '''stmt : LOOP expression IDENTIFIER IDENTIFIER IDENTIFIER suite''' use_loop_before = True if use_loop_before: container, 의, variable, 마다, suite = t[2], t[3], t[4], t[5], t[6] container_idx = 2 variable_idx = 4 else: container, 의, variable, 마다, suite = t[1], t[2], t[3], t[4], t[6] container_idx = 1 variable_idx = 3 if 의 != '의' or 마다 != '마다': if use_loop_before: report_error(t, "구문 오류입니다: 반복 {} {} {}".format(의, variable, 마다)) else: report_error(t, "구문 오류입니다: {} {} {} 반복".format(의, variable, 마다)) report_error(t, "\t'~ 의 ~ 마다 반복' 꼴이어야 합니다.") raise SyntaxError for_var = ast.Name(variable, ast.Store()) for_var.lineno = t.lineno(variable_idx) for_var.col_offset = -1 # XXX t[0] = ast.For(for_var, container, suite, []) t[0].lineno = t.lineno(container_idx) t[0].col_offset = -1 # XXX
def visit_For(self, node): super().generic_visit(node) # TODO: Support attributes if isinstance(node.iter, ast.Name) or ((isinstance(node.iter, ast.List) or isinstance(node.iter, ast.Tuple)) and not (all(isinstance(item, ast.Num) for item in node.iter.elts) or all(isinstance(item, ast.Str) for item in node.iter.elts))): targets = node.target.elts if hasattr(node.target, 'elts') else [node.target] indexator = self.get_unique_iter_target() set_targets = [ ast.Assign( targets=[t], value=ast.Subscript( value=ast.Subscript(value=node.iter, slice=ast.Index(value=ast.Name(id=indexator))), slice=ast.Index(value=ast.Num(n=i)) ) ) for i, t in enumerate(targets) ] return ast.For( target=indexator, iter=ast.Call( func=ast.Name(id='range'), args=[ast.Call( func=ast.Name(id='len'), args=node.iter )] ), body=set_targets + node.body ) return node
def visit_SetComp_Rec( self, generators: List[Type[ast.AST]]) -> List[Type[ast.AST]]: if not generators: self.generic_visit(self.setCompReg[1].elt ) # the location of the node may be wrong if self.setCompReg[0]: return [ ast.Expr(value=ast.Call(func=ast.Attribute(value=ast.Name( id=self.setCompReg[0], ctx=ast.Load()), attr='add', ctx=ast.Load()), args=[self.setCompReg[1].elt], keywords=[])) ] else: # not supported yet return [ast.Expr(value=self.setCompReg[1].elt)] else: return [ ast.For( target=generators[-1].target, iter=generators[-1].iter, body=[ ast.If(test=self.combine_conditions( generators[-1].ifs), body=self.visit_SetComp_Rec(generators[:-1]), orelse=[]) ] if generators[-1].ifs else self.visit_SetComp_Rec( generators[:-1]), orelse=[]) ]
def generate(self, element: Element, GC: GenerationContext): self.precheck(element, GC) acode = element.code target_iter_element = acode[1] target_element = target_iter_element.code[0] iter_element = target_iter_element.code[1] with GC.let(domain=LValueDomain): target_code = GC.generate(target_element) with GC.let(domain=ExpressionDomain): iter_code = GC.generate(iter_element) if is_form(acode.last, "else"): raise NotImplementedError() body_codes = [] for e in acode[2:]: extend_body(body_codes, GC.generate(e)) return ast.For( target=target_code, iter=iter_code, body=body_codes, orelse=[], )
def visit_DictComp_Rec( self, generators: List[Type[ast.AST]]) -> List[Type[ast.AST]]: if not generators: if self.dictCompReg[ 0]: # bug if there is else statement in comprehension return [ ast.Assign(targets=[ ast.Subscript( value=ast.Name(id=self.dictCompReg[0], ctx=ast.Load()), slice=ast.Index(value=self.dictCompReg[1].key), ctx=ast.Store()) ], value=self.dictCompReg[1].value) ] # else: # not supported yet # return [ast.Expr(value=self.dictCompReg[1].elt)] else: return [ ast.For( target=generators[-1].target, iter=generators[-1].iter, body=[ ast.If(test=self.combine_conditions( generators[-1].ifs), body=self.visit_DictComp_Rec(generators[:-1]), orelse=[]) ] if generators[-1].ifs else self.visit_DictComp_Rec( generators[:-1]), orelse=[]) ]
def simplify_list_comp( comp: t.Union[ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp], new_stmts: t.List[ast.stmt], init: ast.expr, appender_attr: str, ) -> ast.Name: rewriter = NameRewriter() for gen in comp.generators: rewriter.visit(gen.target) res_load, res_store = gensym() res_stmts: t.List[ast.stmt] = [] if isinstance(comp, ast.DictComp): rewriter.visit(comp.key) rewriter.visit(comp.value) key = SimplifyExpr(res_stmts).visit(comp.key) value = SimplifyExpr(res_stmts).visit(comp.value) res_stmts.append( ast.Assign(targets=[ ast.Subscript(value=c.deepcopy(res_load), slice=ast.Index(value=key), ctx=ast.Store()) ], value=value)) else: rewriter.visit(comp.elt) comp.elt = SimplifyExpr(res_stmts).visit(comp.elt) res_stmts.append( ast.Expr(value=ast.Call( func=ast.Attribute(value=c.deepcopy(res_load), attr=appender_attr, ctx=ast.Load()), args=[comp.elt], keywords=[], ))) for gen in reversed(comp.generators): new_loop: t.Union[ast.For, ast.AsyncFor] if hasattr(gen, 'is_async') and gen.is_async: # type: ignore new_loop = ast.AsyncFor(target=gen.target, orelse=[]) else: new_loop = ast.For(target=gen.target, orelse=[]) body: t.List[ast.stmt] = [] new_loop.iter = SimplifyExpr(body).visit(gen.iter) for cond in reversed(gen.ifs): res_stmts = [ast.If(test=cond, body=res_stmts, orelse=[])] new_loop.body = res_stmts body.append(new_loop) res_stmts = body new_stmts.append(ast.Assign( targets=[res_store], value=init, )) new_stmts.extend(res_stmts) return res_load
def _visit_ForTiered(self, node): var, N, n_inner = self.unroll_in_tiers n_outer = math.floor(N / n_inner) outer_iterable = range(0, n_inner * n_outer, n_inner) inner_iterable = list(range(n_inner)) remainder_iterable = list(range(N % n_inner)) if n_inner > N // 2: node.iter = make_ast_from_literal(list(range(N))) return self._visit_ForFlat(node) inner_node = ast.For(iter=make_ast_from_literal(inner_iterable), target=node.target, body=node.body, orelse=[]) inner_node = self._visit_ForFlat(inner_node, offset='PRAGMA_iouter') remainder_node = ast.For( iter=make_ast_from_literal(remainder_iterable), target=node.target, body=node.body, orelse=[]) remainder_node = self._visit_ForFlat(remainder_node, offset=n_outer * n_inner) ast_range_fun = ast.Name(id='range', ctx=ast.Load()) ast_range_args = [ ast.Num(outer_iterable.start), ast.Num(outer_iterable.stop), ast.Num(outer_iterable.step) ] ast_range_call = ast.Call(func=ast_range_fun, args=ast_range_args, keywords=[]) outer_node = ast.For(iter=ast_range_call, target=ast.Name(id='PRAGMA_iouter', ctx=ast.Store()), body=inner_node, orelse=[]) if isinstance(remainder_node, list): return [outer_node] + remainder_node elif remainder_node is None: return outer_node else: return [outer_node, remainder_node]
def p_iteration_statement(self, p): """ iteration_statement : WHILE LPAREN expression RPAREN statement | FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN statement | FOR LPAREN declaration expression_opt SEMI expression_opt RPAREN statement """ if len(p) == 6: p[0] = ast.While(p[3], p[5], coord=self._token_coord(p, 1)) elif len(p) == 10: p[0] = ast.For(p[3], p[5], p[7], p[9], coord=self._token_coord(p, 1)) else: p[0] = ast.For( ast.DeclList(p[3], coord=self._token_coord(p, 1)), p[4], p[6], p[8], coord=self._token_coord(p, 1), )
def visit_For(self, node): new_node = ast.For( self._visit(node.target), self._visit(node.iter), self._visit(node.body), self._visit(node.orelse), ) return ast.copy_location(new_node, node)
def reverse_loop(for_node): assert isinstance(for_node, ast.For) iter_node = for_node.iter new_iter_node = NewCall(func=ast.Name(id="reversed"), args=[iter_node]) return ast.For(target=for_node.target, iter=new_iter_node, body=for_node.body)
def p_for_statement(p): ''' for_statement : FOR LPAREN ID IN expr RPAREN statement ''' if DEBUG: print("\nfor stmt: ", end="") for i in range(len(p)): print(i, " ", p[i], " ", end="") p[0] = ast.For(ast.ID(p[3]), p[5], p[7])
def test_for_0_args(self): py_ast = ast.For( ast.Name("i", ast.Load()), ast.Call(ast.Name("range", ast.Load()), [], [], None, None), [ast.Name("foo", ast.Load())], [], ) with self.assertRaises(Exception): self._check(py_ast, None)
def python_ast(self): return ast.For(ast.Name(self.var, ast.Store(), lineno=self.line, col_offset=self.column), self.sequence.python_ast(), self.instructions.python_ast(), [], lineno=self.line, col_offset=self.column)
def visit_ForNode(self, node): self.names.append(node.name) iter_ = ast.Name(id=node.name, ctx=ast.Load()) target = ast.Name(id=node.target, ctx=ast.Store()) body = list(self.visit(x) for x in node.value) if node.target in self.names: del self.names[self.names.index(node.target)] orelse = [] return ast.For(target=target, iter=iter_, body=body, orelse=orelse)
def visitFor(self, n, *args): # We need to guard the internal body of for loops to make sure that the iteration target has the expected type. prots = self.destruct_to_checks(n.target) return ast.For(target=self.dispatch(n.target, *args), iter=self.dispatch(n.iter, *args), body=prots + self.dispatch_statements(n.body, *args), orelse=self.dispatch_statements(n.orelse, *args), lineno=n.lineno, col_offset=n.col_offset)
def gen_loop_nest(body, loop_vars, loop_ranges): for var, _range in zip(loop_vars, loop_ranges): if sys.version_info >= (3, 5): body = [ ast.For( ast.Name(var, ast.Store()), ast.Call(ast.Name("range", ast.Load()), [ast.Num(_range)], []), body, []) ] else: body = [ ast.For( ast.Name(var, ast.Store()), ast.Call(ast.Name("range", ast.Load()), [ast.Num(_range)], [], None, None), body, []) ] # body = [ast.For(ast.Name(var, ast.Store()), # ast.Call(ast.Name("range", ast.Load()), [ast.Num(_range[0]), ast.Num(_range[1])], []), body, [])] return body[0]
def add_set_call(self, external_function_name, variable_name_arg_and_trg, targets_ids): self.body.append(ast.For(target=ast.Name(id='i', ctx=ast.Store()), iter=ast.Call(func=ast.Name(id='range', ctx=ast.Load()), args= [ast.Constant(value=len(variable_name_arg_and_trg))], keywords=[]), body=[self._generate_set_call_body(external_function_name, len(variable_name_arg_and_trg[0]), self.variable_names[ variable_name_arg_and_trg[0][0]], targets_ids)], orelse=[], lineno=0))
def inner(*results_initializer: ast.AST) -> CStatements: # for i in range(length): return VectorCallable( Statement( ast.For( ast.Name(index_id.name, ast.Store()), range_expr, [set_result, *results_initializer, set_array], [], )))
def visit_ListComp(self, t): result_append = ast.Attribute(ast.Name('.0', load), 'append', load) body = ast.Expr(Call(result_append, [t.elt])) for loop in reversed(t.generators): for test in reversed(loop.ifs): body = ast.If(test, [body], []) body = ast.For(loop.target, loop.iter, [body], []) fn = [body, ast.Return(ast.Name('.0', load))] args = ast.arguments([ast.arg('.0', None)], None, [], None, [], []) return Call(Function('<listcomp>', args, fn), [ast.List([], load)])
def genIterateCollectionLoop(listVar: ast.Attribute, iterVarName: str, yieldBody: ast.Attribute) -> ast.For: res = ast.For( target=ast.Name(id=iterVarName, ctx=ast.Store()), iter=genIterateListCall(listVar), body=[ast.Expr(value=ast.Yield(value=yieldBody))], orelse=[], type_comment=None, ) return res
def make_for(): """For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)""" return ast.For( target=make_expression(ctx=ast.Store()), iter=make_expression(), body=[make_statement()], # TODO: Add a way of creating the orelse orelse=[], type_comment=None)
def test_For(self): for_ = ast.For(ast.Name('target', ast.Load()), ast.Name('iter_', ast.Load()), [ast.Pass()], []) self.verify(for_, 'for target in iter_:pass') for_.orelse = [ast.Pass()] self.verify(for_, 'for target in iter_:pass\nelse:pass') for_.target = ast.Tuple( [ast.Name('X', ast.Store()), ast.Name('Y', ast.Store())], ast.Store()) for_.orelse = [] self.verify(for_, 'for X,Y in iter_:pass')
def visit_For(self, node): new_body = self.if_exists(node.body, self.visit_list) new_orelse = self.if_exists(node.orelse, self.visit_list) new_target = self.visit(node.target) new_iter = self.visit(node.iter) return_list = self.new_stmts + [ ast.copy_location( ast.For(new_target, new_iter, new_body, new_orelse), node) ] self.new_stmts.clear() return return_list