def testSexpParsing(self): """Test parsing S-expressions. """ cases = [("x", tsym("x")), \ ("(x)", from_python_list([tsym("x")])), \ ("(x y)", from_python_list([tsym("x"), tsym("y")])), \ ("(x (y))", from_python_list([tsym("x"), [tsym("y")]])), \ ("(x . y)", cons(tsym("x"), tsym("y"))), \ ("(x y . z)", cons(tsym("x"), cons(tsym("y"), tsym("z")))), \ ("(x (y . z) w)", cons(tsym("x"), cons(cons(tsym("y"), tsym("z")), cons(tsym("w"), NIL))))] for case in cases: sexp = self.parser.parse(self.tokenizer.tokenize(case[0] + '\n'))[0] self.assertEqual(sexp, case[1])
def compile_namedlet(self, exp, env, cont, istail=False): """Compile a named let form. At runtime a new frame will be created and the closure will be defined in such frame and applied to the arguments listed in the bindings. """ def got_define(define_code): nonlocal compiled_define_code compiled_define_code = define_code apply_form = cons(proc_name, from_python_list(vall)) return bounce(self.compile_call, apply_form, newenv, got_apply, istail=istail) def got_apply(apply_code): code = [ (inst_extenv,), ] + compiled_define_code + \ apply_code + [ (inst_killenv,), ] return bounce(cont, code) proc_name = cadr(exp) varl = let_vars(caddr(exp)) vall = let_vals(caddr(exp)) lambda_form = lib_append( lib_list( tsym('lambda'), from_python_list(varl)), cdddr(exp)) define_form = lib_list(tsym('define'), proc_name, lambda_form) newenv = Frame([proc_name], outer=env) compiled_define_code = None return bounce(self.compile_define, define_form, newenv, got_define)
def inst_tailcall(vm): """Make a tail call to closure in VAL with ARGS. """ closure = vm.regs[vm.REG_VAL] if not isinstance(closure, Closure): raise SchemeError('not a callable procedure') if closure.isprim: vm.regs[vm.REG_VAL] = closure.primcall(vm.regs[vm.REG_ARGS]) vm.regs[vm.REG_PC] += 1 else: # bind parameters to arguments if closure.isvararg: # the last parameter is bound to a list args = vm.regs[vm.REG_ARGS][:closure.arity[0] - 1] args.append(from_python_list(vm.regs[vm.REG_ARGS][closure.arity[0] - 1:])) closure.check_arity(len(args)) frm = Frame(args, closure.env) else: closure.check_arity(len(vm.regs[vm.REG_ARGS])) frm = Frame(vm.regs[vm.REG_ARGS], closure.env) vm.regs[vm.REG_ENV] = frm # jump to the closure code vm.code = closure.body vm.codelen = len(vm.code) vm.regs[vm.REG_PC] = 0
def got_define(define_code): nonlocal compiled_define_code compiled_define_code = define_code apply_form = cons(proc_name, from_python_list(vall)) return bounce(self.compile_call, apply_form, newenv, got_apply, istail=istail)