def pythonize(self, env, compiler): test, has_statement1 = self.test.pythonize(env, compiler) then, has_statement2 = self.then.pythonize(env, compiler) else_, has_statement3 = self.else_.pythonize(env, compiler) if_ = If(test[-1], begin(*then), begin(*else_)) if_.is_statement = if_.is_statement or has_statement2 or has_statement3 return test[:-1]+(if_,), has_statement1 or if_.is_statement
def optimize_apply(self, env, compiler, args): param, arg = self.params[0], args[0] if not arg.side_effects(): body = self.body.subst({param: arg}).optimize(env, compiler) return body else: ref_count = compiler.ref_count.get(param, 0) if ref_count==0: return begin(arg, self.body).optimize(env, compiler) else: return begin(Assign(param, arg), self.body).optimize(env, compiler)
def pythonize(self, env, compiler): body_exps, body_has_any_statement = self.body.pythonize(env, compiler) global_vars = self.find_assign_lefts()-set(self.params) global_vars = set([x for x in global_vars if isinstance(x, Var) and not isinstance(x, LocalVar) and not isinstance(x, SolverVar)]) if global_vars: body_exps = (GlobalDecl(global_vars),)+body_exps if not body_has_any_statement: return (MacroRulesFunction(self.new(self.params, begin(*body_exps))),), False else: name = compiler.new_var(LocalVar('function')) body = begin(*body_exps).insert_return_statement() return (Function(name, self.params, body), MacroRulesFunction(name)), True
def optimize(self, env, compiler): free_vars = self.free_vars() assigns = [] for var in free_vars: value = env[var] if value is None: continue assigns.append(Assign(var, value)) del env[var] return begin(*(tuple(assigns) + (For(self.var, self.range.optimize(env, compiler), self.body.optimize(env, compiler)),)))
def append_failcont(compiler, *exps): v = compiler.new_var(ConstLocalVar('v')) fc = compiler.new_var(ConstLocalVar('fc')) return Begin(( Assign(fc, failcont), SetFailCont( clamda(v, SetFailCont(fc), begin(*exps), fc(v))) ))
def optimize(self, env, compiler): value = self.value.optimize(env, compiler) if isinstance(value, Tuple) or isinstance(value, List): if len(value.item)!=len(self.vars): raise DaoCompileError else: for var, v in zip(self.vars, value.item): if isinstance(var, ConstLocalVar): env[var] = v else: assigns.append(Assign(var, v)) if assigns: return begin(*tuple(Assign(var, v))) else: return None return AssignFromList(*(self.vars+(value,)))
def pythonize(self, env, compiler): if self.has_pythonized: return (self.name,), False body_exps, has_any_statement = self.body.pythonize(env, compiler) global_vars = self.find_assign_lefts()-set(self.params) global_vars = set([x for x in global_vars if isinstance(x, Var) and not isinstance(x, LocalVar) and not isinstance(x, SolverVar) ]) if global_vars: body_exps = (GlobalDecl(global_vars),)+body_exps if not body_exps[-1].is_statement: body_exps = body_exps[:-1] + (Return(body_exps[-1]),) else: body_exps = body_exps[:-1] + (body_exps[-1].insert_return_statement(),) self.has_pythonized = True return (self.new(self.params, begin(*body_exps)), self.name), True
def while_(test, *exps): return While(test, begin(*[x for x in exps]))
def lamda(params, *body): return Lamda(params, begin(*body))
def insert_return_statement(self): return begin(self, Return(self.var))
def for_(var, range, *exps): return For(element(var), element(range), begin(*[x for x in exps]))
def __call__(self, arg): if arg.side_effects(): return begin(Assign(self.params[0], arg), self.body) else: result = self.body.subst({self.params[0]:arg}) return result
def clamda(v, *body): return Clamda(v, begin(*body))
def pythonize(self, env, compiler): var, has_statement1 = self.var.pythonize(env, compiler) range, has_statement1 = self.range.pythonize(env, compiler) body, has_statement2 = self.body.pythonize(env, compiler) return (For(var[-1], range[-1], begin(*body)),), True
def cfunction(name, v, *body): return CFunction(name, v, begin(*body))
def append_failcont(compiler, *exps): v = compiler.new_var(ConstLocalVar('v')) fc = compiler.new_var(ConstLocalVar('fc')) return Begin((Assign(fc, failcont), SetFailCont(clamda(v, SetFailCont(fc), begin(*exps), fc(v)))))
def pythonize(self, env, compiler): test, has_statement1 = self.test.pythonize(env, compiler) body, has_statement2 = self.body.pythonize(env, compiler) result = While(test[-1], begin(*body)) return test[:-1]+(result,), True