Пример #1
0
 def _Closure(self, c):
     closed_over_literal = any(
         map(lambda x: not isinstance(x, S.Name), c.closed_over()))
     if not closed_over_literal:
         return c
     #Find procedure being closed over
     proc_name = c.body().id
     proc = self.procedures[proc_name]
     proc_args = proc.formals()
     closed_args = c.closed_over()
     #Construct new set of arguments, with literals closed over removed
     replaced_args = proc_args[:-len(closed_args)]
     replaced_closed_over = []
     #Also record what replacements to make
     replacement = {}
     for orig_arg, closed_arg in zip(proc_args[-len(closed_args):],
                                     closed_args):
         if isinstance(closed_arg, S.Name):
             replaced_args.append(orig_arg)
             replaced_closed_over.append(closed_arg)
         else:
             replacement[orig_arg.id] = closed_arg
     #If we are only closing over literals, we will return a name
     #rather than a reduced closure. Check.
     fully_opened = len(replacement) == len(closed_args)
     replaced_stmts = [
         S.substituted_expression(si, replacement) \
             for si in proc.body()]
     replaced_name = S.Name(proc_name + self.name_supply.next())
     self.propagated.append(
         S.Procedure(replaced_name, replaced_args, replaced_stmts))
     if fully_opened:
         return replaced_name
     else:
         return S.Closure(replaced_closed_over, replaced_name)
Пример #2
0
    def _Lambda(self, e):
        fn = S.Name(self.names.next())

        self.rewrite_children(e)
        body = S.Return(e.parameters[0])
        self.proclist.append(S.Procedure(fn, e.variables, [body]))

        return fn
Пример #3
0
    def _Procedure(self, proc):
        names = pltools.name_supply(stems=['tuple'], drop_zero=False)
        disassembly = []

        def make_name(arg):
            if not isinstance(arg, S.Tuple):
                return arg
            else:
                made_name = S.Name(names.next())
                assembled = S.Bind(S.Tuple(*[make_name(x) for x in arg]),
                                   made_name)
                disassembly.insert(0, assembled)
                return made_name

        new_variables = map(make_name, proc.formals())
        return S.Procedure(proc.name(), new_variables,
                           disassembly + proc.parameters)