diff options
| author | Joel Martin <github@martintribe.org> | 2014-04-27 17:58:48 -0500 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2014-04-27 17:58:48 -0500 |
| commit | cc021efe10380039a13da5300990639203450634 (patch) | |
| tree | 02977d571ee6b42e7d5429ff8e922f183422eeb5 | |
| parent | b58698b257fb6552e053cd245d63a140d3f7a478 (diff) | |
| download | mal-cc021efe10380039a13da5300990639203450634.tar.gz mal-cc021efe10380039a13da5300990639203450634.zip | |
Add step5/9 tests for impls that support it.
- Also remove broken make/tests/*.mk tests. Not used any more.
35 files changed, 226 insertions, 784 deletions
@@ -24,7 +24,19 @@ step8 = step8_macros step9 = step9_interop stepA = stepA_more -EXCLUDE_TESTS = test^make^step5 test^mal^step0 test^mal^step5 test^mal^step9 test^java^step9 test^cs^step9 +EXCLUDE_TESTS += test^bash^step5 # no stack exhaustion or completion +EXCLUDE_TESTS += test^c^step5 # segfault +EXCLUDE_TESTS += test^cs^step5 # fatal stack overflow fault +EXCLUDE_TESTS += test^make^step5 # no TCO capability/step +EXCLUDE_TESTS += test^mal^step5 # no TCO capability/step +EXCLUDE_TESTS += test^php^step5 # test completes, even at 100,000 +EXCLUDE_TESTS += test^ruby^step5 # test completes, even at 100,000 + +# interop tests now implemented yet +EXCLUDE_TESTS += test^cs^step9 test^java^step9 test^mal^step9 \ + test^php^step9 test^ps^step9 test^python^step9 \ + test^ruby^step9 + EXCLUDE_PERFS = perf^mal # TODO: fix this # diff --git a/bash/Makefile b/bash/Makefile index d5a0867..e171f69 100644 --- a/bash/Makefile +++ b/bash/Makefile @@ -1,5 +1,3 @@ -TESTS = tests/types.sh tests/reader.sh - SOURCES_BASE = types.sh reader.sh printer.sh SOURCES_LISP = env.sh core.sh stepA_more.sh SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) @@ -15,15 +13,9 @@ mal.sh: $(SOURCES) clean: rm -f mal.sh -.PHONY: stats tests $(TESTS) +.PHONY: stats stats: $(SOURCES) @wc $^ stats-lisp: $(SOURCES_LISP) @wc $^ - -tests: $(TESTS) - -$(TESTS): - @echo "Running $@"; \ - bash $@ || exit 1; \ diff --git a/bash/step9_interop.sh b/bash/step9_interop.sh index 5e4828f..1e00ede 100755 --- a/bash/step9_interop.sh +++ b/bash/step9_interop.sh @@ -164,7 +164,7 @@ EVAL () { while read line; do output="${output}${line}\n" done < <(eval ${ANON["${r}"]}) - _string "${output}" + _string "${output%\\n}" return ;; do) _count "${ast}" _slice "${ast}" 1 $(( ${r} - 2 )) diff --git a/bash/stepA_more.sh b/bash/stepA_more.sh index 7f582c3..6c3d6c9 100755 --- a/bash/stepA_more.sh +++ b/bash/stepA_more.sh @@ -164,7 +164,7 @@ EVAL () { while read line; do output="${output}${line}\n" done < <(eval ${ANON["${r}"]}) - _string "${output}" + _string "${output%\\n}" return ;; try*) MACROEXPAND "${a1}" "${env}" EVAL "${r}" "${env}" diff --git a/bash/tests/common.sh b/bash/tests/common.sh deleted file mode 100644 index 9924107..0000000 --- a/bash/tests/common.sh +++ /dev/null @@ -1,25 +0,0 @@ - -assert () { - if ! eval "${2}"; then - echo "assert failure line ${1}" - exit 1 - fi -} - -assert_eq () { - if eval "${3}"; then - if [[ "${2}" != "${r}" ]]; then - echo "assert_eq failure line ${1}: '${2}' != '${r}'" - exit 1 - fi - else - echo "assert_eq failure line ${1}: could not evaluate '${3}'" - exit 1 - fi -} - -TEST_RE () { - r= - READ_STR "${1}" - EVAL "${r}" ${REPL_ENV} -} diff --git a/bash/tests/reader.sh b/bash/tests/reader.sh deleted file mode 100644 index 8516b06..0000000 --- a/bash/tests/reader.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash - -INTERACTIVE= - -source tests/common.sh -source reader.sh - -echo "Testing read of constants/strings" -assert_eq $LINENO 2 "READ_STR '2'; number_pr_str \$r" -assert_eq $LINENO 12345 "READ_STR '12345'; number_pr_str \$r" -assert_eq $LINENO 12345 "READ_STR '12345 \"abc\"'; number_pr_str \$r" -assert_eq $LINENO 'abc' "READ_STR '\"abc\"'; number_pr_str \$r" -assert_eq $LINENO 'a string (with parens)' "READ_STR '\"a string (with parens)\"'; number_pr_str \$r" - -echo "Testing read of symbols" -assert $LINENO "READ_STR 'abc'; _symbol? \$r" -assert_eq $LINENO 'abc' "READ_STR 'abc'; symbol_pr_str \$r" -assert_eq $LINENO '.' "READ_STR '.'; symbol_pr_str \$r" - -raw_val () { - r="${ANON["${1}"]}" -} - -echo "Testing READ_STR of strings" -assert_eq $LINENO 'a string' "READ_STR '\"a string\"'; raw_val \$r" -assert_eq $LINENO 'a string (with parens)' "READ_STR '\"a string (with parens)\"'; raw_val \$r" -assert_eq $LINENO 'a string' "READ_STR '\"a string\"()'; raw_val \$r" -assert_eq $LINENO 'a string' "READ_STR '\"a string\"123'; raw_val \$r" -assert_eq $LINENO 'a string' "READ_STR '\"a string\"abc'; raw_val \$r" -assert_eq $LINENO '' "READ_STR '\"\"'; raw_val \$r" -assert_eq $LINENO 'abc ' "READ_STR '\"abc \"'; raw_val \$r" -assert_eq $LINENO ' abc' "READ_STR '\" abc\"'; raw_val \$r" -assert_eq $LINENO '$abc' "READ_STR '\"\$abc\"'; raw_val \$r" -assert_eq $LINENO 'abc$()' "READ_STR '\"abc\$()\"'; raw_val \$r" -# TODO: fix parsing of escaped characters -#assert_eq $LINENO '"xyz"' "READ_STR '\"\\\"xyz\\\"\"'; raw_val \$r" - -echo "Testing READ_STR of lists" -assert_eq $LINENO 2 "READ_STR '(2 3)'; _count \$r" -assert_eq $LINENO 2 "READ_STR '(2 3)'; first \$r; number_pr_str \$r" -assert_eq $LINENO 3 "READ_STR '(2 3)'; rest \$r; first \$r; number_pr_str \$r" - -READ_STR "(+ 1 2 \"str1\" \"string (with parens) and 'single quotes'\")" -L="${r}" -assert_eq $LINENO 5 "_count \$r" -assert_eq $LINENO 'str1' "_nth ${L} 3; raw_val \$r" -assert_eq $LINENO "string (with parens) and 'single quotes'" "_nth ${L} 4; raw_val \$r" -assert_eq $LINENO '(2 3)' "READ_STR '(2 3)'; list_pr_str \$r" -assert_eq $LINENO '(2 3 "string (with parens)")' "READ_STR '(2 3 \"string (with parens)\")'; list_pr_str \$r yes" - - -echo "Testing READ_STR of vectors" -assert_eq $LINENO 2 "READ_STR '[2 3]'; _count \$r" -assert_eq $LINENO 2 "READ_STR '[2 3]'; first \$r; number_pr_str \$r" -assert_eq $LINENO 3 "READ_STR '[2 3]'; rest \$r; first \$r; number_pr_str \$r" - -READ_STR "[+ 1 2 \"str1\" \"string (with parens) and 'single quotes'\"]" -L="${r}" -assert_eq $LINENO 5 "_count \$r" -assert_eq $LINENO 'str1' "_nth ${L} 3; raw_val \$r" -assert_eq $LINENO "string (with parens) and 'single quotes'" "_nth ${L} 4; raw_val \$r" -assert_eq $LINENO '[2 3]' "READ_STR '[2 3]'; vector_pr_str \$r yes" -assert_eq $LINENO '[2 3 "string (with parens)"]' "READ_STR '[2 3 \"string (with parens)\"]'; vector_pr_str \$r yes" - - -echo "Testing READ_STR of quote/quasiquote" -assert_eq $LINENO 'quote' "READ_STR \"'1\"; _nth \$r 0; raw_val \$r" -assert_eq $LINENO 1 "READ_STR \"'1\"; _nth \$r 1; raw_val \$r" -assert_eq $LINENO 'quote' "READ_STR \"'(1 2 3)\"; _nth \$r 0; raw_val \$r" -assert_eq $LINENO 3 "READ_STR \"'(1 2 3)\"; _nth \$r 1; _nth \$r 2; raw_val \$r" - -assert_eq $LINENO 'quasiquote' "READ_STR \"\\\`1\"; _nth \$r 0; raw_val \$r" -assert_eq $LINENO 1 "READ_STR \"\\\`1\"; _nth \$r 1; raw_val \$r" -assert_eq $LINENO 'quasiquote' "READ_STR \"\\\`(1 2 3)\"; _nth \$r 0; raw_val \$r" -assert_eq $LINENO 3 "READ_STR \"\\\`(1 2 3)\"; _nth \$r 1; _nth \$r 2; raw_val \$r" - -assert_eq $LINENO 'unquote' "READ_STR \"~1\"; _nth \$r 0; raw_val \$r" -assert_eq $LINENO 1 "READ_STR \"~1\"; _nth \$r 1; raw_val \$r" -assert_eq $LINENO 'unquote' "READ_STR \"~(1 2 3)\"; _nth \$r 0; raw_val \$r" -assert_eq $LINENO 3 "READ_STR \"~(1 2 3)\"; _nth \$r 1; _nth \$r 2; raw_val \$r" - -assert_eq $LINENO 'splice-unquote' "READ_STR \"~@1\"; _nth \$r 0; raw_val \$r" -assert_eq $LINENO 1 "READ_STR \"~@1\"; _nth \$r 1; raw_val \$r" -assert_eq $LINENO 'splice-unquote' "READ_STR \"~@(1 2 3)\"; _nth \$r 0; raw_val \$r" -assert_eq $LINENO 3 "READ_STR \"~@(1 2 3)\"; _nth \$r 1; _nth \$r 2; raw_val \$r" - - -echo "All tests completed" diff --git a/bash/tests/step9_interop.mal b/bash/tests/step9_interop.mal new file mode 100644 index 0000000..bf3eabd --- /dev/null +++ b/bash/tests/step9_interop.mal @@ -0,0 +1,17 @@ +;; Testing basic bash interop + +(sh* "echo 7") +;=>"7" + +(sh* "echo >&2 hello") +; hello +;=>"" + +(sh* "foo=8; echo ${foo}") +;=>"8" + +(sh* "for x in a b c; do echo -n \"X${x}Y \"; done; echo") +;=>"XaY XbY XcY" + +(sh* "for x in 1 2 3; do echo -n \"$((1+$x)) \"; done; echo") +;=>"2 3 4" diff --git a/bash/tests/types.sh b/bash/tests/types.sh deleted file mode 100644 index 0e073c5..0000000 --- a/bash/tests/types.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/bin/bash - -source tests/common.sh -source types.sh - -echo "Testing type function" -assert_eq $LINENO bash "_obj_type xyz" -assert_eq $LINENO nil "_obj_type ${__nil}" -assert_eq $LINENO true "_obj_type ${__true}" -assert_eq $LINENO false "_obj_type ${__false}" - - -echo "Testing number? function" -assert_eq $LINENO number "number 1; _obj_type \$r" -assert_eq $LINENO number "number 10; _obj_type \$r" -assert_eq $LINENO number "number 12345; _obj_type \$r" - - -echo "Testing symbols" -assert_eq $LINENO symbol "symbol abc; _obj_type \$r" -symbol "a sym value"; SYM1="${r}" -assert_eq $LINENO "a sym value" "symbol_pr_str ${SYM1} yes" -assert_eq $LINENO ${__true} "symbol? ${SYM1}" - - -echo "Testing strings" -assert_eq $LINENO string "string abc; _obj_type \$r" -string "a string value"; STR1="${r}" -assert_eq $LINENO "\"a string value\"" "string_pr_str ${STR1} yes" -assert_eq $LINENO ${__true} "string? ${STR1}" -# TODO: fix to count characters instead of words -#assert_eq $LINENO 14 "_count ${STR1}" - -string "a string (with parens)"; STR2="${r}" -assert_eq $LINENO "\"a string (with parens)\"" "string_pr_str ${STR2} yes" -assert_eq $LINENO ${__true} "string? ${STR2}" - -# TODO: test str and subs - - -echo "Testing function objects" -assert_eq $LINENO "function" "_function \"echo hello\"; _obj_type \$r" -_function "r=\"arg1:'\$1' arg2:'\$2'\""; FN1="${r}" -assert_eq $LINENO ${__true} "function? ${FN1}" -assert_eq $LINENO "arg1:'A' arg2:'B'" "${ANON["${FN1}"]} A B" - - - -echo "Testing lists" -list; LE="${r}" -assert_eq $LINENO list "_obj_type ${LE}" - -echo "Testing lists (cons)" -list; cons P ${r}; L1="${r}" -cons Q ${L1}; L2="${r}" -assert_eq $LINENO ${__true} "list? ${L1}" -assert_eq $LINENO ${__true} "list? ${L2}" -assert_eq $LINENO P "first ${L1}" -assert_eq $LINENO 2 "_count ${L2}" -assert_eq $LINENO Q "first ${L2}" -assert_eq $LINENO P "_nth ${L2} 1" -rest ${L2}; L2R="${r}" - -echo "Testing lists (concat)" -concat ${L1} ${L2}; L1_2="${r}" -assert_eq $LINENO 3 "_count ${L1_2}" -assert_eq $LINENO P "first ${L1_2}" -assert_eq $LINENO Q "_nth ${L1_2} 1" -assert_eq $LINENO P "_nth ${L1_2} 2" -rest ${L1_2}; L1_2R="${r}" - -echo "Testing lists (conj)" -list; conj ${r} A B; L3="${r}" -list; conj ${r} X ${L3}; L4="${r}" -assert_eq $LINENO ${__true} "list? ${L3}" -assert_eq $LINENO ${__true} "list? ${L4}" -assert_eq $LINENO A "first ${L3}" -assert_eq $LINENO X "first ${L4}" -_nth ${L4} 1; L4_1="${r}" -assert_eq $LINENO ${__true} "list? ${L4_1}" -assert_eq $LINENO A "first ${L4_1}" - - -echo "Testing hash maps" -hash_map; X="${r}" -hash_map; Y="${r}" -assert_eq $LINENO ${__true} "hash_map? ${X}" -assert_eq $LINENO ${__true} "hash_map? ${Y}" - -string "a" -mykey="${r}" -assert_eq $LINENO "" "_get ${X} a" -assert_eq $LINENO ${__false} "contains? ${X} ${mykey}" -assoc! ${X} a 'value of X a' -assert_eq $LINENO "value of X a" "_get ${X} a" -assert_eq $LINENO ${__true} "contains? ${X} ${mykey}" - -# TODO: more testing of Y, assoc!, dissoc! - - -# TODO: vectors - - -echo "Testing _map/map function" -list; conj "${r}" 1 2 3; L5="${r}" -inc () { r=$(( ${1} + 1)); } -assert_eq $LINENO "2 3 4" "_map inc ${L5}; r=\${ANON[\$r]}" -_function "r=\$(( \$1 + 1 ));"; inc_func="${r}" -assert_eq $LINENO "2 3 4" "map ${inc_func} ${L5}; r=\${ANON[\$r]}" - - -echo "Testing equal? function" -assert_eq $LINENO ${__true} "equal? 2 2" -assert_eq $LINENO ${__false} "equal? 2 3" -assert_eq $LINENO ${__false} "equal? 2 3" -assert_eq $LINENO ${__true} "equal? abc abc" -assert_eq $LINENO ${__false} "equal? abc abz" -assert_eq $LINENO ${__false} "equal? zbc abc" -assert_eq $LINENO ${__true} "string abc; A=\$r; string abc; B=\$r; equal? \$A \$B" -assert_eq $LINENO ${__false} "string abc; A=\$r; string abz; B=\$r; equal? \$A \$B" -assert_eq $LINENO ${__false} "string zbc; A=\$r; string abc; B=\$r; equal? \$A \$B" -assert_eq $LINENO ${__true} "symbol abc; A=\$r; symbol abc; B=\$r; equal? \$A \$B" -assert_eq $LINENO ${__false} "symbol abc; A=\$r; symbol abz; B=\$r; equal? \$A \$B" -assert_eq $LINENO ${__false} "symbol zbc; A=\$r; symbol abc; B=\$r; equal? \$A \$B" -list; conj "${r}" 1 2 3; L6="${r}" -list; conj "${r}" 1 2 3; L7="${r}" -list; conj "${r}" 1 2 Z; L8="${r}" -list; conj "${r}" Z 2 3; L9="${r}" -list; conj "${r}" 1 2; L10="${r}" -assert_eq $LINENO ${__true} "equal? ${L6} ${L7}" -assert_eq $LINENO ${__false} "equal? ${L6} ${L8}" -assert_eq $LINENO ${__false} "equal? ${L6} ${L9}" -assert_eq $LINENO ${__false} "equal? ${L6} ${L10}" -assert_eq $LINENO ${__false} "equal? ${L10} ${L6}" - -# TODO: empty? function tests - -echo "Testing ENV environment (1 level)" -ENV; env1="${r}" -assert_eq $LINENO "" "ENV_GET \"${env1}\" a" -ENV_SET "${env1}" a "val_a" -ENV_SET "${env1}" b "val_b" -ENV_SET "${env1}" = "val_eq" -assert_eq $LINENO "val_a" "ENV_GET \"${env1}\" a" -assert_eq $LINENO "val_b" "ENV_GET \"${env1}\" b" -assert_eq $LINENO "val_eq" "ENV_GET \"${env1}\" =" -assert_eq $LINENO "${env1}" "ENV_FIND \"${env1}\" =" - -echo "Testing ENV environment (2 levels)" -ENV "${env1}"; env2="${r}" -ENV_SET "${env2}" b "val_b2" -ENV_SET "${env2}" c "val_c" -assert_eq $LINENO "${env1}" "ENV_FIND \"${env2}\" a" -assert_eq $LINENO "${env2}" "ENV_FIND \"${env2}\" b" -assert_eq $LINENO "${env2}" "ENV_FIND \"${env2}\" c" -assert_eq $LINENO "val_a" "ENV_GET \"${env2}\" a" -assert_eq $LINENO "val_b2" "ENV_GET \"${env2}\" b" -assert_eq $LINENO "val_c" "ENV_GET \"${env2}\" c" - - -echo "All tests completed" diff --git a/clojure/Makefile b/clojure/Makefile index 376d107..2ddfbcc 100644 --- a/clojure/Makefile +++ b/clojure/Makefile @@ -1,21 +1,12 @@ - -TESTS = - SOURCES_BASE = src/readline.clj src/reader.clj src/printer.clj SOURCES_LISP = src/env.clj src/core.clj src/stepA_more.clj SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) all: -.PHONY: stats tests $(TESTS) +.PHONY: stats stats: $(SOURCES) @wc $^ stats-lisp: $(SOURCES_LISP) @wc $^ - -tests: $(TESTS) - -$(TESTS): - @echo "Running $@"; \ - lein with-profile XXX$@XXX trampoline run || exit 1; \ diff --git a/clojure/tests/step9_interop.mal b/clojure/tests/step9_interop.mal new file mode 100644 index 0000000..b323222 --- /dev/null +++ b/clojure/tests/step9_interop.mal @@ -0,0 +1,17 @@ +;; Testing basic clojure interop + +(clj* "7") +;=>7 + +(clj* "\"abc\"") +;=>"abc" + +(clj* "{\"abc\" 123}") +;=>{"abc" 123} + +(clj* "(prn \"foo\")") +; "foo" +;=>nil + +(clj* "(for [x [1 2 3]] (+ 1 x))") +;=>(2 3 4) diff --git a/java/src/main/java/mal/step1_read_print.java b/java/src/main/java/mal/step1_read_print.java index 2c029aa..e849052 100644 --- a/java/src/main/java/mal/step1_read_print.java +++ b/java/src/main/java/mal/step1_read_print.java @@ -49,11 +49,11 @@ public class step1_read_print { System.out.println(PRINT(RE(null, line))); } catch (MalContinue e) { continue; - } catch (MalError e) { - System.out.println("Error: " + e.getMessage()); + } catch (MalThrowable t) { + System.out.println("Error: " + t.getMessage()); continue; - } catch (reader.ParseError e) { - System.out.println(e.getMessage()); + } catch (Throwable t) { + System.out.println("Uncaught " + t + ": " + t.getMessage()); continue; } } diff --git a/java/src/main/java/mal/step2_eval.java b/java/src/main/java/mal/step2_eval.java index ee8ea26..6de69cd 100644 --- a/java/src/main/java/mal/step2_eval.java +++ b/java/src/main/java/mal/step2_eval.java @@ -126,11 +126,11 @@ public class step2_eval { System.out.println(PRINT(RE(repl_env, line))); } catch (MalContinue e) { continue; - } catch (reader.ParseError e) { - System.out.println(e.getMessage()); + } catch (MalThrowable t) { + System.out.println("Error: " + t.getMessage()); continue; - } catch (MalError e) { - System.out.println("Error: " + e.getMessage()); + } catch (Throwable t) { + System.out.println("Uncaught " + t + ": " + t.getMessage()); continue; } } diff --git a/java/src/main/java/mal/step3_env.java b/java/src/main/java/mal/step3_env.java index 0bf5c16..a88dc13 100644 --- a/java/src/main/java/mal/step3_env.java +++ b/java/src/main/java/mal/step3_env.java @@ -146,11 +146,11 @@ public class step3_env { System.out.println(PRINT(RE(repl_env, line))); } catch (MalContinue e) { continue; - } catch (reader.ParseError e) { - System.out.println(e.getMessage()); + } catch (MalThrowable t) { + System.out.println("Error: " + t.getMessage()); continue; - } catch (MalError e) { - System.out.println("Error: " + e.getMessage()); + } catch (Throwable t) { + System.out.println("Uncaught " + t + ": " + t.getMessage()); continue; } } diff --git a/java/src/main/java/mal/step4_if_fn_do.java b/java/src/main/java/mal/step4_if_fn_do.java index 9a66542..ce9043d 100644 --- a/java/src/main/java/mal/step4_if_fn_do.java +++ b/java/src/main/java/mal/step4_if_fn_do.java @@ -154,12 +154,12 @@ public class step4_if_fn_do { System.out.println(PRINT(RE(repl_env, line))); } catch (MalContinue e) { continue; - } catch (reader.ParseError e) { - System.out.println(e.getMessage()); - continue; } catch (MalThrowable t) { System.out.println("Error: " + t.getMessage()); continue; + } catch (Throwable t) { + System.out.println("Uncaught " + t + ": " + t.getMessage()); + continue; } } } diff --git a/java/src/main/java/mal/step5_tco.java b/java/src/main/java/mal/step5_tco.java index aa3f7a7..ef56083 100644 --- a/java/src/main/java/mal/step5_tco.java +++ b/java/src/main/java/mal/step5_tco.java @@ -167,12 +167,12 @@ public class step5_tco { System.out.println(PRINT(RE(repl_env, line))); } catch (MalContinue e) { continue; - } catch (reader.ParseError e) { - System.out.println(e.getMessage()); - continue; } catch (MalThrowable t) { System.out.println("Error: " + t.getMessage()); continue; + } catch (Throwable t) { + System.out.println("Uncaught " + t + ": " + t.getMessage()); + continue; } } } diff --git a/java/src/main/java/mal/step6_file.java b/java/src/main/java/mal/step6_file.java index d3f4914..56bcdf7 100644 --- a/java/src/main/java/mal/step6_file.java +++ b/java/src/main/java/mal/step6_file.java @@ -185,12 +185,12 @@ public class step6_file { System.out.println(PRINT(RE(repl_env, line))); } catch (MalContinue e) { continue; - } catch (reader.ParseError e) { - System.out.println(e.getMessage()); - continue; } catch (MalThrowable t) { System.out.println("Error: " + t.getMessage()); continue; + } catch (Throwable t) { + System.out.println("Uncaught " + t + ": " + t.getMessage()); + continue; } } } diff --git a/java/src/main/java/mal/step7_quote.java b/java/src/main/java/mal/step7_quote.java index 639f8b9..8c3766a 100644 --- a/java/src/main/java/mal/step7_quote.java +++ b/java/src/main/java/mal/step7_quote.java @@ -217,12 +217,12 @@ public class step7_quote { System.out.println(PRINT(RE(repl_env, line))); } catch (MalContinue e) { continue; - } catch (reader.ParseError e) { - System.out.println(e.getMessage()); - continue; } catch (MalThrowable t) { System.out.println("Error: " + t.getMessage()); continue; + } catch (Throwable t) { + System.out.println("Uncaught " + t + ": " + t.getMessage()); + continue; } } } diff --git a/java/src/main/java/mal/step8_macros.java b/java/src/main/java/mal/step8_macros.java index fb3ffdc..4c89356 100644 --- a/java/src/main/java/mal/step8_macros.java +++ b/java/src/main/java/mal/step8_macros.java @@ -257,12 +257,12 @@ public class step8_macros { System.out.println(PRINT(RE(repl_env, line))); } catch (MalContinue e) { continue; - } catch (reader.ParseError e) { - System.out.println(e.getMessage()); - continue; } catch (MalThrowable t) { System.out.println("Error: " + t.getMessage()); continue; + } catch (Throwable t) { + System.out.println("Uncaught " + t + ": " + t.getMessage()); + continue; } } } diff --git a/java/src/main/java/mal/stepA_more.java b/java/src/main/java/mal/stepA_more.java index 75ec301..7e869e6 100644 --- a/java/src/main/java/mal/stepA_more.java +++ b/java/src/main/java/mal/stepA_more.java @@ -287,15 +287,15 @@ public class stepA_more { System.out.println(PRINT(RE(repl_env, line))); } catch (MalContinue e) { continue; - } catch (reader.ParseError e) { - System.out.println(e.getMessage()); - continue; } catch (MalException e) { System.out.println("Error: " + printer._pr_str(e.getValue(), false)); continue; } catch (MalThrowable t) { System.out.println("Error: " + t.getMessage()); continue; + } catch (Throwable t) { + System.out.println("Uncaught " + t + ": " + t.getMessage()); + continue; } } } diff --git a/js/Makefile b/js/Makefile index 02678fb..454e481 100644 --- a/js/Makefile +++ b/js/Makefile @@ -1,5 +1,5 @@ -TESTS = tests/types.js tests/reader.js tests/step5_tco.js +TESTS = tests/types.js tests/reader.js SOURCES_BASE = node_readline.js types.js reader.js printer.js SOURCES_LISP = env.js core.js stepA_more.js diff --git a/js/tests/step5_tco.js b/js/tests/step5_tco.js deleted file mode 100644 index 60c0576..0000000 --- a/js/tests/step5_tco.js +++ /dev/null @@ -1,22 +0,0 @@ -common = require('./common.js'); -var assert_eq = common.assert_eq; -var rep = require('../step5_tco.js').rep; - -console.log("Testing Stack Exhaustion Function"); -rep('(def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1))))))'); -try { - rep('(sum-to 10000)'); - throw new Error("Did not get expected stack exhaustion"); -} catch (e) { - if (e.toString().match(/RangeError/)) { - console.log("Got expected stack exhaustion"); - } else { - throw new Error("Unexpected error: " + e); - } -} - -console.log("Testing Tail Call Optimization/Elimination"); -rep('(def! sum2 (fn* (n acc) (if (= n 0) acc (sum2 (- n 1) (+ n acc)))))'); -rep('(sum2 10000 0)'); - -console.log("All tests completed"); diff --git a/js/tests/step9_interop.mal b/js/tests/step9_interop.mal new file mode 100644 index 0000000..f785292 --- /dev/null +++ b/js/tests/step9_interop.mal @@ -0,0 +1,24 @@ +;; Testing basic bash interop + +(js* "7") +;=>7 + +(js* "'7'") +;=>"7" + +(js* "[7,8,9]") +;=>(7 8 9) + +(js* "console.log('hello');") +; hello +;=>nil + +(js* "foo=8;") +(js* "foo;") +;=>8 + +(js* "['a','b','c'].map(function(x){return 'X'+x+'Y'}).join(' ')") +;=>"XaY XbY XcY" + +(js* "[1,2,3].map(function(x){return 1+x})") +;=>(2 3 4) diff --git a/make/rules.mk b/make/rules.mk new file mode 100644 index 0000000..a73dba5 --- /dev/null +++ b/make/rules.mk @@ -0,0 +1,34 @@ +# To load this file: +# $(eval include rules.mk) + +# Usage: +# (make* "$(eval $(call PRINT_RULE,abc,,@echo \"building $$@\"))") +define PRINT_RULE +$(1): $(2) + $(3) +endef + +# Usage: +# (make* "$(eval $(call PRINT_LINES,abc:, @echo \"shell command\"))") +define PRINT_LINES +$(1) +$(2) +$(3) +$(4) +$(5) +$(6) +$(7) +$(8) +$(9) +$(10) +$(11) +$(12) +$(13) +$(14) +$(15) +$(16) +$(17) +$(18) +$(19) +$(20) +endef diff --git a/make/step6_file.mk b/make/step6_file.mk index f779d12..f0298a9 100644 --- a/make/step6_file.mk +++ b/make/step6_file.mk @@ -119,9 +119,10 @@ $(if $(MAKECMDGOALS),\ $(call do,$(call _conj!,$(_argv),$(call _string,$(arg)))))\ $(call do,$(call REP, (load-file "$(word 1,$(MAKECMDGOALS))") )) \ $(eval INTERACTIVE :=),) -.PHONY: none $(MAKECMDGOALS) -none $(MAKECMDGOALS): - @true # repl loop $(if $(strip $(INTERACTIVE)),$(call REPL)) + +.PHONY: none $(MAKECMDGOALS) +none $(MAKECMDGOALS): + @true diff --git a/make/step7_quote.mk b/make/step7_quote.mk index c734ad1..df3745f 100644 --- a/make/step7_quote.mk +++ b/make/step7_quote.mk @@ -136,9 +136,10 @@ $(if $(MAKECMDGOALS),\ $(call do,$(call _conj!,$(_argv),$(call _string,$(arg)))))\ $(call do,$(call REP, (load-file "$(word 1,$(MAKECMDGOALS))") )) \ $(eval INTERACTIVE :=),) -.PHONY: none $(MAKECMDGOALS) -none $(MAKECMDGOALS): - @true # repl loop $(if $(strip $(INTERACTIVE)),$(call REPL)) + +.PHONY: none $(MAKECMDGOALS) +none $(MAKECMDGOALS): + @true diff --git a/make/step8_macros.mk b/make/step8_macros.mk index 5a0007c..96e5d31 100644 --- a/make/step8_macros.mk +++ b/make/step8_macros.mk @@ -161,9 +161,10 @@ $(if $(MAKECMDGOALS),\ $(call do,$(call _conj!,$(_argv),$(call _string,$(arg)))))\ $(call do,$(call REP, (load-file "$(word 1,$(MAKECMDGOALS))") )) \ $(eval INTERACTIVE :=),) -.PHONY: none $(MAKECMDGOALS) -none $(MAKECMDGOALS): - @true # repl loop $(if $(strip $(INTERACTIVE)),$(call REPL)) + +.PHONY: none $(MAKECMDGOALS) +none $(MAKECMDGOALS): + @true diff --git a/make/step9_interop.mk b/make/step9_interop.mk index 07ad5a3..984740a 100644 --- a/make/step9_interop.mk +++ b/make/step9_interop.mk @@ -102,7 +102,7 @@ $(if $(__ERROR),,\ $(if $(call _EQ,make*,$($(a0)_value)),\ $(foreach a1,$(call _nth,$(1),1),\ $(and $(EVAL_DEBUG),$(info make*: $$(eval __result := $(call str_decode,$(value $(a1)_value)))))\ - $(eval __result := $(call str_decode,$(value $(a1)_value)))$(call READ_STR,$(__result))),\ + $(eval __result := $(call str_decode,$(value $(a1)_value)))$(call _string,$(__result))),\ $(if $(call _EQ,do,$($(a0)_value)),\ $(call slast,$(call EVAL_AST,$(call srest,$(1)),$(2))),\ $(if $(call _EQ,if,$($(a0)_value)),\ @@ -165,9 +165,10 @@ $(if $(MAKECMDGOALS),\ $(call do,$(call _conj!,$(_argv),$(call _string,$(arg)))))\ $(call do,$(call REP, (load-file "$(word 1,$(MAKECMDGOALS))") )) \ $(eval INTERACTIVE :=),) -.PHONY: none $(MAKECMDGOALS) -none $(MAKECMDGOALS): - @true # repl loop $(if $(strip $(INTERACTIVE)),$(call REPL)) + +.PHONY: none $(MAKECMDGOALS) +none $(MAKECMDGOALS): + @true diff --git a/make/stepA_more.mk b/make/stepA_more.mk index dc07b01..050366c 100644 --- a/make/stepA_more.mk +++ b/make/stepA_more.mk @@ -102,7 +102,7 @@ $(if $(__ERROR),,\ $(if $(call _EQ,make*,$($(a0)_value)),\ $(foreach a1,$(call _nth,$(1),1),\ $(and $(EVAL_DEBUG),$(info make*: $$(eval __result := $(call str_decode,$(value $(a1)_value)))))\ - $(eval __result := $(call str_decode,$(value $(a1)_value)))$(call READ_STR,$(__result))),\ + $(eval __result := $(call str_decode,$(value $(a1)_value)))$(call _string,$(__result))),\ $(if $(call _EQ,try*,$($(a0)_value)),\ $(foreach a1,$(call _nth,$(1),1),\ $(foreach res,$(call EVAL,$(a1),$(2)),\ @@ -181,11 +181,12 @@ $(if $(MAKECMDGOALS),\ $(call do,$(call _conj!,$(_argv),$(call _string,$(arg)))))\ $(call do,$(call REP, (load-file "$(word 1,$(MAKECMDGOALS))") )) \ $(eval INTERACTIVE :=),) -.PHONY: none $(MAKECMDGOALS) -none $(MAKECMDGOALS): - @true # repl loop $(if $(strip $(INTERACTIVE)),\ $(call do,$(call REP, (println (str "Mal [" *host-language* "]")) )) \ $(call REPL)) + +.PHONY: none $(MAKECMDGOALS) +none $(MAKECMDGOALS): + @true diff --git a/make/tests/common.mk b/make/tests/common.mk deleted file mode 100644 index 55b931d..0000000 --- a/make/tests/common.mk +++ /dev/null @@ -1,18 +0,0 @@ - -# assert macros -assert = $(if $1,,$(error assert failure: $2)) -assert_not = $(if $1,$(error assert_not: $2),) -assert_eq = $(if $(call _EQ,$(1),$(2)),,$(error assert_eq failure: $(1) != $(2): $(3))) -# With debug: -#assert_eq = $(info 1: $(1))$(info 2: $(2))$(info 3: $(3))$(if $(call _EQ,$(1),$(2)),,$(error assert_eq failure: $(3))) - - -# REPL related wrappers -test_read = $(call READ_STR,$(1)) -ifndef MACROEXPAND -define MACROEXPAND -$(1) -endef -endif -test_re = $(strip $(call EVAL,$(call MACROEXPAND,$(strip $(call test_read,$(1))),$(REPL_ENV)),$(REPL_ENV))) -test_rep = $(call PRINT,$(strip $(call EVAL,$(call MACROEXPAND,$(strip $(call test_read,$(1))),$(REPL_ENV)),$(REPL_ENV)))) diff --git a/make/tests/reader.mk b/make/tests/reader.mk deleted file mode 100644 index 672d27b..0000000 --- a/make/tests/reader.mk +++ /dev/null @@ -1,76 +0,0 @@ -INTERACTIVE = no - -include tests/common.mk -include reader.mk - -_tonum = $(call int_decode,$($(1)_value)) - -$(info Testing READ_STR of numbers) -$(call assert_eq,2,$(call _tonum,$(call READ_STR,2))) -$(call assert_eq,12345,$(call _tonum,$(call READ_STR,12345))) -$(call assert_eq,12345,$(call _tonum,$(call READ_STR,12345 "abc"))) -$(call assert_eq,12345,$(call _tonum,$(call READ_STR,12345"abc"))) -$(call assert_eq,12345,$(call _tonum,$(call READ_STR,12345(1)))) - -$(info Testing READ_STR of symbols) -$(call assert_eq,abc,$($(call READ_STR,abc)_value)) -$(call assert_eq,abc,$($(call READ_STR,abc )_value)) -$(call assert_eq,abc,$($(call READ_STR,abc"a str")_value)) -$(call assert_eq,abc,$($(call READ_STR,abc(2 3))_value)) - -$(info Testing READ_STR of strings) -$(call assert_eq,a string,$(call str_decode,$($(call READ_STR,"a string")_value))) -$(call assert_eq,a string (with parens),$(call str_decode,$($(call READ_STR,"a string (with parens)")_value))) -$(call assert_eq,a string,$(call str_decode,$($(call READ_STR,"a string"())_value))) -$(call assert_eq,a string,$(call str_decode,$($(call READ_STR,"a string"123)_value))) -$(call assert_eq,a string,$(call str_decode,$($(call READ_STR,"a string"abc)_value))) -$(call assert_eq,,$(call str_decode,$($(call READ_STR,"")_value))) -$(call assert_eq,abc ,$(call str_decode,$($(call READ_STR,"abc ")_value))) -$(call assert_eq, abc,$(call str_decode,$($(call READ_STR," abc")_value))) -$(call assert_eq,$$abc,$(call str_decode,$($(call READ_STR,"$$abc")_value))) -$(call assert_eq,abc$$(),$(call str_decode,$($(call READ_STR,"abc$$()")_value))) -$(call assert_eq,"xyz",$(call str_decode,$($(call READ_STR,"\"xyz\"")_value))) - -$(info Testing READ_STR of lists) -$(call assert_eq,2,$(call _count,$(call READ_STR,(2 3)))) -$(call assert_eq,2,$(call _tonum,$(call sfirst,$(call READ_STR,(2 3))))) -$(call assert_eq,3,$(call _tonum,$(call sfirst,$(call srest,$(call READ_STR,(2 3)))))) -L := $(strip $(call READ_STR,(+ 1 2 "str1" "string (with parens) and 'single quotes'"))) -$(call assert_eq,5,$(call _count,$(L))) -$(call assert_eq,str1,$(call str_decode,$($(call _nth,$(L),3)_value))) -$(call assert_eq,string (with parens) and 'single quotes',$(call str_decode,$($(call _nth,$(L),4)_value))) - -$(info Testing READ_STR of vectors) -$(call assert_eq,2,$(call _count,$(call READ_STR,[2 3]))) -$(call assert_eq,2,$(call _tonum,$(call sfirst,$(call READ_STR,[2 3])))) -$(call assert_eq,3,$(call _tonum,$(call sfirst,$(call srest,$(call READ_STR,[2 3]))))) -L := $(strip $(call READ_STR,[+ 1 2 "str1" "string (with parens) and 'single quotes'"])) -$(call assert_eq,5,$(call _count,$(L))) -$(call assert_eq,str1,$(call str_decode,$($(call _nth,$(L),3)_value))) -$(call assert_eq,string (with parens) and 'single quotes',$(call str_decode,$($(call _nth,$(L),4)_value))) - -$(info Testing READ_STR of quote/quasiquote) -$(call assert_eq,quote,$($(call _nth,$(call READ_STR,'1),0)_value)) #' -$(call assert_eq,1,$(call _tonum,$(call _nth,$(call READ_STR,'1),1))) #' -$(call assert_eq,quote,$($(call _nth,$(call READ_STR,'(1 2 3)),0)_value)) #' -$(call assert_eq,3,$(call _tonum,$(call _nth,$(call _nth,$(call READ_STR,'(1 2 3)),1),2))) #' - -$(call assert_eq,quasiquote,$($(call _nth,$(call READ_STR,`1),0)_value)) -$(call assert_eq,1,$(call _tonum,$(call _nth,$(call READ_STR,`1),1))) -$(call assert_eq,quasiquote,$($(call _nth,$(call READ_STR,`(1 2 3)),0)_value)) -$(call assert_eq,3,$(call _tonum,$(call _nth,$(call _nth,$(call READ_STR,`(1 2 3)),1),2))) - -$(call assert_eq,unquote,$($(call _nth,$(call READ_STR,~1),0)_value)) -$(call assert_eq,1,$(call _tonum,$(call _nth,$(call READ_STR,~1),1))) -$(call assert_eq,unquote,$($(call _nth,$(call READ_STR,~(1 2 3)),0)_value)) -$(call assert_eq,3,$(call _tonum,$(call _nth,$(call _nth,$(call READ_STR,~(1 2 3)),1),2))) - -$(call assert_eq,splice-unquote,$($(call _nth,$(call READ_STR,~@1),0)_value)) -$(call assert_eq,1,$(call _tonum,$(call _nth,$(call READ_STR,~@1),1))) -$(call assert_eq,splice-unquote,$($(call _nth,$(call READ_STR,~@(1 2 3)),0)_value)) -$(call assert_eq,3,$(call _tonum,$(call _nth,$(call _nth,$(call READ_STR,~@(1 2 3)),1),2))) - - -.PHONY: all -all: - @echo "All tests completed" diff --git a/make/tests/step9_interop.mal b/make/tests/step9_interop.mal new file mode 100644 index 0000000..9b1a2f9 --- /dev/null +++ b/make/tests/step9_interop.mal @@ -0,0 +1,19 @@ +;; Testing basic make interop + +(make* "7") +;=>"7" + +(make* "$(info foo)") +; foo +;=>"" + +(make* "$(eval foo := 8)") +(make* "$(foo)") +;=>"8" + +(make* "$(foreach v,a b c,X$(v)Y)") +;=>"XaY XbY XcY" + +(read-string (make* "($(foreach v,1 2 3,$(call gmsl_plus,1,$(v))))")) +;=>(2 3 4) + diff --git a/make/tests/step9_interop.mk b/make/tests/step9_interop.mk deleted file mode 100644 index 0e44a88..0000000 --- a/make/tests/step9_interop.mk +++ /dev/null @@ -1,14 +0,0 @@ -INTERACTIVE = - -include tests/common.mk -include step9_interop.mk - -$(info Testing trivial macros) -$(call assert_eq,7,$(call test_rep, (make* "7") )) -$(call assert_eq,"XaY XbY XcY",$(call test_rep, (make* "\"$(foreach v,a b c,X$(v)Y)\"") )) -$(call assert_eq,(2 3 4),$(call test_rep, (make* "($(foreach v,1 2 3,$(call gmsl_plus,1,$(v))))") )) - - -.PHONY: all -all: - @echo "All tests completed" diff --git a/make/tests/types.mk b/make/tests/types.mk deleted file mode 100644 index a100afe..0000000 --- a/make/tests/types.mk +++ /dev/null @@ -1,304 +0,0 @@ -include tests/common.mk -include types.mk - -# treat an expression as a statement -do = $(eval __tmp := $(1)) - - -$(info Testing foreach as a let form) - -$(call assert_eq,XbX,$(foreach local_var,b,X$(local_var)X),\ - Using foreach as 'let' failed) - - -$(info Testing type function) -$(call assert_eq,make,$(call _obj_type,xyz),\ - (type xyz) is not 'make') -$(call assert_eq,nil,$(call _obj_type,$(__nil)),\ - (type $$(__nil)) is not 'nil') -$(call assert_eq,true,$(call _obj_type,$(__true)),\ - (type $$(__true)) is not 'true') -$(call assert_eq,false,$(call _obj_type,$(__false)),\ - (type $$(__false)) is not 'false') - - -$(info Testing number? function) - -$(call assert_eq,number,$(call _obj_type,$(call number,1))) -$(call assert_eq,number,$(call _obj_type,$(call number,10))) -$(call assert_eq,number,$(call _obj_type,$(call number,12345))) - - -$(info Testing symbols) - -$(call assert_eq,symbol,$(call _obj_type,$(call symbol,abc)),\ - (type (symbol abc)) is not 'symbol') -SYM1 := $(call symbol,a sym value) -$(call assert_eq,a sym value,$($(SYM1)_value)) -$(call assert_eq,$(__true),$(call symbol?,$(SYM1))) - - -$(info Testing strings) - -$(call assert_eq,string,$(call _obj_type,$(call string,abc)),\ - (type (string abc)) is not string) - -STR1 := $(call string,a string value) -$(call assert_eq,a string value,$(call str_decode,$($(STR1)_value))) -$(call assert_eq,$(__true),$(call string?,$(STR1))) -$(call assert_eq,14,$(call _count,$(STR1))) - -STR2 := $(call string,a string (with parens)) -$(call assert_eq,a string (with parens),$(call str_decode,$($(STR2)_value))) -$(call assert_eq,$(__true),$(call string?,$(STR2))) -$(call assert_eq,22,$(call _count,$(STR2))) - -$(info Testing strings (subs)) -$(call assert_eq,a string (with parens),$(call str_decode,$($(call subs,$(STR2),$(call number,2))_value))) -$(call assert_eq,a string,$(call str_decode,$($(call subs,$(STR2),$(call number,0),$(call number,8))_value))) - -$(info Testing strings (str)) -$(call assert_eq,a string value - a string (with parens),$(call str_decode,$($(call str,$(STR1) $(call string, - ) $(STR2))_value))) - - -$(info Testing function objects) - -$(call assert_eq,function,$(call _obj_type,$(call _function,abc)),\ - (type (function abc)) is not 'function') -FN1 := $(call _function,arg1:'$$(word 1,$$(1))' arg2:'$$(word 2,$$(1))') -$(call assert_eq,$(__true),$(call function?,$(FN1))) -$(call assert_eq,arg1:'A' arg2:'B',$(call apply,$(FN1),$(call list,A B))) - - -$(info Testing lists) - -$(call assert_eq,list,$(call _obj_type,$(call list)),\ - (type (list)) is not 'list') - -$(info Testing lists (cons)) -L1 := $(call cons,P $(call list)) -L2 := $(call cons,Q $(L1)) -$(call assert_eq,$(__true),$(call list?,$(L1))) -$(call assert_eq,$(__true),$(call list?,$(L2))) -$(call assert_eq,P,$(call sfirst,$(L1))) -$(call assert_eq,2,$(call _count,$(L2))) -$(call assert_eq,Q,$(call sfirst,$(L2))) -$(call assert_eq,P,$(call _nth,$(L2),1)) -$(call assert_eq,$(__true),$(call equal?,$(L1) $(call srest,$(L2)))) - -$(info Testing lists (concat)) -L1_2 := $(call concat,$(L1) $(L2)) -$(call assert_eq,3,$(call _count,$(L1_2))) -$(call assert_eq,P,$(call sfirst,$(L1_2))) -$(call assert_eq,Q,$(call _nth,$(L1_2),1)) -$(call assert_eq,P,$(call _nth,$(L1_2),2)) -$(call assert_eq,$(__true),$(call equal?,$(L2) $(call srest,$(L1_2)))) - -$(info Testing lists (conj)) -L3 := $(call _conj!,$(call list),A B) -L4 := $(call _conj!,$(call list),X $(L3)) -$(call assert_eq,$(__true),$(call list?,$(L3)),\ - (list? $$(L3))) -$(call assert_eq,$(__true),$(call list?,$(L4)),\ - (list? $$(L3))) -$(call assert_eq,A,$(call sfirst,$(L3)),\ - (sfirst $$(L3)) is not 'A') -$(call assert_eq,X,$(call sfirst,$(L4)),\ - (sfirst $$(L4)) is not 'X') -$(call assert_eq,$(__true),$(call list?,$(call _nth,$(L4),1)),\ - (_nth $$(L4),1) is not a list) -$(call assert_eq,A,$(call sfirst,$(call _nth,$(L4),1)),\ - (first (_nth $$(L4),1)) is not 'A') - - -$(info Testing hash_maps) - -X := $(call _hash_map) -$(call assert_eq,$(__true),$(call hash_map?,$(X)),\ - (hash_map? $$(X))) -$(call assert_eq,$(__false),$(call vector?,$(X)),\ - (vector? $$(X))) - -mykey := $(call _string,a) -$(call assert_not,$(call _get,$(X),a),\ - (get $$(X),a)) -$(call assert_eq,$(__false),$(call contains?,$(X),$(mykey)),\ - (contains? $$(X),a)) -$(call do,$(call _assoc!,$(X),a,value of X a)) -$(call assert_eq,value of X a,$(call _get,$(X),a),\ - (get $$(X),a) is not 'value of Xa') -$(call assert_eq,$(__true),$(call contains?,$(X) $(mykey)),\ - (contains? $$(X),a)) - -Y := $(call _hash_map) -$(call assert_eq,0,$(call _count,$(Y)),\ - (_count $$(Y))) -$(call do,$(call _assoc!,$(Y),a,value of Y a)) -$(call assert_eq,1,$(call _count,$(Y)),\ - (_count $$(Y))) -$(call do,$(call _assoc!,$(Y),b,value of Y b)) -$(call assert_eq,2,$(call _count,$(Y)),\ - (_count $$(Y))) -$(call assert_eq,value of Y a,$(call _get,$(Y),a),\ - (get $$(Y),a) is not 'value of Y a') -$(call assert_eq,value of Y b,$(call _get,$(Y),b),\ - (get $$(Y),b) is not 'value of Y b') -$(call assert_eq,value of Y a value of Y b,$(call raw_flat,$(Y),b),\ - (raw_flat $(Y)) is not 'value of Y a value of Y b') - -$(call do,$(call _assoc!,$(X),b,$(Y))) -$(call assert_eq,2,$(call _count,$(Y),a),\ - (_count $$(Y)) should still be 2) - -$(call assert_eq,$(__true),$(call hash_map?,$(call _get,$(X),b)),\ - (hash_map? (get $$(X),b))) - -$(call assert_eq,$(call _get,$(call _get,$(X),b),a),value of Y a,\ - (get (get $(X),b),a) is not 'value of Y a') -$(call assert_eq,$(call _get,$(call _get,$(X),b),b),value of Y b,\ - (get (get $(X),b),b) is not 'value of Y b') - -$(call do,$(call _dissoc!,$(Y),a)) -$(call assert_eq,1,$(call _count,$(Y)),\ - (_count $$(Y)) should now be 1) -$(call assert_not,$(call _get,$(Y),a),\ - (get $$(Y),a)) -$(call do,$(call _dissoc!,$(Y),b)) -$(call assert_eq,0,$(call _count,$(Y)),\ - (_count $$(Y)) should now be 0) -$(call assert_not,$(call _get,$(Y),b),\ - (get $$(Y),b)) - - -$(info Testing vectors) - -V1 := $(call _conj!,$(call vector),first.vector.value second.vector.value third.vector.value) -$(call assert_eq,$(__true),$(call vector?,$(V1)),\ - (vector? $$(V1))) -$(call assert_eq,first.vector.value,$(call _nth,$(V1),0)) -$(call assert_eq,second.vector.value,$(call _nth,$(V1),1)) -$(call assert_eq,third.vector.value,$(call _nth,$(V1),2)) -$(call assert_eq,third.vector.value,$(call slast,$(V1))) -$(call assert_eq,3,$(call _count,$(V1))) - -V2 := $(call _conj!,$(call vector),A B C) -$(call assert_eq,3,$(call _count,$(V2)),\ - (_count $$(V2)) is not 3) -$(call assert_eq,A B C,$($(V2)_value)) -$(call assert_eq,A,$(call sfirst,$(V2)),\ - (first $$(V2)) is not 'A') -$(call assert_eq,$(__true),$(call list?,$(call srest,$(V2))),\ - (rest $$(V2)) is not a vector) -$(call assert_eq,B C,$($(call srest,$(V2))_value)) -$(call assert_eq,B,$(call sfirst,$(call srest,$(V2))),\ - (first (rest $$(V2))) is not 'B') -$(call assert_eq,C,$(call sfirst,$(call srest,$(call srest,$(V2)))),\ - (first (rest (rest $$(V2)))) is not 'C') -$(call assert_eq,C,$(call _nth,$(V2),2),\ - (_nth $$(V2),2) is not 'C') - -V2_1 := $(call _conj!,$(V2),$(V1)) -$(call assert_eq,4,$(call _count,$(V2_1)),\ - (_count $$(V2_1)) is not 4) -$(call assert_eq,C,$(call _nth,$(V2_1),2),\ - (_nth $$(V2_1),2) is no longer 'C') -$(call assert_eq,$(__true),$(call vector?,$(call _nth,$(V2_1),3)),\ - (_nth $$(V2_1),3) is not a vector) -$(call assert_eq,second.vector.value,$(call _nth,$(call _nth,$(V2_1),3),1),\ - (_nth (_nth $$(V2_1),3),1) is not 'second.vector.value') - -$(info Testing vectors (rest)) - -V3 := $(call srest,$(V2_1)) -$(call assert_eq,3,$(call _count,$(V3)),\ - (_count $$(V3)) is not 3) -$(call assert_eq,B,$(call sfirst,$(V3)),\ - (first $$(V3)) is not 'B') -$(call assert_eq,$(__true),$(call vector?,$(call _nth,$(V3),2)),\ - (_nth $$(V3),2) is not a vector) -$(call assert_eq,second.vector.value,$(call _nth,$(call _nth,$(V3),2),1),\ - (_nth (_nth $$(V3),2),1) is not 'second.vector.value') - -$(info Testing vectors (contains?)) - -$(call assert_eq,$(__true),$(call _contains?,$(V2_1),0),\ - (contains? $$(V2_1),0)) -$(call assert_eq,,$(call _contains?,$(V2_1),7),\ - (contains? $$(V2_1),7)) - - -$(info Testing _apply function) - -label_args = $(word 1,$(1))$(word 2,$(1))$(word 3,$(1))$(word 4,$(1)) -$(call assert_eq,,$(call _apply,label_args,$(call list))) -$(call assert_eq,A,$(call _apply,label_args,$(call list,A))) -$(call assert_eq,AB,$(call _apply,label_args,$(call list,A B))) -$(call assert_eq,ABCD,$(call _apply,label_args,$(call list,A B C D))) - - -$(info Testing smap function) - -L5 := $(call _conj!,$(call list),$(call number,1) $(call number,2) $(call number,3)) -inc = $(call number_plus,$(call number,1) $(1)) -$(call assert_eq,(2 3 4),$(call _pr_str,$(call _smap,inc,$(L5)))) -inc_func := $(call _function,$$(call number_plus,$$(call number,1) $$(1))) -$(call assert_eq,(2 3 4),$(call _pr_str,$(call smap,$(inc_func) $(L5)))) - - -$(info Testing equal? function) -$(call assert_eq,$(__true),$(call equal?,2 2)) -$(call assert_eq,$(__false),$(call equal?,2 3)) -$(call assert_eq,$(__false),$(call equal?,2 3)) -$(call assert_eq,$(__true),$(call equal?,abc abc)) -$(call assert_eq,$(__false),$(call equal?,abc abz)) -$(call assert_eq,$(__false),$(call equal?,zbc abc)) -$(call assert_eq,$(__true),$(call equal?,$(call string,abc) $(call string,abc))) -$(call assert_eq,$(__false),$(call equal?,$(call string,abc) $(call string,abz))) -$(call assert_eq,$(__false),$(call equal?,$(call string,zbc) $(call string,abc))) -$(call assert_eq,$(__true),$(call equal?,$(call symbol,abc) $(call symbol,abc))) -$(call assert_eq,$(__false),$(call equal?,$(call symbol,abc) $(call symbol,abz))) -$(call assert_eq,$(__false),$(call equal?,$(call symbol,zbc) $(call symbol,abc))) -L6 := $(call _conj!,$(call list),1 2 3) -L7 := $(call _conj!,$(call list),1 2 3) -L8 := $(call _conj!,$(call list),1 2 Z) -L9 := $(call _conj!,$(call list),Z 2 3) -L10 := $(call _conj!,$(call list),1 2) -$(call assert_eq,$(__true),$(call equal?,$(L6) $(L7))) -$(call assert_eq,$(__false),$(call equal?,$(L6) $(L8))) -$(call assert_eq,$(__false),$(call equal?,$(L6) $(L9))) -$(call assert_eq,$(__false),$(call equal?,$(L6) $(L10))) -$(call assert_eq,$(__false),$(call equal?,$(L10) $(L6))) - - -$(info Testing empty? function) -$(call assert_eq,$(__true),$(call empty?,$(call list))) -$(call assert_eq,$(__false),$(call empty?,$(call list,1))) - - -$(info Testing ENV (1 level)) -env1 := $(call ENV) -$(call assert_eq,,$(call ENV_GET,$(env1),a)) -$(call assert_eq,$(env1),$(call ENV_SET,$(env1),a,val_a)) -$(call assert_eq,$(env1),$(call ENV_SET,$(env1),b,val_b)) -$(call assert_eq,$(env1),$(call ENV_SET,$(env1),=,val_eq)) -$(call assert_eq,val_a,$(call ENV_GET,$(env1),a)) -$(call assert_eq,val_b,$(call ENV_GET,$(env1),b)) -$(call assert_eq,val_eq,$(call ENV_GET,$(env1),=)) -$(call assert_eq,hash_map,$(call _obj_type,$(call ENV_FIND,$(env1),a))) -$(call assert_eq,val_a,$(call _get,$(call ENV_FIND,$(env1),a),a)) - -$(info Testing ENV (2 levels)) -env2 := $(call ENV,$(env1)) -$(call assert_eq,$(env2),$(call ENV_SET,$(env2),b,val_b2)) -$(call assert_eq,$(env2),$(call ENV_SET,$(env2),c,val_c)) -$(call assert_eq,$(env1),$(call ENV_FIND,$(env2),a)) -$(call assert_eq,$(env2),$(call ENV_FIND,$(env2),b)) -$(call assert_eq,$(env2),$(call ENV_FIND,$(env2),c)) -$(call assert_eq,val_a,$(call ENV_GET,$(env2),a)) -$(call assert_eq,val_b2,$(call ENV_GET,$(env2),b)) -$(call assert_eq,val_c,$(call ENV_GET,$(env2),c)) - - -.PHONY: all -all: - @echo "All tests completed" @@ -18,6 +18,8 @@ parser.add_argument('--start-timeout', default=10, type=int, help="default timeout for initial prompt") parser.add_argument('--test-timeout', default=20, type=int, help="default timeout for each individual test action") +parser.add_argument('--pre-eval', default=None, type=str, + help="Mal code to evaluate prior to running the test") parser.add_argument('--redirect', action='store_true', help="Run implementation in bash and redirect output to /dev/null") @@ -77,14 +79,24 @@ def read_test(data): return form, output, ret, test_idx +def assert_prompt(timeout): + # Wait for the initial prompt + idx = p.expect(['user> ', 'mal-user> ', EOF, TIMEOUT], + timeout=timeout) + if idx not in [0,1]: + print "Did not get 'user> ' or 'mal-user> ' prompt" + print " Got : %s" % repr(p.before) + sys.exit(1) + # Wait for the initial prompt -idx = p.expect(['user> ', 'mal-user> ', EOF, TIMEOUT], - timeout=args.start_timeout) -if idx not in [0,1]: - print "Never got 'user> ' prompt" - print " Got : %s" % repr(p.before) - sys.exit(1) +assert_prompt(args.start_timeout) + +# Send the pre-eval code if any +if args.pre_eval: + sys.stdout.write("RUNNING pre-eval: %s" % args.pre_eval) + p.sendline(args.pre_eval) + assert_prompt(args.test_timeout) fail_cnt = 0 diff --git a/tests/step5_tco.mal b/tests/step5_tco.mal new file mode 100644 index 0000000..9054c74 --- /dev/null +++ b/tests/step5_tco.mal @@ -0,0 +1,27 @@ +;; Test recursive non-tail call function + +(def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) + +(sum-to 10) +;=>55 + +;;; no try* yet, so test completion of side-effects +(def! res1 nil) +;=>nil +(def! res1 (sum-to 10000))) +res1 +;=>nil + +;; Testing recursive tail-call function + +(def! sum2 (fn* (n acc) (if (= n 0) acc (sum2 (- n 1) (+ n acc))))) + +(sum2 10 0) +;=>55 + +(def! res2 nil) +;=>nil +(def! res2 (sum2 10000 0)) +res2 +;=>50005000 + |
