def test_step4_count(self): self.assertEqual("0", step4_if_fn_do.rep("(count (list))", self._repl_env)) self.assertEqual( "2", step4_if_fn_do.rep("(count (list 1 2))", self._repl_env)) self.assertEqual("0", step4_if_fn_do.rep("(count nil)", self._repl_env))
def test_step6_swap(self): self.assertEqual( "#<function>", step6_file.rep("(def! inc3 (fn* (a) (+ 3 a)))", self._repl_env), ) self.assertEqual("(atom 2)", step6_file.rep("(def! a (atom 2))", self._repl_env)) self.assertEqual("3", step6_file.rep("(swap! a + 1)", self._repl_env))
def test_tokenize_line_iter(self): lines = [ "(def! contains (fn* (m l)\n", " (let* (f (first l))\n", " (if (nil? f)\n", " false\n", " (if (= m f)\n", " true\n", " (contains m (rest l)))))))\n", ] self.assertEqual("#<function>", rep.rep(iter(lines), self._repl_env)) self.assertEqual("true", rep.rep("(contains 3 '(2 3 1))", self._repl_env))
def test_step5_tco(self): self.assertEqual( "#<function>", step5_tco.rep( "(def! sum2 (fn* (n acc) (if (= n 0) acc (sum2 (- n 1) (+ n acc)))))", self._repl_env, ), ) self.assertEqual("55", step5_tco.rep("(sum2 10 0)", self._repl_env)) self.assertEqual("nil", step5_tco.rep("(def! res2 nil)", self._repl_env)) self.assertEqual( "500500", step5_tco.rep("(def! res2 (sum2 1000 0))", self._repl_env)) self.assertEqual("500500", step5_tco.rep("res2", self._repl_env))
def test_step4_equal(self): self.assertEqual("true", step4_if_fn_do.rep("(= 0 0)", self._repl_env)) self.assertEqual( "true", step4_if_fn_do.rep("(= (list 1) (list 1))", self._repl_env)) self.assertEqual( "false", step4_if_fn_do.rep("(= (list 1) (list 1 2))", self._repl_env)) self.assertEqual( "true", step4_if_fn_do.rep( "(= (list (list 1) (list 2)) (list (list 1) (list 2)))", self._repl_env), ) self.assertEqual("true", step4_if_fn_do.rep("(= nil nil)", self._repl_env))
def test_step6_standard_string(self): self.assertEqual( '"foo"', step6_file.EVAL(MalString('"foo"'), Env(None)).native()) self.assertEqual('"foo"', step6_file.rep('"foo"', self._repl_env).__str__()) self.assertEqual('"foo"', MalString('"foo"').native()) self.assertEqual('"\\"foo\\""', MalString('"foo"').__str__())
def test_step8_repl_env_isolation(self): env1 = step8_macros.init_repl_env() step8_macros.rep("(def! a 2)", env1) env2 = step8_macros.init_repl_env() step8_macros.rep("(def! a 3)", env2) self.assertEqual("2", step8_macros.rep("a", env1)) self.assertEqual("3", step8_macros.rep("a", env2)) self.assertEqual("6", step8_macros.rep("(eval (list + a 3))", env2))
def test_step4_closures(self): self.assertEqual( "12", step4_if_fn_do.rep("(( (fn* (a) (fn* (b) (+ a b))) 5) 7)", self._repl_env), ) self.assertEqual( "#<function>", step4_if_fn_do.rep("(def! gen-plus5 (fn* () (fn* (b) (+ 5 b))))", self._repl_env), ) self.assertEqual( "#<function>", step4_if_fn_do.rep("(def! gen-plus5 (fn* () (fn* (b) (+ 5 b))))", self._repl_env), ) self.assertEqual( "#<function>", step4_if_fn_do.rep("(def! plus5 (gen-plus5))", self._repl_env), ) self.assertEqual("12", step4_if_fn_do.rep("(plus5 7)", self._repl_env))
def test_tokenize_line_generator(self): lines = [ "(+\n", " 3\n", " 2)\n", ] def line_reader() -> Iterator[str]: for l in lines: yield l self.assertEqual("5", rep.rep(line_reader(), self._repl_env))
def test_step4_more(self): self.assertEqual("false", step4_if_fn_do.rep("(> 1 2)", self._repl_env)) self.assertEqual("true", step4_if_fn_do.rep("(> 2 1)", self._repl_env)) self.assertEqual("false", step4_if_fn_do.rep("(> 1 1)", self._repl_env)) try: step4_if_fn_do.rep("(> 1 nil)", self._repl_env) self.fail("Expected exception") except MalInvalidArgumentException: pass try: step4_if_fn_do.rep("(> nil 1)", self._repl_env) self.fail("Expected exception") except MalInvalidArgumentException: pass
def test_step3_let_multiple(self): self.assertEqual( "5", step3_env.rep("(let* (c 2 d 3) (+ c d))", self._repl_env))
def test_step4_str(self): self.assertEqual( '"(1 a 2 3)"', step4_if_fn_do.rep('(str (list 1 "a" 2 3))', self._repl_env))
def test_tokenize_single_line(self): self.assertEqual("5", rep.rep("(+ 3 2)", self._repl_env))
def rep(self, input: str) -> str: return step9_try.rep(input, self._repl_env)
def rep(self, input: str) -> str: return step8_macros.rep(input, self._repl_env)
def test_step4_quoted_string(self): self.assertEqual('"\\""', step4_if_fn_do.rep('"\\""', self._repl_env))
def test_step3_let_nested_backref(self): self.assertEqual( "6", step3_env.rep("(let* (c 2 d c) (+ c (+ d 2)))", self._repl_env))
def test_step7_quasiquote_advanced(self): self.assertEqual("(2)", step7_quote.rep("(def! c '(2))", self._repl_env)) self.assertEqual("(1 2 3)", step7_quote.rep("`[1 ~@c 3]", self._repl_env))
def test_step2_let_multiple(self): self.assertEqual('{"a" 15}', step2_eval.rep('{"a" (+ 7 8)} ', self._repl_env))
def test_step7_concat(self): self.assertEqual("()", step7_quote.rep("(concat)", self._repl_env))
def test_step4_use_fn(self): self.assertEqual("7", step4_if_fn_do.rep("((fn* (a) a) 7)", self._repl_env))
def test_step4_fn(self): self.assertEqual("#<function>", step4_if_fn_do.rep("(fn* (a) 0)", self._repl_env))
def test_step4_do(self): self.assertEqual("44", step4_if_fn_do.rep("(do 1 2 3 44)", self._repl_env)) self.assertEqual("21", step4_if_fn_do.rep("(do 21)", self._repl_env))
def test_step4_equal_vector_list(self): self.assertEqual("true", step4_if_fn_do.rep("(=[] (list))", self._repl_env))
def test_step4_use_fn_multiple(self): self.assertEqual( "8", step4_if_fn_do.rep("((fn* (a b) a) 8 9)", self._repl_env))
def test_step4_variadic_b(self): self.assertEqual( "0", step4_if_fn_do.rep("((fn* (& more) (count more)))", self._repl_env))
def test_step7_quasiquote(self): self.assertEqual( "(+ 1 3)", step7_quote.rep("(quasiquote (+ 1 (unquote (+ 1 2))))", self._repl_env), )
def test_step4_use_fn_multiple_nested(self): self.assertEqual( "10", step4_if_fn_do.rep("((fn* (a b) (+ a (+ b 1))) 4 5)", self._repl_env))
def test_step7_cons(self): self.assertEqual("(1)", step7_quote.rep("(cons 1 (list))", self._repl_env))
def rep(self, input: str) -> str: return rep.rep(input, self._repl_env)