@ -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 |