def extend(env, variables, values):
    if is_pair(variables):
        if is_pair(values):
            return cons(cons(variables.car, values.car),
                        extend(env, variables.cdr, values.cdr))
        else:
            raise ValueError("Too few values")
    elif is_null(variables):
        if is_null(values):
            return env
        else:
            raise ValueError("Too many values")
    elif is_symbol(variables):
        return cons(cons(variables, values), env)
    else:
        raise RuntimeError("Branch should be unreachable")
 def __init__(self, *exprs):
     super().__init__()
     if len(exprs) == 0:
         self.exprs = Nil
     elif len(exprs) == 1 and is_pair(exprs[0]):
         self.exprs = exprs[0]
     else:
         self.exprs = Nil
         for x in exprs[::-1]:
             self.exprs = cons(x, self.exprs)
def main():
    definitial('x')
    defprimitive('+', lambda args: args.car + args.cadr, 2)
    defprimitive('-', lambda args: args.car - args.cadr, 2)
    defprimitive('<', lambda args: args.car < args.cadr, 2)
    defprimitive('cons', lambda args: cons(args.car, args.cadr), 2)
    definitial('list', lambda args: args)
    definitial('fib', lambda args: args)
    while True:
        exprs = read()  # our version of read returns a list of expressions
        for expr in exprs:
            value = evaluate(expr, GLOBAL_ENV)
            print(value)
 def resume(self, vs):
     return self.k.resume(cons(self.v, vs))
def test_eval_apply_lambda():
    func = LambdaExpr(cons(Symbol("a"), cons(Symbol("b"), Nil)),
                      cons(ApplyExpr(VariableExpr(Symbol("+")), cons(VariableExpr(Symbol("a")), cons(VariableExpr(Symbol("b")), Nil))), Nil))
    expr = ApplyExpr(func, cons(QuoteExpr(5), cons(QuoteExpr(2), Nil)))
    expr.evaluate(GLOBAL_ENV, AssertEqCont(7))
def test_eval_apply_primitive():
    expr = ApplyExpr(VariableExpr(Symbol("+")), cons(QuoteExpr(1), cons(QuoteExpr(2), Nil)))
    expr.evaluate(GLOBAL_ENV, AssertEqCont(3))
def test_eval_lambda():
    expr = LambdaExpr(cons(Symbol("a"), cons(Symbol("b"), Nil)),
                      cons(QuoteExpr(42), Nil))
    expr.evaluate(NullEnv(), AssertInstanceCont(Function))
def test_eval_begin():
    expr = BeginExpr(QuoteExpr(1), QuoteExpr(2), QuoteExpr(3))
    expr.evaluate(NullEnv(), AssertEqCont(3))

    expr = BeginExpr(cons(QuoteExpr(1), cons(QuoteExpr(2), cons(QuoteExpr(3), Nil))))
    expr.evaluate(NullEnv(), AssertEqCont(3))
def primitive(name, value, vs, arity, k):
    if arity == length(vs):
        return k.resume(value(vs))
    else:
        raise TypeError("incorrect arity {} {}".format(name, vs))

GLOBAL_ENV = NullEnv()
definitial('f')
definitial('foo')
definitial('bar')
definitial('x')
definitial('y')
definitial('z')
defprimitive('null?', lambda args: is_null(args.car), 1)
defprimitive('cons', lambda args: cons(args.car, args.cadr), 2)
defprimitive('car', lambda args: args.caar, 1)
defprimitive('cdr', lambda args: args.cdar, 1)
defprimitive('+', lambda args: args.car + args.cadr, 2)
defprimitive('-', lambda args: args.car - args.cadr, 2)
defprimitive('*', lambda args: args.car * args.cadr, 2)
defprimitive('/', lambda args: args.car / args.cadr, 2)
definitial('println', Primitive('println', lambda args, r, k: k.resume(
    print() if is_null(args) else print(str(args)[1:-1]))))

definitial(
    'call/cc',
    Primitive(
        'call/cc',
        lambda vs, r, k: vs.car.invoke(cons(k, Nil), r, k) if length(
            vs) == 1 else wrong(
Exemple #10
0
def primitive(name, value, vs, arity, k):
    if arity == length(vs):
        return k.resume(value(vs))
    else:
        raise TypeError("incorrect arity {} {}".format(name, vs))


GLOBAL_ENV = NullEnv()
definitial('f')
definitial('foo')
definitial('bar')
definitial('x')
definitial('y')
definitial('z')
defprimitive('null?', lambda args: is_null(args.car), 1)
defprimitive('cons', lambda args: cons(args.car, args.cadr), 2)
defprimitive('car', lambda args: args.caar, 1)
defprimitive('cdr', lambda args: args.cdar, 1)
defprimitive('+', lambda args: args.car + args.cadr, 2)
defprimitive('-', lambda args: args.car - args.cadr, 2)
defprimitive('*', lambda args: args.car * args.cadr, 2)
defprimitive('/', lambda args: args.car / args.cadr, 2)
definitial(
    'println',
    Primitive(
        'println', lambda args, r, k: k.resume(print()
                                               if is_null(args) else print(
                                                   str(args)[1:-1]))))

definitial(
    'call/cc',
def definitial(name, value=None):
    global GLOBAL_ENV
    GLOBAL_ENV = cons(cons(name, value), GLOBAL_ENV)
    return name
def evlis(exps, env):
    if is_pair(exps):
        argument = evaluate(exps.car, env)
        return cons(argument, evlis(exps.cdr, env))
    else:
        return Nil
def primitive(name, value, vs, arity, k):
    if arity == length(vs):
        return k.resume(value(vs))
    else:
        raise TypeError("incorrect arity {} {}".format(name, vs))


GLOBAL_ENV = NullEnv()
definitial('f')
definitial('foo')
definitial('bar')
definitial('x')
definitial('y')
definitial('z')
defprimitive('null?', lambda args: is_null(args.car), 1)
defprimitive('cons', lambda args: cons(args.car, args.cadr), 2)
defprimitive('car', lambda args: args.caar, 1)
defprimitive('cdr', lambda args: args.cdar, 1)
defprimitive('+', lambda args: args.car + args.cadr, 2)
defprimitive('-', lambda args: args.car - args.cadr, 2)
defprimitive('*', lambda args: args.car * args.cadr, 2)
defprimitive('/', lambda args: args.car / args.cadr, 2)
definitial(
    'println',
    Primitive(
        'println', lambda args, r, k: k.resume(print()
                                               if is_null(args) else print(
                                                   str(args)[1:-1]))))

# ========================================================================
#   begin exercise-specific code