def visit_FunctionDef(self, node): args = node.args if not args.defaults: return node orig_id = node.name node.name = self.id_factory(orig_id) parameters = mk_tuple(mk_str(arg.id) for arg in args.args) defaults = mk_tuple(args.defaults) parameters_id = self.id_factory("tuple") parameters_stmt = mk_assign(parameters_id, parameters) parameters = mk_name(parameters_id) defaults_id = self.id_factory("tuple") default_stmt = mk_assign(defaults_id, defaults) defaults = mk_name(defaults_id) args.defaults = [] func_expr = mk_call("__pydron_defaults__", [mk_name(node.name), parameters, defaults]) assign_stmt = mk_assign(orig_id, func_expr) return [node, parameters_stmt, default_stmt, assign_stmt]
def visit_FunctionDef(self, node): self.generic_visit(node) scopes = node.scopes shared = [var for var,scope in scopes.iteritems() if scope == scoping.Scope.SHARED] free = [var for var,scope in scopes.iteritems() if scope == scoping.Scope.FREE] # create cells first thing in body shared_stmts = [mk_assign(var, mk_call("__pydron_new_cell__", [mk_str(var)])) for var in shared] node.body = shared_stmts + node.body if free: # free vars become arguments free_args = [ast.Name(id=var, ctx=ast.Param()) for var in free] node.args.args = free_args + node.args.args # rename the function orig_name = node.name tmp_name = self.id_factory(node.name) node.name = tmp_name # wrap it if self._inside_class(): wrap_args = [mk_name(naming.passthrough_var(var)) for var in free] else: wrap_args = [mk_name(var) for var in free] wrap_call = mk_call("__pydron_wrap_closure__", [mk_name(tmp_name), mk_tuple(wrap_args)]) wrap_stmt = mk_assign(orig_name, wrap_call) return [node, wrap_stmt] else: return node
def visit_ExtSlice(self, node): self.generic_visit(node) # ast.ExtSlice becomes ast.Index with a tuple. assert all(isinstance(dim, ast.Index) for dim in node.dims) parts = [dim.value for dim in node.dims] s = mk_tuple(parts) return ast.Index(value=s)
def import_call_expr(self, name, fromlist=None, level=None): name_expr = mk_str(name) if name else mk_None() if fromlist: from_expr = mk_tuple(mk_str(item) for item in fromlist) else: from_expr = mk_None() args = [name_expr, mk_call("globals"), mk_None(), from_expr] if level: args.append(mk_num(level)) return mk_call("__import__", args)
def visit_Print(self, node): node = self.generic_visit(node) if node.dest: dest = node.dest else: dest = mk_name("None") if node.nl: nl = mk_name("True") else: nl = mk_name("False") values = mk_tuple(node.values) call = mk_call("__pydron_print__", [dest, values, nl]) return ast.Expr(value=call)
def visit_FunctionDef(self, node): self.generic_visit(node) scopes = node.scopes shared = [ var for var, scope in scopes.iteritems() if scope == scoping.Scope.SHARED ] free = [ var for var, scope in scopes.iteritems() if scope == scoping.Scope.FREE ] # create cells first thing in body shared_stmts = [ mk_assign(var, mk_call("__pydron_new_cell__", [mk_str(var)])) for var in shared ] node.body = shared_stmts + node.body if free: # free vars become arguments free_args = [ast.Name(id=var, ctx=ast.Param()) for var in free] node.args.args = free_args + node.args.args # rename the function orig_name = node.name tmp_name = self.id_factory(node.name) node.name = tmp_name # wrap it if self._inside_class(): wrap_args = [ mk_name(naming.passthrough_var(var)) for var in free ] else: wrap_args = [mk_name(var) for var in free] wrap_call = mk_call( "__pydron_wrap_closure__", [mk_name(tmp_name), mk_tuple(wrap_args)]) wrap_stmt = mk_assign(orig_name, wrap_call) return [node, wrap_stmt] else: return node
def visit_ClassDef(self, node): node = self.generic_visit(node) # free variables of the class block become parameters of the function scopes = getattr(node, "scopes", {}) free = [var for var, scope in scopes.iteritems() if scope == scoping.Scope.FREE] free_param = [ast.Name(id=var, ctx=ast.Param()) for var in free] free_args = [ast.Name(id=var, ctx=ast.Load()) for var in free] # free variables of sub-blocks. Those need name mangling to avoid # collisions with variables local to the class block. passthrough = self.find_passthrough_vars(node) pt_param = [ast.Name(id=naming.passthrough_var(var), ctx=ast.Param()) for var in passthrough] pt_args = [ast.Name(id=var, ctx=ast.Load()) for var in passthrough] # function to execute the class body and collect the attributes func = ast.FunctionDef() func.name = self.id_factory("class_" + node.name) func.args = ast.arguments(args=free_param + pt_param, vararg=None, kwarg=None, defaults=[]) func.body = node.body + [ast.Return(value=mk_name("__pydron_members__"))] func.decorator_list = [] # replicate name mangling of `LocalizeFreeVariables` all_args = free_args + pt_args if self._inside_class(): for arg in all_args: arg.id = naming.passthrough_var(arg.id) # create the class typefunc = mk_call("__pydron_read_global__", [mk_str("type")]) class_expr = mk_call_expr(typefunc, [mk_str(node.name), mk_tuple(node.bases), mk_call(func.name, all_args)]) for decorator in reversed(node.decorator_list): class_expr = mk_call_expr(decorator, [class_expr]) stmt = mk_assign(node.name, class_expr) return [func, stmt]
def visit_ClassDef(self, node): node = self.generic_visit(node) # free variables of the class block become parameters of the function scopes = getattr(node, 'scopes', {}) free = [var for var,scope in scopes.iteritems() if scope == scoping.Scope.FREE] free_param = [ast.Name(id=var, ctx=ast.Param()) for var in free] free_args = [ast.Name(id=var, ctx=ast.Load()) for var in free] # free variables of sub-blocks. Those need name mangling to avoid # collisions with variables local to the class block. passthrough = self.find_passthrough_vars(node) pt_param = [ast.Name(id=naming.passthrough_var(var), ctx=ast.Param()) for var in passthrough] pt_args = [ast.Name(id=var, ctx=ast.Load()) for var in passthrough] # function to execute the class body and collect the attributes func = ast.FunctionDef() func.name = self.id_factory("class_" + node.name) func.args = ast.arguments(args=free_param + pt_param, vararg=None, kwarg=None, defaults=[]) func.body = node.body + [ast.Return(value=mk_name('__pydron_members__')) ] func.decorator_list = [] # replicate name mangling of `LocalizeFreeVariables` all_args = free_args + pt_args if self._inside_class(): for arg in all_args: arg.id = naming.passthrough_var(arg.id) # create the class typefunc = mk_call('__pydron_read_global__', [mk_str('type')]) class_expr = mk_call_expr(typefunc, [mk_str(node.name), mk_tuple(node.bases), mk_call(func.name, all_args)]) for decorator in reversed(node.decorator_list): class_expr = mk_call_expr(decorator, [class_expr]) stmt = mk_assign(node.name, class_expr) return [func, stmt]
def visit_FunctionDef(self, node): self.generic_visit(node) scopes = node.scopes shared = [ var for var, scope in scopes.iteritems() if scope == scoping.Scope.SHARED ] free = [ var for var, scope in scopes.iteritems() if scope == scoping.Scope.FREE ] # create cells first thing in body shared_stmts = [ mk_assign(var, mk_call("__pydron_new_cell__", [mk_str(var)])) for var in shared ] fixed_arguments = [] for arg in node.args.args: if isinstance(arg, ast.Attribute) and arg.attr == "cell_contents": # the generic_visit above made a mess. The attribute is # a free/shared variable and visit_Name replaced it with # an attribute. This makes no sense, so lets repair the damage. # # We don't want to change the parameter name. And I don't # want to change the variable name either. To solve this # we temporarily assign it to another variable: # # def foo(freevar): # freevar__U0 = freevar # freevar = __pydron_new_cell__('freevar') # freevar.cell_contents = freevar__U0 varname = arg.value.id tmp = self.id_factory(varname) # freevar__U0 = freevar shared_stmts.insert(0, mk_assign(tmp, mk_name(varname))) # freevar = __pydron_new_cell__('freevar') # is already in shared_stmts # reevar.cell_contents = freevar__U0 arg.ctx = ast.Store() shared_stmts.append( ast.Assign(targets=[arg], value=mk_name(tmp))) fixed_arguments.append(ast.Name(id=varname, ctx=ast.Param())) else: fixed_arguments.append(arg) node.args.args = fixed_arguments node.body = shared_stmts + node.body if free: # free vars become arguments free_args = [ast.Name(id=var, ctx=ast.Param()) for var in free] node.args.args = free_args + node.args.args # rename the function orig_name = node.name tmp_name = self.id_factory(node.name) node.name = tmp_name # wrap it if self._inside_class(): wrap_args = [ mk_name(naming.passthrough_var(var)) for var in free ] else: wrap_args = [mk_name(var) for var in free] wrap_call = mk_call( "__pydron_wrap_closure__", [mk_name(tmp_name), mk_tuple(wrap_args)]) wrap_stmt = mk_assign(orig_name, wrap_call) return [node, wrap_stmt] else: return node
def visit_DictComp(self, node): node = self.generic_visit(node) elt = mk_tuple([node.key, node.value]) listexpr = ast.ListComp(elt=elt, generators=node.generators) return mk_call('dict', [listexpr])