def op_RAP(self, state): """rap works like ap, only that it replaces an occurrence of a dummy environment with the current one, thus making recursive functions possible """ new_dump = state.D.push(state.S).push(state.E).push(state.C) closure, new_stack = state.S.pop() parameters, new_stack = new_stack.pop() if not isinstance(parameters, Cons): raise ValueError("top of stack expected to be a cons") param_list = cons2list(parameters) new_stack = state.S.reset() new_env = closure.env.replace_level(param_list) return SECDState(new_stack, new_env, closure.frame, new_dump)
def op_AP(self, state): """ap pops a closure and a list of parameter values from the stack. The closure is applied to the parameters by installing its environment as the current one, pushing the parameter list in front of that, clearing the stack, and setting C to the closure's function pointer. The previous values of S, E, and the next value of C are saved on the dump. """ new_dump = state.D.push(state.S).push(state.E).push(state.C) closure, tmp_stack = state.S.pop() parameters, _ = tmp_stack.pop() if not isinstance(parameters, Cons): raise ValueError("top of stack expected to be a cons") param_list = cons2list(parameters) new_stack = state.S.reset() new_env = closure.env.new_level(param_list) return SECDState(new_stack, new_env, closure.frame, new_dump)