| @ -0,0 +1,4 @@ | |||
| (def! inc1 (fn* (a) (+ 1 a))) | |||
| (def! inc2 (fn* (a) (+ 2 a))) | |||
| (def! inc3 (fn* (a) | |||
| (+ 3 a))) | |||
| @ -0,0 +1,3 @@ | |||
| (def! inc4 (fn* (a) (+ 4 a))) | |||
| (prn (inc4 5)) | |||
| @ -0,0 +1,10 @@ | |||
| ;; A comment in a file | |||
| (def! inc4 (fn* (a) (+ 4 a))) | |||
| (def! inc5 (fn* (a) ;; a comment after code | |||
| (+ 5 a))) | |||
| (prn "incB.mal finished") | |||
| "incB.mal return string" | |||
| ;; ending comment | |||
| @ -0,0 +1,6 @@ | |||
| (def! mymap {"a" | |||
| 1}) | |||
| (prn "incC.mal finished") | |||
| "incC.mal return string" | |||
| @ -0,0 +1,11 @@ | |||
| (load-file "../core.mal") | |||
| (load-file "../perf.mal") | |||
| ;;(prn "Start: basic macros performance test") | |||
| (time (do | |||
| (or false nil false nil false nil false nil false nil 4) | |||
| (cond false 1 nil 2 false 3 nil 4 false 5 nil 6 "else" 7) | |||
| (-> (list 1 2 3 4 5 6 7 8 9) rest rest rest rest rest rest first))) | |||
| ;;(prn "Done: basic macros performance test") | |||
| @ -0,0 +1,13 @@ | |||
| (load-file "../core.mal") | |||
| (load-file "../perf.mal") | |||
| ;;(prn "Start: basic math/recursion test") | |||
| (def! sumdown (fn* (N) (if (> N 0) (+ N (sumdown (- N 1))) 0))) | |||
| (def! fib (fn* (N) (if (= N 0) 1 (if (= N 1) 1 (+ (fib (- N 1)) (fib (- N 2))))))) | |||
| (time (do | |||
| (sumdown 10) | |||
| (fib 12))) | |||
| ;;(prn "Done: basic math/recursion test") | |||
| @ -0,0 +1,28 @@ | |||
| (load-file "../core.mal") | |||
| (load-file "../perf.mal") | |||
| ;;(prn "Start: basic macros/atom test") | |||
| (def! atm (atom (list 0 1 2 3 4 5 6 7 8 9))) | |||
| (println "iters/s:" | |||
| (run-fn-for | |||
| (fn* [] | |||
| (do | |||
| (or false nil false nil false nil false nil false nil (first @atm)) | |||
| (cond false 1 nil 2 false 3 nil 4 false 5 nil 6 "else" (first @atm)) | |||
| (-> (deref atm) rest rest rest rest rest rest first) | |||
| (swap! atm (fn* [a] (concat (rest a) (list (first a))))))) | |||
| 10)) | |||
| ;;(def! sumdown (fn* (N) (if (> N 0) (+ N (sumdown (- N 1))) 0))) | |||
| ;;(def! fib (fn* (N) (if (= N 0) 1 (if (= N 1) 1 (+ (fib (- N 1)) (fib (- N 2))))))) | |||
| ;; | |||
| ;;(println "iters/s:" | |||
| ;; (run-fn-for | |||
| ;; (fn* [] | |||
| ;; (do | |||
| ;; (sumdown 10) | |||
| ;; (fib 12))) | |||
| ;; 3)) | |||
| ;;(prn "Done: basic macros/atom test") | |||
| @ -0,0 +1,14 @@ | |||
| hello world | |||
| ;=>hello world | |||
| abcABC123 | |||
| ;=>abcABC123 | |||
| ;:() []{}"'* | |||
| ;=>;:() []{}"'* | |||
| ;;; Test long line | |||
| hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*) | |||
| ;=>hello world abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 (;:() []{}"'* ;:() []{}"'* ;:() []{}"'*) | |||
| @ -0,0 +1,136 @@ | |||
| ;; Testing read of nil/true/false | |||
| nil | |||
| ;=>nil | |||
| true | |||
| ;=>true | |||
| false | |||
| ;=>false | |||
| ;; Testing read of numbers | |||
| 1 | |||
| ;=>1 | |||
| 7 | |||
| ;=>7 | |||
| 7 | |||
| ;=>7 | |||
| ;; Testing read of symbols | |||
| + | |||
| ;=>+ | |||
| abc | |||
| ;=>abc | |||
| abc | |||
| ;=>abc | |||
| abc5 | |||
| ;=>abc5 | |||
| abc-def | |||
| ;=>abc-def | |||
| ;; Testing read of strings | |||
| "abc" | |||
| ;=>"abc" | |||
| "abc" | |||
| ;=>"abc" | |||
| "abc (with parens)" | |||
| ;=>"abc (with parens)" | |||
| "abc\"def" | |||
| ;=>"abc\"def" | |||
| ;;;"abc\ndef" | |||
| ;;;;=>"abc\ndef" | |||
| "" | |||
| ;=>"" | |||
| ;; Testing read of lists | |||
| (+ 1 2) | |||
| ;=>(+ 1 2) | |||
| ((3 4)) | |||
| ;=>((3 4)) | |||
| (+ 1 (+ 2 3)) | |||
| ;=>(+ 1 (+ 2 3)) | |||
| ( + 1 (+ 2 3 ) ) | |||
| ;=>(+ 1 (+ 2 3)) | |||
| (* 1 2) | |||
| ;=>(* 1 2) | |||
| (** 1 2) | |||
| ;=>(** 1 2) | |||
| ;; Test commas as whitespace | |||
| (1 2, 3,,,,),, | |||
| ;=>(1 2 3) | |||
| ;; Testing read of quoting | |||
| '1 | |||
| ;=>(quote 1) | |||
| '(1 2 3) | |||
| ;=>(quote (1 2 3)) | |||
| `1 | |||
| ;=>(quasiquote 1) | |||
| `(1 2 3) | |||
| ;=>(quasiquote (1 2 3)) | |||
| ~1 | |||
| ;=>(unquote 1) | |||
| ~(1 2 3) | |||
| ;=>(unquote (1 2 3)) | |||
| ~@(1 2 3) | |||
| ;=>(splice-unquote (1 2 3)) | |||
| ;; | |||
| ;; Testing reader errors | |||
| ;;; TODO: fix these so they fail correctly | |||
| (1 2 | |||
| ; expected ')', got EOF | |||
| [1 2 | |||
| ; expected ']', got EOF | |||
| "abc | |||
| ; expected '"', got EOF | |||
| ;; | |||
| ;; -------- Optional Functionality -------- | |||
| ;; Testing keywords | |||
| :kw | |||
| ;=>:kw | |||
| (:kw1 :kw2 :kw3) | |||
| ;=>(:kw1 :kw2 :kw3) | |||
| ;; Testing read of vectors | |||
| [+ 1 2] | |||
| ;=>[+ 1 2] | |||
| [[3 4]] | |||
| ;=>[[3 4]] | |||
| [+ 1 [+ 2 3]] | |||
| ;=>[+ 1 [+ 2 3]] | |||
| [ + 1 [+ 2 3 ] ] | |||
| ;=>[+ 1 [+ 2 3]] | |||
| ;; Testing read of hash maps | |||
| {"abc" 1} | |||
| ;=>{"abc" 1} | |||
| {"a" {"b" 2}} | |||
| ;=>{"a" {"b" 2}} | |||
| {"a" {"b" {"c" 3}}} | |||
| ;=>{"a" {"b" {"c" 3}}} | |||
| { "a" {"b" { "cde" 3 } }} | |||
| ;=>{"a" {"b" {"cde" 3}}} | |||
| { :a {:b { :cde 3 } }} | |||
| ;=>{:a {:b {:cde 3}}} | |||
| ;; Testing read of comments | |||
| ;; whole line comment (not an exception) | |||
| 1 ; comment after expression | |||
| ;=>1 | |||
| 1; comment after expression | |||
| ;=>1 | |||
| ;; Testing read of ^/metadata | |||
| ^{"a" 1} [1 2 3] | |||
| ;=>(with-meta [1 2 3] {"a" 1}) | |||
| ;; Testing read of @/deref | |||
| @a | |||
| ;=>(deref a) | |||
| @ -0,0 +1,31 @@ | |||
| ;; Testing evaluation of arithmetic operations | |||
| (+ 1 2) | |||
| ;=>3 | |||
| (+ 5 (* 2 3)) | |||
| ;=>11 | |||
| (- (+ 5 (* 2 3)) 3) | |||
| ;=>8 | |||
| (/ (- (+ 5 (* 2 3)) 3) 4) | |||
| ;=>2 | |||
| (/ (- (+ 515 (* 222 311)) 302) 27) | |||
| ;=>2565 | |||
| (abc 1 2 3) | |||
| ; .*\'abc\' not found.* | |||
| ;; | |||
| ;; -------- Optional Functionality -------- | |||
| ;; Testing evaluation within collection literals | |||
| [1 2 (+ 1 2)] | |||
| ;=>[1 2 3] | |||
| {"a" (+ 7 8)} | |||
| ;=>{"a" 15} | |||
| {:a (+ 7 8)} | |||
| ;=>{:a 15} | |||
| @ -0,0 +1,56 @@ | |||
| ;; Testing REPL_ENV | |||
| (+ 1 2) | |||
| ;=>3 | |||
| (/ (- (+ 5 (* 2 3)) 3) 4) | |||
| ;=>2 | |||
| ;; Testing def! | |||
| (def! x 3) | |||
| ;=>3 | |||
| x | |||
| ;=>3 | |||
| (def! x 4) | |||
| ;=>4 | |||
| x | |||
| ;=>4 | |||
| (def! y (+ 1 7)) | |||
| ;=>8 | |||
| y | |||
| ;=>8 | |||
| ;; Testing let* | |||
| (let* (z 9) z) | |||
| ;=>9 | |||
| (let* (x 9) x) | |||
| ;=>9 | |||
| x | |||
| ;=>4 | |||
| (let* (z (+ 2 3)) (+ 1 z)) | |||
| ;=>6 | |||
| (let* (p (+ 2 3) q (+ 2 p)) (+ p q)) | |||
| ;=>12 | |||
| ;; Testing outer environment | |||
| (def! a 4) | |||
| ;=>4 | |||
| (let* (q 9) q) | |||
| ;=>9 | |||
| (let* (q 9) a) | |||
| ;=>4 | |||
| (let* (z 2) (let* (q 9) a)) | |||
| ;=>4 | |||
| ;; | |||
| ;; -------- Optional Functionality -------- | |||
| ;; Testing let* with vector bindings | |||
| (let* [z 9] z) | |||
| ;=>9 | |||
| (let* [p (+ 2 3) q (+ 2 p)] (+ p q)) | |||
| ;=>12 | |||
| ;; Testing vector evaluation | |||
| (let* (a 5 b 6) [3 4 a [b 7] 8]) | |||
| ;=>[3 4 5 [6 7] 8] | |||
| @ -0,0 +1,388 @@ | |||
| ;; ----------------------------------------------------- | |||
| ;; Testing list functions | |||
| (list) | |||
| ;=>() | |||
| (list? (list)) | |||
| ;=>true | |||
| (empty? (list)) | |||
| ;=>true | |||
| (empty? (list 1)) | |||
| ;=>false | |||
| (list 1 2 3) | |||
| ;=>(1 2 3) | |||
| (count (list 1 2 3)) | |||
| ;=>3 | |||
| (count (list)) | |||
| ;=>0 | |||
| (count nil) | |||
| ;=>0 | |||
| (if (> (count (list 1 2 3)) 3) "yes" "no") | |||
| ;=>"no" | |||
| (if (>= (count (list 1 2 3)) 3) "yes" "no") | |||
| ;=>"yes" | |||
| ;; Testing if form | |||
| (if true 7 8) | |||
| ;=>7 | |||
| (if false 7 8) | |||
| ;=>8 | |||
| (if true (+ 1 7) (+ 1 8)) | |||
| ;=>8 | |||
| (if false (+ 1 7) (+ 1 8)) | |||
| ;=>9 | |||
| (if nil 7 8) | |||
| ;=>8 | |||
| (if 0 7 8) | |||
| ;=>7 | |||
| (if "" 7 8) | |||
| ;=>7 | |||
| (if (list) 7 8) | |||
| ;=>7 | |||
| (if (list 1 2 3) 7 8) | |||
| ;=>7 | |||
| (= (list) nil) | |||
| ;=>false | |||
| ;; Testing 1-way if form | |||
| (if false (+ 1 7)) | |||
| ;=>nil | |||
| (if nil 8 7) | |||
| ;=>7 | |||
| (if true (+ 1 7)) | |||
| ;=>8 | |||
| ;; Testing basic conditionals | |||
| (= 2 1) | |||
| ;=>false | |||
| (= 1 1) | |||
| ;=>true | |||
| (= 1 2) | |||
| ;=>false | |||
| (= 1 (+ 1 1)) | |||
| ;=>false | |||
| (= 2 (+ 1 1)) | |||
| ;=>true | |||
| (= nil 1) | |||
| ;=>false | |||
| (= nil nil) | |||
| ;=>true | |||
| (> 2 1) | |||
| ;=>true | |||
| (> 1 1) | |||
| ;=>false | |||
| (> 1 2) | |||
| ;=>false | |||
| (>= 2 1) | |||
| ;=>true | |||
| (>= 1 1) | |||
| ;=>true | |||
| (>= 1 2) | |||
| ;=>false | |||
| (< 2 1) | |||
| ;=>false | |||
| (< 1 1) | |||
| ;=>false | |||
| (< 1 2) | |||
| ;=>true | |||
| (<= 2 1) | |||
| ;=>false | |||
| (<= 1 1) | |||
| ;=>true | |||
| (<= 1 2) | |||
| ;=>true | |||
| ;; Testing equality | |||
| (= 1 1) | |||
| ;=>true | |||
| (= 0 0) | |||
| ;=>true | |||
| (= 1 0) | |||
| ;=>false | |||
| (= "" "") | |||
| ;=>true | |||
| (= "abc" "") | |||
| ;=>false | |||
| (= "" "abc") | |||
| ;=>false | |||
| (= "abc" "def") | |||
| ;=>false | |||
| (= (list) (list)) | |||
| ;=>true | |||
| (= (list 1 2) (list 1 2)) | |||
| ;=>true | |||
| (= (list 1) (list)) | |||
| ;=>false | |||
| (= (list) (list 1)) | |||
| ;=>false | |||
| (= 0 (list)) | |||
| ;=>false | |||
| (= (list) 0) | |||
| ;=>false | |||
| (= (list) "") | |||
| ;=>false | |||
| (= "" (list)) | |||
| ;=>false | |||
| ;; Testing builtin and user defined functions | |||
| (+ 1 2) | |||
| ;=>3 | |||
| ( (fn* (a b) (+ b a)) 3 4) | |||
| ;=>7 | |||
| ( (fn* () 4) ) | |||
| ;=>4 | |||
| ( (fn* (f x) (f x)) (fn* (a) (+ 1 a)) 7) | |||
| ;=>8 | |||
| ;; Testing closures | |||
| ( ( (fn* (a) (fn* (b) (+ a b))) 5) 7) | |||
| ;=>12 | |||
| (def! gen-plus5 (fn* () (fn* (b) (+ 5 b)))) | |||
| (def! plus5 (gen-plus5)) | |||
| (plus5 7) | |||
| ;=>12 | |||
| (def! gen-plusX (fn* (x) (fn* (b) (+ x b)))) | |||
| (def! plus7 (gen-plusX 7)) | |||
| (plus7 8) | |||
| ;=>15 | |||
| ;; Testing variable length arguments | |||
| ( (fn* (& more) (count more)) 1 2 3) | |||
| ;=>3 | |||
| ( (fn* (& more) (count more)) 1) | |||
| ;=>1 | |||
| ( (fn* (& more) (count more)) ) | |||
| ;=>0 | |||
| ( (fn* (a & more) (count more)) 1 2 3) | |||
| ;=>2 | |||
| ( (fn* (a & more) (count more)) 1) | |||
| ;=>0 | |||
| ;; Testing language defined not function | |||
| (not false) | |||
| ;=>true | |||
| (not true) | |||
| ;=>false | |||
| (not "a") | |||
| ;=>false | |||
| (not 0) | |||
| ;=>false | |||
| ;; Testing do form | |||
| (do (prn "prn output1")) | |||
| ; "prn output1" | |||
| ;=>nil | |||
| (do (prn "prn output2") 7) | |||
| ; "prn output2" | |||
| ;=>7 | |||
| (do (prn "prn output1") (prn "prn output2") (+ 1 2)) | |||
| ; "prn output1" | |||
| ; "prn output2" | |||
| ;=>3 | |||
| (do (def! a 6) 7 (+ a 8)) | |||
| ;=>14 | |||
| a | |||
| ;=>6 | |||
| ;; Testing recursive sumdown function | |||
| (def! sumdown (fn* (N) (if (> N 0) (+ N (sumdown (- N 1))) 0))) | |||
| (sumdown 1) | |||
| ;=>1 | |||
| (sumdown 2) | |||
| ;=>3 | |||
| (sumdown 6) | |||
| ;=>21 | |||
| ;; Testing recursive fibonacci function | |||
| (def! fib (fn* (N) (if (= N 0) 1 (if (= N 1) 1 (+ (fib (- N 1)) (fib (- N 2))))))) | |||
| (fib 1) | |||
| ;=>1 | |||
| (fib 2) | |||
| ;=>2 | |||
| (fib 4) | |||
| ;=>5 | |||
| (fib 10) | |||
| ;=>89 | |||
| ;; ----------------------------------------------------- | |||
| ;; Testing string quoting | |||
| "" | |||
| ;=>"" | |||
| "abc" | |||
| ;=>"abc" | |||
| "abc def" | |||
| ;=>"abc def" | |||
| "\"" | |||
| ;=>"\"" | |||
| ;; Testing pr-str | |||
| (pr-str) | |||
| ;=>"" | |||
| (pr-str "") | |||
| ;=>"\"\"" | |||
| (pr-str "abc") | |||
| ;=>"\"abc\"" | |||
| (pr-str "abc def" "ghi jkl") | |||
| ;=>"\"abc def\" \"ghi jkl\"" | |||
| (pr-str "\"") | |||
| ;=>"\"\\\"\"" | |||
| (pr-str (list 1 2 "abc" "\"") "def") | |||
| ;=>"(1 2 \"abc\" \"\\\"\") \"def\"" | |||
| ;; Testing str | |||
| (str) | |||
| ;=>"" | |||
| (str "") | |||
| ;=>"" | |||
| (str "abc") | |||
| ;=>"abc" | |||
| (str "\"") | |||
| ;=>"\"" | |||
| (str 1 "abc" 3) | |||
| ;=>"1abc3" | |||
| (str "abc def" "ghi jkl") | |||
| ;=>"abc defghi jkl" | |||
| ;;; TODO: get this working properly | |||
| ;;;(str (list 1 2 "abc" "\"") "def") | |||
| ;;;;=>"(1 2 \"abc\" \"\\\"\")def" | |||
| ;; Testing prn | |||
| (prn) | |||
| ; | |||
| ;=>nil | |||
| (prn "") | |||
| ; "" | |||
| ;=>nil | |||
| (prn "abc") | |||
| ; "abc" | |||
| ;=>nil | |||
| (prn "abc def" "ghi jkl") | |||
| ; "abc def" "ghi jkl" | |||
| (prn "\"") | |||
| ; "\"" | |||
| ;=>nil | |||
| (prn (list 1 2 "abc" "\"") "def") | |||
| ; (1 2 "abc" "\"") "def" | |||
| ;=>nil | |||
| ;; Testing println | |||
| (println) | |||
| ; | |||
| ;=>nil | |||
| (println "") | |||
| ; | |||
| ;=>nil | |||
| (println "abc") | |||
| ; abc | |||
| ;=>nil | |||
| (println "abc def" "ghi jkl") | |||
| ; abc def ghi jkl | |||
| (println "\"") | |||
| ; " | |||
| ;=>nil | |||
| (println (list 1 2 "abc" "\"") "def") | |||
| ; (1 2 abc ") def | |||
| ;=>nil | |||
| ;; | |||
| ;; -------- Optional Functionality -------- | |||
| ;; Testing keywords | |||
| (= :abc :abc) | |||
| ;=>true | |||
| (= :abc :def) | |||
| ;=>false | |||
| (= :abc ":abc") | |||
| ;=>false | |||
| ;; Testing vector truthiness | |||
| (if [] 7 8) | |||
| ;=>7 | |||
| ;; Testing vector functions | |||
| (count [1 2 3]) | |||
| ;=>3 | |||
| (empty? [1 2 3]) | |||
| ;=>false | |||
| (empty? []) | |||
| ;=>true | |||
| (list? [4 5 6]) | |||
| ;=>false | |||
| ;; Testing vector equality | |||
| (= [] (list)) | |||
| ;=>true | |||
| (= (list 1 2) [1 2]) | |||
| ;=>true | |||
| (= (list 1) []) | |||
| ;=>false | |||
| (= [] [1]) | |||
| ;=>false | |||
| (= 0 []) | |||
| ;=>false | |||
| (= [] 0) | |||
| ;=>false | |||
| (= [] "") | |||
| ;=>false | |||
| (= "" []) | |||
| ;=>false | |||
| ;; Testing vector parameter lists | |||
| ( (fn* [] 4) ) | |||
| ;=>4 | |||
| ( (fn* [f x] (f x)) (fn* [a] (+ 1 a)) 7) | |||
| ;=>8 | |||
| @ -0,0 +1,30 @@ | |||
| ;; 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 | |||
| ;; 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 | |||
| ;;; For implementations without their own TCO this should fail and | |||
| ;;; leave res1 unchanged | |||
| (def! res1 (sum-to 10000)) | |||
| res1 | |||
| ;=>nil | |||
| @ -0,0 +1,72 @@ | |||
| ;;; TODO: really a step5 test | |||
| ;; | |||
| ;; Testing that (do (do)) not broken by TCO | |||
| (do (do 1 2)) | |||
| ;=>2 | |||
| ;; | |||
| ;; Testing read-string, eval and slurp | |||
| (read-string "(1 2 (3 4) nil)") | |||
| ;=>(1 2 (3 4) nil) | |||
| (read-string "(+ 2 3)") | |||
| ;=>(+ 2 3) | |||
| (read-string "7 ;; comment") | |||
| ;=>7 | |||
| ;;; Differing output, but make sure no fatal error | |||
| (read-string ";; comment") | |||
| (eval (read-string "(+ 2 3)")) | |||
| ;=>5 | |||
| ;;; TODO: fix newline matching so that this works | |||
| ;;;(slurp "../tests/test.txt") | |||
| ;;;;=>"A line of text\n" | |||
| ;; Testing load-file | |||
| (load-file "../tests/inc.mal") | |||
| (inc1 7) | |||
| ;=>8 | |||
| (inc2 7) | |||
| ;=>9 | |||
| (inc3 9) | |||
| ;=>12 | |||
| ;; | |||
| ;; Testing that *ARGV* exists and is an empty list | |||
| (list? *ARGV*) | |||
| ;=>true | |||
| *ARGV* | |||
| ;=>() | |||
| ;; | |||
| ;; -------- Optional Functionality -------- | |||
| ;; Testing comments in a file | |||
| (load-file "../tests/incB.mal") | |||
| ; "incB.mal finished" | |||
| ;=>"incB.mal return string" | |||
| (inc4 7) | |||
| ;=>11 | |||
| (inc5 7) | |||
| ;=>12 | |||
| ;; Testing map literal across multiple lines in a file | |||
| (load-file "../tests/incC.mal") | |||
| mymap | |||
| ;=>{"a" 1} | |||
| ;;; TODO: really a step5 test | |||
| ;; Testing that vector params not broken by TCO | |||
| (def! g (fn* [] 78)) | |||
| (g) | |||
| ;=>78 | |||
| (def! g (fn* [a] (+ a 78))) | |||
| (g 3) | |||
| ;=>81 | |||
| @ -0,0 +1,126 @@ | |||
| ;; Testing cons function | |||
| (cons 1 (list)) | |||
| ;=>(1) | |||
| (cons 1 (list 2)) | |||
| ;=>(1 2) | |||
| (cons 1 (list 2 3)) | |||
| ;=>(1 2 3) | |||
| (cons (list 1) (list 2 3)) | |||
| ;=>((1) 2 3) | |||
| ;; Testing concat function | |||
| (concat) | |||
| ;=>() | |||
| (concat (list 1 2)) | |||
| ;=>(1 2) | |||
| (concat (list 1 2) (list 3 4)) | |||
| ;=>(1 2 3 4) | |||
| (concat (list 1 2) (list 3 4) (list 5 6)) | |||
| ;=>(1 2 3 4 5 6) | |||
| (concat (concat)) | |||
| ;=>() | |||
| ;; Testing regular quote | |||
| (quote 7) | |||
| ;=>7 | |||
| '7 | |||
| ;=>7 | |||
| (quote (1 2 3)) | |||
| ;=>(1 2 3) | |||
| '(1 2 3) | |||
| ;=>(1 2 3) | |||
| (quote (1 2 (3 4))) | |||
| ;=>(1 2 (3 4)) | |||
| '(1 2 (3 4)) | |||
| ;=>(1 2 (3 4)) | |||
| ;; Testing simple quasiquote | |||
| (quasiquote 7) | |||
| ;=>7 | |||
| `7 | |||
| ;=>7 | |||
| (quasiquote (1 2 3)) | |||
| ;=>(1 2 3) | |||
| `(1 2 3) | |||
| ;=>(1 2 3) | |||
| (quasiquote (1 2 (3 4))) | |||
| ;=>(1 2 (3 4)) | |||
| `(1 2 (3 4)) | |||
| ;=>(1 2 (3 4)) | |||
| ;; Testing unquote | |||
| `~7 | |||
| ;=>7 | |||
| (def! a 8) | |||
| ;=>8 | |||
| `a | |||
| ;=>a | |||
| `~a | |||
| ;=>8 | |||
| `(1 a 3) | |||
| ;=>(1 a 3) | |||
| `(1 ~a 3) | |||
| ;=>(1 8 3) | |||
| (def! b '(1 "b" "d")) | |||
| ;=>(1 "b" "d") | |||
| `(1 b 3) | |||
| ;=>(1 b 3) | |||
| `(1 ~b 3) | |||
| ;=>(1 (1 "b" "d") 3) | |||
| ;; Testing splice-unquote | |||
| (def! c '(1 "b" "d")) | |||
| ;=>(1 "b" "d") | |||
| `(1 c 3) | |||
| ;=>(1 c 3) | |||
| `(1 ~@c 3) | |||
| ;=>(1 1 "b" "d" 3) | |||
| ;; Testing symbol equality | |||
| (= 'abc 'abc) | |||
| ;=>true | |||
| (= 'abc 'abcd) | |||
| ;=>false | |||
| (= 'abc "abc") | |||
| ;=>false | |||
| (= "abc" 'abc) | |||
| ;=>false | |||
| ;;;;; Test quine | |||
| ;;; TODO: needs expect line length fix | |||
| ;;;((fn* [q] (quasiquote ((unquote q) (quote (unquote q))))) (quote (fn* [q] (quasiquote ((unquote q) (quote (unquote q))))))) | |||
| ;;;=>((fn* [q] (quasiquote ((unquote q) (quote (unquote q))))) (quote (fn* [q] (quasiquote ((unquote q) (quote (unquote q))))))) | |||
| ;; | |||
| ;; -------- Optional Functionality -------- | |||
| ;; Testing cons, concat, first, rest with vectors | |||
| (cons [1] [2 3]) | |||
| ;=>([1] 2 3) | |||
| (cons 1 [2 3]) | |||
| ;=>(1 2 3) | |||
| (concat [1 2] (list 3 4) [5 6]) | |||
| ;=>(1 2 3 4 5 6) | |||
| ;; Testing unquote with vectors | |||
| (def! a 8) | |||
| ;=>8 | |||
| `[1 a 3] | |||
| ;=>(1 a 3) | |||
| ;;; TODO: fix this | |||
| ;;;;=>[1 a 3] | |||
| ;; Testing splice-unquote with vectors | |||
| (def! c '(1 "b" "d")) | |||
| ;=>(1 "b" "d") | |||
| `[1 ~@c 3] | |||
| ;=>(1 1 "b" "d" 3) | |||
| ;;; TODO: fix this | |||
| ;;;;=>[1 1 "b" "d" 3] | |||
| @ -0,0 +1,164 @@ | |||
| ;; Testing non-macro function | |||
| (not (= 1 1)) | |||
| ;=>false | |||
| ;;; This should fail if it is a macro | |||
| (not (= 1 2)) | |||
| ;=>true | |||
| ;; Testing trivial macros | |||
| (defmacro! one (fn* () 1)) | |||
| (one) | |||
| ;=>1 | |||
| (defmacro! two (fn* () 2)) | |||
| (two) | |||
| ;=>2 | |||
| ;; Testing unless macros | |||
| (defmacro! unless (fn* (pred a b) `(if ~pred ~b ~a))) | |||
| (unless false 7 8) | |||
| ;=>7 | |||
| (unless true 7 8) | |||
| ;=>8 | |||
| (defmacro! unless2 (fn* (pred a b) `(if (not ~pred) ~a ~b))) | |||
| (unless2 false 7 8) | |||
| ;=>7 | |||
| (unless2 true 7 8) | |||
| ;=>8 | |||
| ;; Testing macroexpand | |||
| (macroexpand (unless2 2 3 4)) | |||
| ;=>(if (not 2) 3 4) | |||
| ;; Testing nth, first and rest functions | |||
| (nth '(1) 0) | |||
| ;=>1 | |||
| (nth '(1 2) 1) | |||
| ;=>2 | |||
| (def! x "x") | |||
| (def! x (nth '(1 2) 2)) | |||
| x | |||
| ;=>"x" | |||
| (first '()) | |||
| ;=>nil | |||
| (first '(6)) | |||
| ;=>6 | |||
| (first '(7 8 9)) | |||
| ;=>7 | |||
| (rest '()) | |||
| ;=>() | |||
| (rest '(6)) | |||
| ;=>() | |||
| (rest '(7 8 9)) | |||
| ;=>(8 9) | |||
| ;; Testing or macro | |||
| (or) | |||
| ;=>nil | |||
| (or 1) | |||
| ;=>1 | |||
| (or 1 2 3 4) | |||
| ;=>1 | |||
| (or false 2) | |||
| ;=>2 | |||
| (or false nil 3) | |||
| ;=>3 | |||
| (or false nil false false nil 4) | |||
| ;=>4 | |||
| (or false nil 3 false nil 4) | |||
| ;=>3 | |||
| (or (or false 4)) | |||
| ;=>4 | |||
| ;; Testing cond macro | |||
| (cond) | |||
| ;=>nil | |||
| (cond true 7) | |||
| ;=>7 | |||
| (cond true 7 true 8) | |||
| ;=>7 | |||
| (cond false 7 true 8) | |||
| ;=>8 | |||
| (cond false 7 false 8 "else" 9) | |||
| ;=>9 | |||
| (cond false 7 (= 2 2) 8 "else" 9) | |||
| ;=>8 | |||
| (cond false 7 false 8 false 9) | |||
| ;=>nil | |||
| ;; | |||
| ;; Loading core.mal | |||
| (load-file "../core.mal") | |||
| ;; Testing and macro | |||
| (and) | |||
| ;=>true | |||
| (and 1) | |||
| ;=>1 | |||
| (and 1 2) | |||
| ;=>2 | |||
| (and 1 2 3) | |||
| ;=>3 | |||
| (and 1 2 3 4) | |||
| ;=>4 | |||
| (and 1 2 3 4 false) | |||
| ;=>false | |||
| (and 1 2 3 4 false 5) | |||
| ;=>false | |||
| ;; Testing -> macro | |||
| (-> 7) | |||
| ;=>7 | |||
| (-> (list 7 8 9) first) | |||
| ;=>7 | |||
| (-> (list 7 8 9) (first)) | |||
| ;=>7 | |||
| (-> (list 7 8 9) first (+ 7)) | |||
| ;=>14 | |||
| (-> (list 7 8 9) rest (rest) first (+ 7)) | |||
| ;=>16 | |||
| ;; Testing EVAL in let* | |||
| (let* (x (or nil "yes")) x) | |||
| ;=>"yes" | |||
| ;; | |||
| ;; -------- Optional Functionality -------- | |||
| ;; Testing nth, first, rest with vectors | |||
| (nth [1] 0) | |||
| ;=>1 | |||
| (nth [1 2] 1) | |||
| ;=>2 | |||
| (def! x "x") | |||
| (def! x (nth [1 2] 2)) | |||
| x | |||
| ;=>"x" | |||
| (first []) | |||
| ;=>nil | |||
| (first [10]) | |||
| ;=>10 | |||
| (first [10 11 12]) | |||
| ;=>10 | |||
| (rest []) | |||
| ;=>() | |||
| (rest [10]) | |||
| ;=>() | |||
| (rest [10 11 12]) | |||
| ;=>(11 12) | |||
| ;; Testing EVAL in vector let* | |||
| (let* [x (or nil "yes")] x) | |||
| ;=>"yes" | |||
| @ -0,0 +1,264 @@ | |||
| ;; | |||
| ;; Testing try*/catch* | |||
| (try* 123 (catch* e 456)) | |||
| ;=>123 | |||
| (try* (abc 1 2) (catch* exc (prn "exc is:" exc))) | |||
| ; "exc is:" "'abc' not found" | |||
| ;=>nil | |||
| ;;;TODO: fix so long lines don't trigger ANSI escape codes ;;;(try* | |||
| ;;;(try* (throw ["data" "foo"]) (catch* exc (do (prn "exc is:" exc) 7))) ;;;; | |||
| ;;;; "exc is:" ["data" "foo"] ;;;;=>7 | |||
| ;;;;=>7 | |||
| (try* (throw (list 1 2 3)) (catch* exc (do (prn "err:" exc) 7))) | |||
| ; "err:" (1 2 3) | |||
| ;=>7 | |||
| (try* (throw "my exception") (catch* exc (do (prn "exc:" exc) 7))) | |||
| ; "exc:" "my exception" | |||
| ;=>7 | |||
| ;;; Test that throw is a function: | |||
| (try* (map throw (list 7)) (catch* exc exc)) | |||
| ;=>7 | |||
| ;; | |||
| ;; Testing builtin functions | |||
| (symbol? 'abc) | |||
| ;=>true | |||
| (symbol? "abc") | |||
| ;=>false | |||
| (nil? nil) | |||
| ;=>true | |||
| (nil? true) | |||
| ;=>false | |||
| (true? true) | |||
| ;=>true | |||
| (true? false) | |||
| ;=>false | |||
| (true? true?) | |||
| ;=>false | |||
| (false? false) | |||
| ;=>true | |||
| (false? true) | |||
| ;=>false | |||
| ;; Testing apply function with core functions | |||
| (apply + (list 2 3)) | |||
| ;=>5 | |||
| (apply + 4 (list 5)) | |||
| ;=>9 | |||
| (apply prn (list 1 2 "3" (list))) | |||
| ; 1 2 "3" () | |||
| (apply prn 1 2 (list "3" (list))) | |||
| ; 1 2 "3" () | |||
| ;; Testing apply function with user functions | |||
| (apply (fn* (a b) (+ a b)) (list 2 3)) | |||
| ;=>5 | |||
| (apply (fn* (a b) (+ a b)) 4 (list 5)) | |||
| ;=>9 | |||
| ;; Testing map function | |||
| (def! nums (list 1 2 3)) | |||
| (def! double (fn* (a) (* 2 a))) | |||
| (double 3) | |||
| ;=>6 | |||
| (map double nums) | |||
| ;=>(2 4 6) | |||
| (map (fn* (x) (symbol? x)) (list 1 (symbol "two") "three")) | |||
| ;=>(false true false) | |||
| ;; | |||
| ;; ------- Optional Functionality ---------- | |||
| ;; ------- (Needed for self-hosting) ------- | |||
| ;; Testing symbol and keyword functions | |||
| (symbol? :abc) | |||
| ;=>false | |||
| (symbol? 'abc) | |||
| ;=>true | |||
| (symbol? "abc") | |||
| ;=>false | |||
| (symbol? (symbol "abc")) | |||
| ;=>true | |||
| (keyword? :abc) | |||
| ;=>true | |||
| (keyword? 'abc) | |||
| ;=>false | |||
| (keyword? "abc") | |||
| ;=>false | |||
| (keyword? (keyword "abc")) | |||
| ;=>true | |||
| (symbol "abc") | |||
| ;=>abc | |||
| ;;;TODO: all implementations should suppport this too | |||
| ;;;(keyword :abc) | |||
| ;;;;=>:abc | |||
| (keyword "abc") | |||
| ;=>:abc | |||
| ;; Testing sequential? function | |||
| (sequential? (list 1 2 3)) | |||
| ;=>true | |||
| (sequential? [15]) | |||
| ;=>true | |||
| (sequential? sequential?) | |||
| ;=>false | |||
| (sequential? nil) | |||
| ;=>false | |||
| (sequential? "abc") | |||
| ;=>false | |||
| ;; Testing apply function with core functions and arguments in vector | |||
| (apply + 4 [5]) | |||
| ;=>9 | |||
| (apply prn 1 2 ["3" 4]) | |||
| ; 1 2 "3" 4 | |||
| ;=>nil | |||
| ;; Testing apply function with user functions and arguments in vector | |||
| (apply (fn* (a b) (+ a b)) [2 3]) | |||
| ;=>5 | |||
| (apply (fn* (a b) (+ a b)) 4 [5]) | |||
| ;=>9 | |||
| ;; Testing map function with vectors | |||
| (map (fn* (a) (* 2 a)) [1 2 3]) | |||
| ;=>(2 4 6) | |||
| ;; Testing vector functions | |||
| (vector? [10 11]) | |||
| ;=>true | |||
| (vector? '(12 13)) | |||
| ;=>false | |||
| (vector 3 4 5) | |||
| ;=>[3 4 5] | |||
| (map? {}) | |||
| ;=>true | |||
| (map? '()) | |||
| ;=>false | |||
| (map? []) | |||
| ;=>false | |||
| (map? 'abc) | |||
| ;=>false | |||
| (map? :abc) | |||
| ;=>false | |||
| ;; | |||
| ;; Testing hash-maps | |||
| (hash-map "a" 1) | |||
| ;=>{"a" 1} | |||
| {"a" 1} | |||
| ;=>{"a" 1} | |||
| (assoc {} "a" 1) | |||
| ;=>{"a" 1} | |||
| (get (assoc (assoc {"a" 1 } "b" 2) "c" 3) "a") | |||
| ;=>1 | |||
| (def! hm1 (hash-map)) | |||
| ;=>{} | |||
| (map? hm1) | |||
| ;=>true | |||
| (map? 1) | |||
| ;=>false | |||
| (map? "abc") | |||
| ;=>false | |||
| (get nil "a") | |||
| ;=>nil | |||
| (get hm1 "a") | |||
| ;=>nil | |||
| (contains? hm1 "a") | |||
| ;=>false | |||
| (def! hm2 (assoc hm1 "a" 1)) | |||
| ;=>{"a" 1} | |||
| (get hm1 "a") | |||
| ;=>nil | |||
| (contains? hm1 "a") | |||
| ;=>false | |||
| (get hm2 "a") | |||
| ;=>1 | |||
| (contains? hm2 "a") | |||
| ;=>true | |||
| ;;; TODO: fix. Clojure returns nil but this breaks mal impl | |||
| (keys hm1) | |||
| ;=>() | |||
| (keys hm2) | |||
| ;=>("a") | |||
| ;;; TODO: fix. Clojure returns nil but this breaks mal impl | |||
| (vals hm1) | |||
| ;=>() | |||
| (vals hm2) | |||
| ;=>(1) | |||
| (count (keys (assoc hm2 "b" 2 "c" 3))) | |||
| ;=>3 | |||
| (def! hm3 (assoc hm2 "b" 2)) | |||
| (count (keys hm3)) | |||
| ;=>2 | |||
| (count (vals hm3)) | |||
| ;=>2 | |||
| (dissoc hm3 "a") | |||
| ;=>{"b" 2} | |||
| (dissoc hm3 "a" "b") | |||
| ;=>{} | |||
| (dissoc hm3 "a" "b" "c") | |||
| ;=>{} | |||
| (count (keys hm3)) | |||
| ;=>2 | |||
| ;; Testing keywords as hash-map keys | |||
| (get {:abc 123} :abc) | |||
| ;=>123 | |||
| (contains? {:abc 123} :abc) | |||
| ;=>true | |||
| (contains? {:abcd 123} :abc) | |||
| ;=>false | |||
| (assoc {} :bcd 234) | |||
| ;=>{:bcd 234} | |||
| (dissoc {:cde 345 :fgh 456} :cde) | |||
| ;=>{:fgh 456} | |||
| (keyword? (nth (keys {:abc 123 :def 456}) 0)) | |||
| ;=>true | |||
| ;;; TODO: support : in strings in make impl | |||
| ;;;(keyword? (nth (keys {":abc" 123 ":def" 456}) 0)) | |||
| ;;;;=>false | |||
| (keyword? (nth (vals {"a" :abc "b" :def}) 0)) | |||
| ;=>true | |||
| @ -0,0 +1,225 @@ | |||
| ;;; | |||
| ;;; See IMPL/tests/stepA_mal.mal for implementation specific | |||
| ;;; interop tests. | |||
| ;;; | |||
| ;; | |||
| ;; Testing readline | |||
| (readline "mal-user> ") | |||
| "hello" | |||
| ;=>"\"hello\"" | |||
| ;; | |||
| ;; Testing *host-language* | |||
| ;;; each impl is different, but this should return false | |||
| ;;; rather than throwing an exception | |||
| (= "something bogus" *host-language*) | |||
| ;=>false | |||
| ;; | |||
| ;; ------- Optional Functionality ---------- | |||
| ;; ------- (Needed for self-hosting) ------- | |||
| ;; | |||
| ;; Testing metadata on functions | |||
| ;; | |||
| ;; Testing metadata on mal functions | |||
| (meta (fn* (a) a)) | |||
| ;=>nil | |||
| (meta (with-meta (fn* (a) a) {"b" 1})) | |||
| ;=>{"b" 1} | |||
| (meta (with-meta (fn* (a) a) "abc")) | |||
| ;=>"abc" | |||
| (def! l-wm (with-meta (fn* (a) a) {"b" 2})) | |||
| (meta l-wm) | |||
| ;=>{"b" 2} | |||
| (meta (with-meta l-wm {"new_meta" 123})) | |||
| ;=>{"new_meta" 123} | |||
| (meta l-wm) | |||
| ;=>{"b" 2} | |||
| (def! f-wm (with-meta (fn* [a] (+ 1 a)) {"abc" 1})) | |||
| (meta f-wm) | |||
| ;=>{"abc" 1} | |||
| (meta (with-meta f-wm {"new_meta" 123})) | |||
| ;=>{"new_meta" 123} | |||
| (meta f-wm) | |||
| ;=>{"abc" 1} | |||
| (def! f-wm2 ^{"abc" 1} (fn* [a] (+ 1 a))) | |||
| (meta f-wm2) | |||
| ;=>{"abc" 1} | |||
| ;; Meta of native functions should return nil (not fail) | |||
| (meta +) | |||
| ;=>nil | |||
| ;; | |||
| ;; Make sure closures and metadata co-exist | |||
| (def! gen-plusX (fn* (x) (with-meta (fn* (b) (+ x b)) {"meta" 1}))) | |||
| (def! plus7 (gen-plusX 7)) | |||
| (def! plus8 (gen-plusX 8)) | |||
| (plus7 8) | |||
| ;=>15 | |||
| (meta plus7) | |||
| ;=>{"meta" 1} | |||
| (meta plus8) | |||
| ;=>{"meta" 1} | |||
| (meta (with-meta plus7 {"meta" 2})) | |||
| ;=>{"meta" 2} | |||
| (meta plus8) | |||
| ;=>{"meta" 1} | |||
| ;; | |||
| ;; Testing atoms | |||
| (def! inc3 (fn* (a) (+ 3 a))) | |||
| (def! a (atom 2)) | |||
| ;=>(atom 2) | |||
| ;;;(type a) | |||
| ;;;;=>"atom" | |||
| (deref a) | |||
| ;=>2 | |||
| @a | |||
| ;=>2 | |||
| (reset! a 3) | |||
| ;=>3 | |||
| @a | |||
| ;=>3 | |||
| (swap! a inc3) | |||
| ;=>6 | |||
| @a | |||
| ;=>6 | |||
| (swap! a (fn* (a) a)) | |||
| ;=>6 | |||
| (swap! a (fn* (a) (* 2 a))) | |||
| ;=>12 | |||
| (swap! a (fn* (a b) (* a b)) 10) | |||
| ;=>120 | |||
| (swap! a + 3) | |||
| ;=>123 | |||
| ;; Testing swap!/closure interaction | |||
| (def! inc-it (fn* (a) (+ 1 a))) | |||
| (def! atm (atom 7)) | |||
| (def! f (fn* [] (swap! atm inc-it))) | |||
| (f) | |||
| ;=>8 | |||
| (f) | |||
| ;=>9 | |||
| ;; Testing hash-map evaluation and atoms (i.e. an env) | |||
| (def! e (atom {"+" +})) | |||
| (swap! e assoc "-" -) | |||
| ( (get @e "+") 7 8) | |||
| ;=>15 | |||
| ( (get @e "-") 11 8) | |||
| ;=>3 | |||
| ;; | |||
| ;; ------- Optional Functionality -------------- | |||
| ;; ------- (Not needed for self-hosting) ------- | |||
| ;; | |||
| ;; Testing conj function | |||
| (conj (list) 1) | |||
| ;=>(1) | |||
| (conj (list 1) 2) | |||
| ;=>(2 1) | |||
| (conj (list 2 3) 4) | |||
| ;=>(4 2 3) | |||
| (conj (list 2 3) 4 5 6) | |||
| ;=>(6 5 4 2 3) | |||
| (conj (list 1) (list 2 3)) | |||
| ;=>((2 3) 1) | |||
| (conj [] 1) | |||
| ;=>[1] | |||
| (conj [1] 2) | |||
| ;=>[1 2] | |||
| (conj [2 3] 4) | |||
| ;=>[2 3 4] | |||
| (conj [2 3] 4 5 6) | |||
| ;=>[2 3 4 5 6] | |||
| (conj [1] [2 3]) | |||
| ;=>[1 [2 3]] | |||
| ;; | |||
| ;; Testing metadata on collections | |||
| (meta [1 2 3]) | |||
| ;=>nil | |||
| (with-meta [1 2 3] {"a" 1}) | |||
| ;=>[1 2 3] | |||
| (meta (with-meta [1 2 3] {"a" 1})) | |||
| ;=>{"a" 1} | |||
| (vector? (with-meta [1 2 3] {"a" 1})) | |||
| ;=>true | |||
| (meta (with-meta [1 2 3] "abc")) | |||
| ;=>"abc" | |||
| (meta (with-meta (list 1 2 3) {"a" 1})) | |||
| ;=>{"a" 1} | |||
| (list? (with-meta (list 1 2 3) {"a" 1})) | |||
| ;=>true | |||
| (meta (with-meta {"abc" 123} {"a" 1})) | |||
| ;=>{"a" 1} | |||
| (map? (with-meta {"abc" 123} {"a" 1})) | |||
| ;=>true | |||
| ;;; Not actually supported by Clojure | |||
| ;;;(meta (with-meta (atom 7) {"a" 1})) | |||
| ;;;;=>{"a" 1} | |||
| (def! l-wm (with-meta [4 5 6] {"b" 2})) | |||
| ;=>[4 5 6] | |||
| (meta l-wm) | |||
| ;=>{"b" 2} | |||
| (meta (with-meta l-wm {"new_meta" 123})) | |||
| ;=>{"new_meta" 123} | |||
| (meta l-wm) | |||
| ;=>{"b" 2} | |||
| ;; | |||
| ;; Testing metadata on builtin functions | |||
| (meta +) | |||
| ;=>nil | |||
| (def! f-wm3 ^{"def" 2} +) | |||
| (meta f-wm3) | |||
| ;=>{"def" 2} | |||
| (meta +) | |||
| ;=>nil | |||
| @ -0,0 +1 @@ | |||
| A line of text | |||