def bind(self, param, val): if param.is_nil() and val.is_nil(): return w_nil elif isinstance(param, W_Symbol): if param is self.w_underscore: return w_nil else: return w_list([w_list([param, val])]) elif param.is_nil(): raise QuoppaException("too many arguments") elif val.is_nil(): raise QuoppaException("too few arguments") elif isinstance(param, W_List) and isinstance(val, W_List): return self.bind(param.car, val.car).comma(self.bind(param.cdr, val.cdr)) else: raise QuoppaException("can't bind %s %s" % (param.to_string(), val.to_string()))
def __init__(self, primitives): vau = W_Vau(self.vau) global_frame = self.bind(symbol("vau"), vau) global_frame.comma(w_list([w_list([symbol("operate"), W_Operate()])])) global_frame.comma(w_list([w_list([symbol("eval"), W_Eval()])])) primitives["lookup"] = self.lookup for name in primitives: prim = W_Primitive(primitives[name]) global_frame.comma(w_list([w_list([symbol(name), prim])])) self.global_env = w_list([global_frame])
def interpret(self, env, w_exp): stack = w_nil operand_stack = w_list([w_exp]) env_stack = w_list([self.global_env if env.is_nil() else env]) while not operand_stack.is_nil(): w_exp = operand_stack.car if isinstance(w_exp, W_Fexpr): self.jitdriver.can_enter_jit( self=self, w_exp=w_exp, env_stack=env_stack, stack=stack, operand_stack=operand_stack ) self.jitdriver.jit_merge_point( self=self, w_exp=w_exp, env_stack=env_stack, stack=stack, operand_stack=operand_stack ) env_stack, stack, operand_stack = w_exp.compile(self, env_stack, stack, operand_stack.cdr) assert isinstance(env_stack, W_List) assert isinstance(stack, W_List) assert isinstance(operand_stack, W_List) return stack.car