def test_set_form_setting_value_in_inner_scope(sym, outer, inner): m = mock.Mock() env = Env({obj.Symbol("func"): m}) eval(f"(define {sym} {outer})", env) eval( f""" (define a (lambda ({sym}) (begin (set! {sym} {inner}) (func {sym})))) """, env, ) eval("(a (quote ()))", env) m.assert_called_once_with(inner) assert env[obj.Symbol(sym)] == outer
def test_set_form_setting_value_in_outer_scope(sym, val): env = Env() eval(f"(define {sym} (quote ()))", env) eval( f""" (define a (lambda () (set! {sym} {val}))) """, env, ) eval("(a)", env) assert env[obj.Symbol(sym)] == val
def test_lambda_env_capture(val): m = mock.Mock() env = Env({obj.Symbol("func"): m}) eval( """ (define a (lambda (x) (lambda () (func x)))) """, init_env=env, ) eval(f"(define b (a {val}))", init_env=env) eval("(b)", init_env=env) m.assert_called_once_with(val)
def test_recursive_function_call(val): m = mock.Mock() env = Env({obj.Symbol("func"): m, **STD_ENV}) calls = [mock.call(x) for x in range(val, 0, -1)] eval( """ (define a (lambda (acc _) (cond ((= acc 0) #t) (#t (a (- acc 1) (func acc)))))) """, init_env=env, ) assert eval(f"(a {val} (func {val}))", init_env=env) m.assert_has_calls(calls)
def visit_symbol(self, node: ast.Symbol): return obj.Symbol(node.value)
def test_lambda_evaluation(val): m = mock.Mock() env = Env({obj.Symbol("func"): m}) eval(f"((lambda (x) (func x)) {val})", init_env=env) m.assert_called_once_with(val)
def test_function_call(fst, snd): m = mock.Mock() env = Env({obj.Symbol("func"): m}) eval(f"(func {fst} {snd})", init_env=env) m.assert_called_once_with(fst, snd)
def test_symbol_definition(sym, val): env = Env() eval(f"(define {sym} {val})", init_env=env) assert obj.Symbol(sym) in env assert env[obj.Symbol(sym)] == val
def test_set_form_on_some_cell_in_list(init, val): env = Env(STD_ENV) list_vals = " ".join(map(str, init)) eval(f"(define loc (quote ({list_vals})))", env) eval(f"(set! (car (cdr (cdr loc))) {val})", env) assert env[obj.Symbol("loc")].cdr.cdr.value == val
def test_set_form_evaluation(sym, val): env = Env() eval(f"(define {sym} (quote ()))", env) eval(f"(set! {sym} {val})", env) assert env[obj.Symbol(sym)] == val