Beispiel #1
0
 def optimize_apply(self, env, compiler, args):
   #1. ((lambda () body))  =>  body 
   if len(self.params)==0:
     return self.body.optimize(env, compiler)
   
   #2. (lamda x: ...x...)(y) => (lambda : ... y ...)() 
   bindings = {}
   new_params, new_args = (), ()
   for i, p in enumerate(self.params):
     arg = args[i]
     if arg.side_effects():
       new_params += (p,)
       new_args += (arg,)
       continue
     else:
       ref_count = compiler.ref_count.get(p, 0)
       if ref_count==0:
         continue
       elif ref_count==1:
         bindings[p] = arg
       else:
         if arg.code_size()*ref_count>MAX_EXTEND_CODE_SIZE: 
           # a(...y...), and a is (lamda ...x...: ...x...), 
           #then convert as above if code size is ok. 
           new_params += (p,)
           new_args += (arg,)
         else: 
           bindings[p] = arg
   
   if new_params:
     if bindings:
       return Apply(self.new(new_params, self.body.subst(bindings).optimize(env, compiler)), 
                       tuple(arg.optimize(env, compiler) for arg in new_args))
     else:
       if len(new_params)!=len(self.params):
         Apply(self.new(new_params, self.body.subst(bindings).optimize(env, compiler)), 
               tuple(arg.optimize(env, compiler) for arg in new_args))   
       else:
         return Apply(self.new(new_params, self.body.optimize(env, compiler)), 
                      optimize_args(new_args, env, compiler))
   else:
     if bindings:
       return self.body.subst(bindings).optimize(env, compiler)
     else:
       return self.body.optimize(env, compiler)
Beispiel #2
0
 def optimize(self, env, compiler):
   args = optimize_args(self.args, env, compiler)
   if isinstance(self.caller, Var):
     if self.caller not in compiler.recursive_call_path:
       caller = self.caller.optimize(env, compiler)
       if isinstance(caller, Lamda):
         compiler.recursive_call_path.append(self.caller)      
         result = caller.optimize_apply(env, compiler, args)
         compiler.recursive_call_path.pop()  
         return result
       else:
         return self.__class__(caller, args)
     else: 
       return self.__class__(self.caller, args)
   elif isinstance(self.caller, Lamda):
     return self.caller.optimize_apply(env, compiler, args)
   else:
     caller = self.caller.optimize(env, compiler)
     if isinstance(caller, Lamda):
       return caller.optimize_apply(env, compiler, args)
     else:
       return self.__class__(caller, args)