Ejemplo n.º 1
0
 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])
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
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
Ejemplo n.º 4
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)