def test_begin(): ctx = ExecutionContext() w_global = W_Integer(0) ctx.put("var", w_global) w_result = eval_(ctx, "(begin (set! var 11) (+ var 33))") assert w_result.to_number() == 44 assert ctx.get("var").to_number() == 11
def test_begin(): ctx = ExecutionContext() w_global = W_Integer(0) ctx.put("var", w_global) w_result = eval_(ctx, "(begin (set! var 11) (+ var 33))") assert w_result.to_number() == 44 assert ctx.get("var").to_number() == 11
def test_list(): ctx = ExecutionContext() ctx.put("var", W_Integer(42)) w_lst = eval_(ctx, "(list 1 var (+ 2 1) 'a)") assert isinstance(w_lst, W_Pair) assert w_lst.car.to_number() == 1 assert w_lst.cdr.car.to_number() == 42 assert w_lst.cdr.cdr.car.to_number() == 3 assert w_lst.cdr.cdr.cdr.car.to_string() == "a" assert w_lst.cdr.cdr.cdr.cdr is w_nil
def test_lambda_noargs(): ctx = ExecutionContext() w_lambda = eval_(ctx, "(lambda () 12)") assert isinstance(w_lambda, W_Procedure) assert isinstance(w_lambda, W_Lambda) ctx.put("f1", w_lambda) w_result = eval_(ctx, "(f1)") assert isinstance(w_result, W_Integer) assert w_result.to_number() == 12
def test_list(): ctx = ExecutionContext() ctx.put("var", W_Integer(42)) w_lst = eval_(ctx, "(list 1 var (+ 2 1) 'a)") assert isinstance(w_lst, W_Pair) assert w_lst.car.to_number() == 1 assert w_lst.cdr.car.to_number() == 42 assert w_lst.cdr.cdr.car.to_number() == 3 assert w_lst.cdr.cdr.cdr.car.to_string() == "a" assert w_lst.cdr.cdr.cdr.cdr is w_nil
def test_lambda_noargs(): ctx = ExecutionContext() w_lambda = eval_(ctx, "(lambda () 12)") assert isinstance(w_lambda, W_Procedure) assert isinstance(w_lambda, W_Lambda) ctx.put("f1", w_lambda) w_result = eval_(ctx, "(f1)") assert isinstance(w_result, W_Integer) assert w_result.to_number() == 12
def test_ctx(): w_fnum = W_Integer(12) w_symb = W_Symbol("symb") ctx = ExecutionContext() ctx.put("v1", w_fnum) ctx.put("symb", w_symb) assert w_symb is ctx.get("symb") assert w_fnum is ctx.get("v1") py.test.raises(UnboundVariable, ctx.get, "no_such_key")
def test_ctx_simple(): ctx = ExecutionContext() ctx.put("v1", W_Integer(4)) ctx.put("v2", W_Integer(5)) w_num = eval_(ctx, "(+ 1 v1 v2)") assert w_num.to_number() == 10 ctx.put("v2", W_Real(3.2)) w_num = eval_(ctx, "(+ 1 v1 v2)") assert w_num.to_number() == 8.2
def test_ctx(): w_fnum = W_Integer(12) w_symb = W_Symbol("symb") ctx = ExecutionContext() ctx.put("v1", w_fnum) ctx.put("symb", w_symb) assert w_symb is ctx.get("symb") assert w_fnum is ctx.get("v1") py.test.raises(UnboundVariable, ctx.get, "no_such_key")
def test_ctx_simple(): ctx = ExecutionContext() ctx.put("v1", W_Integer(4)) ctx.put("v2", W_Integer(5)) w_num = eval_(ctx, "(+ 1 v1 v2)") assert w_num.to_number() == 10 ctx.put("v2", W_Real(3.2)) w_num = eval_(ctx, "(+ 1 v1 v2)") assert w_num.to_number() == 8.2
def test_let(): ctx = ExecutionContext() w_global = W_Integer(0) ctx.put("var", w_global) w_result = eval_(ctx, "(let ((var 42) (x (+ 2 var))) (+ var x))") assert w_result.to_number() == 44 assert ctx.get("var") is w_global w_result = eval_(ctx, """ (let ((x (lambda () 1))) (let ((y (lambda () (x))) (x (lambda () 2))) (y)))""") assert w_result.to_number() == 1 py.test.raises(UnboundVariable, eval_noctx, "(let ((y 0) (x y)) x)")
def test_ctx_sets(): w_fnum = W_Integer(42) w_fnum2 = W_Integer(43) w_fnum3 = W_Integer(44) ctx = ExecutionContext() ctx.put("v1", w_fnum) ctx2 = ctx.copy() assert w_fnum is ctx2.get("v1") ctx.set("v1", w_fnum2) assert w_fnum2 is ctx2.get("v1") assert w_fnum2 is ctx.get("v1") ctx2.put("v1", w_fnum3) assert w_fnum3 is ctx2.get("v1")
def test_let(): ctx = ExecutionContext() w_global = W_Integer(0) ctx.put("var", w_global) w_result = eval_(ctx, "(let ((var 42) (x (+ 2 var))) (+ var x))") assert w_result.to_number() == 44 assert ctx.get("var") is w_global w_result = eval_( ctx, """ (let ((x (lambda () 1))) (let ((y (lambda () (x))) (x (lambda () 2))) (y)))""") assert w_result.to_number() == 1 py.test.raises(UnboundVariable, eval_noctx, "(let ((y 0) (x y)) x)")
def test_ctx_sets(): w_fnum = W_Integer(42) w_fnum2 = W_Integer(43) w_fnum3 = W_Integer(44) ctx = ExecutionContext() ctx.put("v1", w_fnum) ctx2 = ctx.copy() assert w_fnum is ctx2.get("v1") ctx.set("v1", w_fnum2) assert w_fnum2 is ctx2.get("v1") assert w_fnum2 is ctx.get("v1") ctx2.put("v1", w_fnum3) assert w_fnum3 is ctx2.get("v1")
def test_delay_promise_force(): ctx = ExecutionContext() w_promise = eval_(ctx, "(delay (+ 1 2))") assert isinstance(w_promise, W_Promise) ctx.put("d", w_promise) w_promise2 = eval_(ctx, "d") assert w_promise2 is w_promise py.test.raises(NotCallable, eval_, ctx, "(d)") w_value = eval_(ctx, "(force d)") assert w_value.to_number() == 3 py.test.raises(WrongArgType, eval_noctx, "(force 'a)") eval_(ctx, "(define d2 (delay (+ 1 x)))") eval_(ctx, "(define x 42)") w_result = eval_(ctx, "(force d2)") assert w_result.to_number() == 43 eval_(ctx, "(set! x 0)") w_result = eval_(ctx, "(force d2)") assert w_result.to_number() == 43
def test_delay_promise_force(): ctx = ExecutionContext() w_promise = eval_(ctx, "(delay (+ 1 2))") assert isinstance(w_promise, W_Promise) ctx.put("d", w_promise) w_promise2 = eval_(ctx, "d") assert w_promise2 is w_promise py.test.raises(NotCallable, eval_, ctx, "(d)") w_value = eval_(ctx, "(force d)") assert w_value.to_number() == 3 py.test.raises(WrongArgType, eval_noctx, "(force 'a)") eval_(ctx, "(define d2 (delay (+ 1 x)))") eval_(ctx, "(define x 42)") w_result = eval_(ctx, "(force d2)") assert w_result.to_number() == 43 eval_(ctx, "(set! x 0)") w_result = eval_(ctx, "(force d2)") assert w_result.to_number() == 43
def test_syntax_rules_literals(): ctx = ExecutionContext() # => is literal, should be matched exactly # w_transformer created in ctx w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))") w_expr = parse_("(foo 12 boo)") py.test.raises(MatchError, w_transformer.match, ctx, w_expr) w_expr = parse_("(foo bar boo)") py.test.raises(MatchError, w_transformer.match, ctx, w_expr) # exact match w_expr = parse_("(foo => boo)") # within the same context assert w_transformer.match(ctx, w_expr)[0].to_boolean() w_42 = W_Number(42) # different lexical scope, not the same bindings for => in ctx and closure closure = ctx.copy() closure.put("=>", w_42) w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))") py.test.raises(MatchError, w_transformer.match, closure, w_expr) # different lexical scope, not the same bindings for => in ctx and closure ctx.put("=>", W_Number(12)) assert ctx.get("=>") is not closure.get("=>") w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))") py.test.raises(MatchError, w_transformer.match, closure, w_expr) # the same object for => in ctx and closure, but different bindings # <arigo> I think this should also raise MatchError. When R5RS says # "same binding" it probably means bound to the same *location*, not # just that there is the same object in both locations ctx.put("=>", w_42) assert ctx.get("=>") is closure.get("=>") w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))") py.test.raises(MatchError, w_transformer.match, closure, w_expr)
def test_syntax_rules_literals(): ctx = ExecutionContext() # => is literal, should be matched exactly # w_transformer created in ctx w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))") w_expr = parse_("(foo 12 boo)") py.test.raises(MatchError, w_transformer.match, ctx, w_expr) w_expr = parse_("(foo bar boo)") py.test.raises(MatchError, w_transformer.match, ctx, w_expr) # exact match w_expr = parse_("(foo => boo)") # within the same context assert w_transformer.match(ctx, w_expr)[0].to_boolean() w_42 = W_Number(42) # different lexical scope, not the same bindings for => in ctx and closure closure = ctx.copy() closure.put("=>", w_42) w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))") py.test.raises(MatchError, w_transformer.match, closure, w_expr) # different lexical scope, not the same bindings for => in ctx and closure ctx.put("=>", W_Number(12)) assert ctx.get("=>") is not closure.get("=>") w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))") py.test.raises(MatchError, w_transformer.match, closure, w_expr) # the same object for => in ctx and closure, but different bindings # <arigo> I think this should also raise MatchError. When R5RS says # "same binding" it probably means bound to the same *location*, not # just that there is the same object in both locations ctx.put("=>", w_42) assert ctx.get("=>") is closure.get("=>") w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))") py.test.raises(MatchError, w_transformer.match, closure, w_expr)