def visit_Lambda(self, n: ast3.Lambda) -> FuncExpr: body = ast3.Return(n.body) body.lineno = n.lineno body.col_offset = n.col_offset return FuncExpr(self.transform_args(n.args, n.lineno), self.as_block([body], n.lineno))
def visit_Lambda(self, n: ast3.Lambda) -> LambdaExpr: body = ast3.Return(n.body) body.lineno = n.lineno body.col_offset = n.col_offset e = LambdaExpr(self.transform_args(n.args, n.lineno), self.as_required_block([body], n.lineno)) e.set_line( n.lineno, n.col_offset) # Overrides set_line -- can't use self.set_line return e
def visit_ListComp(self, node): from parser.functions import FunctionImplementation # calculate result type if len(node.generators) > 1: raise InvalidOperation( "Only one for statement permitted in comprehensions") comp = node.generators[0] if len(comp.ifs) > 1: raise InvalidOperation( "Only one if statement allowed in List Comprehension") assign_node = ast.Assign(targets=[comp.target], value=ast.Subscript(value=comp.iter, slice=ast.Index( ast.Num(0)))) return_node = ast.Return(value=node.elt) function_node = ast.FunctionDef(name="temp", args=ast.arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[assign_node, return_node]) function_interpreter = FunctionImplementation(function_node, (), self.context) result_type = TypeDB.get_list([function_interpreter.retval.tp]) # create temp list to hold values result = self.context.get_temp_var(result_type) self.prepends.append( f"{result.code} = {result_type.as_literal([])};\n") # create for expression append_node = ast.Expr( ast.Call(func=ast.Attribute(value=ast.Name(id=result.code, ctx=ast.Load()), attr="append", ctx=ast.Load()), args=[node.elt], keywords=[])) if comp.ifs: body = ast.If(test=comp.ifs[0], body=[append_node], orelse=[]) else: body = append_node for_node = ast.For(target=comp.target, iter=comp.iter, body=[body], orelse=[]) self.prepends.append(for_node) return result
def _inline_call_in_return(self, return_stmt): call = return_stmt.value assert self._is_valid_target_for_inlining(call) replacers = [] replacers += create_name_replacers(self._inlined_args, call.args) inlined = self._inline_call(call, replacers) last_statement = inlined[-2] if self._verbose \ else (inlined[-1] if isinstance(inlined, list) else inlined) if not isinstance(last_statement, typed_ast3.Return): if not isinstance(inlined, list): inlined = [inlined] inlined += [typed_ast3.Return(value=None)] return inlined
def visit_While(self, node: ast3.While) -> VisitorOutput: """Transforms an if statement into what Pytropos understands: For example, it converts:: while question: body into:: if_qstn = TRANSFORMED(question) def while_qst(st): return question def while_(st): body return st st = pt.runWhile(st, while_qstn, while_) """ if node.orelse: raise AstTransformerError( f"Pytropos doesn't support else statement in while loop yet, sorry :(" ) self.generic_visit(node) new_body = node.body.copy() new_body.append( ast3.Return(value=ast3.Name(id='st', ctx=ast3.Load()), )) new_node = [ ast3.FunctionDef( name='while_qst', args=ast3.arguments(args=[ast3.arg(arg='st', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ast3.Return(value=node.test)], decorator_list=[], returns=None, ), ast3.FunctionDef( name='while_', args=ast3.arguments(args=[ast3.arg(arg='st', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=new_body, decorator_list=[], returns=None, ), ast3.Assign(targets=[ast3.Name(id='st', ctx=ast3.Store())], value=ast3.Call( func=ast3.Attribute( value=ast3.Name(id='pt', ctx=ast3.Load()), attr='runWhile', ctx=ast3.Load(), ), args=[ ast3.Name(id='st', ctx=ast3.Load()), ast3.Name(id='while_qst', ctx=ast3.Load()), ast3.Name(id='while_', ctx=ast3.Load()) ], keywords=[], )) ] return new_node # type: ignore
def visit_If(self, node: ast3.If) -> VisitorOutput: """Transforms an if statement into what Pytropos understands: For example, it converts:: if question: body1 else: body2 into:: if_qstn = TRANSFORMED(question) def if_(st): body1 return st def else_(st): body2 return st st = pt.runIf(st, if_qstn, if_, else_) """ self.generic_visit(node) new_body = node.body.copy() new_orelse = node.orelse.copy() orelse = bool(node.orelse) new_body.append( ast3.Return(value=ast3.Name(id='st', ctx=ast3.Load()), )) new_node = [ ast3.Assign(targets=[ast3.Name(id='if_qstn', ctx=ast3.Store())], value=node.test), ast3.FunctionDef( name='if_', args=ast3.arguments(args=[ast3.arg(arg='st', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=new_body, decorator_list=[], returns=None, ), ] if orelse: # adding "return st" new_orelse.append( ast3.Return(value=ast3.Name(id='st', ctx=ast3.Load()), )) new_node.append( ast3.FunctionDef( name='else_', args=ast3.arguments( args=[ast3.arg(arg='st', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=new_orelse, decorator_list=[], returns=None, )) new_node.append( ast3.Assign(targets=[ast3.Name(id='st', ctx=ast3.Store())], value=ast3.Call( func=ast3.Attribute( value=ast3.Name(id='pt', ctx=ast3.Load()), attr='runIf', ctx=ast3.Load(), ), args=[ ast3.Name(id='st', ctx=ast3.Load()), ast3.Name(id='if_qstn', ctx=ast3.Load()), ast3.Name(id='if_', ctx=ast3.Load()), ast3.Name(id='else_', ctx=ast3.Load()) ] if orelse else [ ast3.Name(id='st', ctx=ast3.Load()), ast3.Name(id='if_qstn', ctx=ast3.Load()), ast3.Name(id='if_', ctx=ast3.Load()) ], keywords=[], ))) return new_node # type: ignore
def visit_Return(self, node) -> typed_ast3.Return: # pylint: disable=invalid-name expr = self.visit(node.expr) assert isinstance(expr, typed_ast3.AST) _ = self.visit(node.coord) return typed_ast3.Return(value=expr)