def test_source_lib(): g = GlobalEnv() g.eval_str('(source root_env "applications/lib_substitute.lisp")') assert g.eval_str('(in? root_env "substitute")') assert g.eval_str('(in? root_env "substitute_example")') assert g.eval_str('substitute_example') == [1, 2, 5]
def test_quotation_mark(): g = GlobalEnv() g.eval_str('''(define "foo" (join (str) (list double_quote "Hello world!" double_quote )))''') assert g.eval_str('foo') == '"Hello world!"'
def test_macro_lambda0(): g = GlobalEnv() g.eval_str('(define "foo1" (macro (x y) (list x y)))') g.eval_str('(define "foo2" (macro (x y) (list (eval dyn_env x) (eval dyn_env y))))') assert g.eval_str('(foo1 (+ 2 3) (* 4 5))') == [['+', 2, 3], ['*', 4, 5]] assert g.eval_str('(foo2 (+ 2 3) (* 4 5))') == [5, 20]
def test_dyn(): g = GlobalEnv() g.eval_str('(define "foo" (lambda (x y) (if (in? dyn_env x) y 0)))') assert not g.eval_str('(in? root_env "x")') assert g.eval_str('(foo "x" 1)') == 1 assert g.eval_str('(foo "+" 1)') == 0 assert g.eval_str('(foo "y" 55)') == 55
def test_types(): g = GlobalEnv() assert g.eval_str('(type? 5)') == sym_lis3.Int assert g.eval_str('(type? "foo")') == sym_lis3.String assert g.eval_str('(type? (quote type))') == sym_lis3.Symbol assert g.eval_str('(type? type?)') == type(g['type?']) assert g.eval_str('(type? (str "foo"))') == str
def test_env_lambda(): g = GlobalEnv() g.eval_str('(define "foo" (lambda (x y) (* (+ 2 x) y)))') assert g.eval_str('(in? foo "_args")') assert g.eval_str('(in? foo "_body")') assert g.eval_str('(in foo "_args")') == ['x', 'y'] assert g.eval_str('(in foo "_body")') == ['*', ['+', 2, 'x'], 'y']
def test_substitute(): g = GlobalEnv() g.eval_str('''(define "substitute" (lambda (target_name sub expr) (if (list? expr) (map (curry substitute target_name sub) expr) (if (equal? expr target_name) sub expr) )))''') assert g.eval_str('(substitute "x" 5 (quote (1 2 x)))') == [1, 2, 5]
def test_define_nested_dynamic(): g = GlobalEnv() g.eval_str( '(define "e1" (nest dyn_env (env (list "foo" "bar") (list 2 3))))') assert g.eval_str('(find e1 "+")') is g.eval_str('+') g.eval_str('(define e1 "ka" (env (list "zzz" "qwe") (list 55 77)))') assert not g.eval_str('(in? root_env "ka")') assert g.eval_str('(in? e1 "ka")') assert g.eval_str('(in (in e1 "ka") "qwe")') == 77
def repl(prompt='sym_repl> '): "A prompt-read-eval-print loop." g = GlobalEnv() while True: input_program = handy_input(prompt) if not input_program.strip(): continue try: val = g.eval_str(input_program) if val is not None: print(lispstr(val)) except Exception as e: print(e)
def test_define_nest_empty_env(): g = GlobalEnv() g.eval_str('(define "e0" (env))') assert g.eval_str('(in? root_env "e0")') g.eval_str('(define e0 "foo" 5)') assert "foo" in g.eval_str('e0')
def test_nest(): g = GlobalEnv() # return None for not found vars #g.eval_str('(define "not_found" (lambda (var) None))') # no, the not_found handler is attached per env chain # a custom env will not randomly search for it in root_env g.eval_str('(define "e0" (env (list "foo" "bar") (list 2 3)))') with pytest.raises(NameError): g.eval_str('(find e0 "+")') g.eval_str('(nest root_env e0)') assert g.eval_str('(find e0 "+")') is g.eval_str('+')
def test_env_lambda_diy(): g = GlobalEnv() g.eval_str('(define "foo" (lambda (x y) (* (+ 2 x) y)))') g.eval_str('''(define "foo2" (nest root_env (env (list "_args" "_body") (' (("x" "y") (* (+ 2 x) y))) )))''') assert g.eval_str('(foo 3 4)') == g.eval_str('(foo2 3 4)') == 20 assert g.eval_str('(in? foo "_args")')
def test_func(): g = GlobalEnv() #g.eval_str('''(define "func" (lambda (func_name args body) # (define (out (out dyn_env)) func_name (lambda args body)) # ))''') # TODO: there is a limitation in lambda here: it always sets outer to its # current dyn_env, not to the one where I do the define -- it only attaches # it. The Env handles it with `nest`. g.eval_str('''(define "func" (lambda (func_name args body) (define (out (out dyn_env)) func_name (nest (out (out dyn_env)) (env (list "_args" "_body") (list args body)))) ))''') g.eval_str('(func "foo" (list "x" "y") (quote (+ x y)))') assert g.eval_str('(in? root_env "foo")') assert g.eval_str('(out foo)') is g # root_env assert g.eval_str('(foo 2 7)') == 9
def define_none_hook(): g = GlobalEnv() g.eval_str('(define "not_found" (lambda (x) None))') return g
def test_define_wrong_arity(): g = GlobalEnv() with pytest.raises(ValueError): g.eval_str('(define "foo" "bar" "e1" "value")')
def define_str_hook(): g = GlobalEnv() g.eval_str('(define "not_found" (lambda (x) (str x)))') return g
def test_define_nested(): g = GlobalEnv() g.eval_str( '(define "e1" (nest root_env (env (list "foo" "bar") (list 2 3))))') assert g.eval_str('(find e1 "+")') is g.eval_str('+')
def test_map_curry(): g = GlobalEnv() g.eval_str('(define "foo" (lambda (x y) (* x y)))') assert list(g.eval_str('(map (curry foo 2) (list 1 2 3))')) == [2, 4, 6]
def test_join_string(test_input, expected): g = GlobalEnv() assert g.eval_str(test_input) == expected
def test_retrieve(): g = GlobalEnv() assert g.eval_str('(in (env (list "foo" "bar") (list 2 3)) "foo")') == 2 with pytest.raises(KeyError): g.eval_str('(in (env (list "foo" "bar") (list 2 3)) "baz")') == 2
def test_format(): g = GlobalEnv() assert g.eval_str('(format "%s %s" "foo" "bar")') == 'foo bar'
def test_source_file(): g = GlobalEnv() g.eval_str('(source root_env "applications/lib_foo.lisp")') assert 'foo' in g
def test_version(): g = GlobalEnv() assert g.eval_str('(_getattr _sys (str "version"))')[0] == '3'
def test_source_lib_chain(): g = GlobalEnv() g.eval_str('(source root_env "applications/lib_bar.lisp")') assert 'bar' in g assert 'foo' in g
def test_print_parentheses(): g = GlobalEnv() assert g.eval_str('(+ "foo" ")")') == 'foo)' assert g.eval_str('(+ "(" (+ "foo" ")"))') == '(foo)'
def test_input_syntax(): g = GlobalEnv() with pytest.raises(ValueError): g.eval_str('(env (list "foo" "bar") (list 2 3) "boo")') == 2
def test_outer_env(): g = GlobalEnv() g.eval_str('(define "e0" (env))') assert g.eval_str('(in? root_env "e0")') g.eval_str('(define e0 "bar" 5)') g.eval_str('''(define e0 "foo" (nest root_env (env (list "_args" "_body") (' (("x" "y") (* (+ 2 x) y))) )))''') assert "bar" in g.eval_str('e0') assert "foo" in g.eval_str('e0') assert g.eval_str('(find? (in e0 "foo") "bar")') is False assert g.eval_str('(find? (in e0 "foo") "+")') is True assert g.eval_str('(out (in e0 "foo"))') is g.eval_str('root_env')
def test_map_basic(): g = GlobalEnv() assert list(g.eval_str('(map (lambda (x) (* 2 x)) (list 1 2 3))')) == [2, 4, 6]
def test_quotes(var_name, val): g = GlobalEnv() g.eval_str('(define "%s" "%s")' % (var_name, val)) assert g.eval_str(var_name) == val
def test_content(true_test): g = GlobalEnv() g.eval_str('(define "e0" (env (list "foo" "bar") (list 2 3)))') assert g.eval_str(true_test)