perf: fix perf3 to show total iters instead of / 3
[jackhill/mal.git] / tests / step9_try.mal
1 ;;
2 ;; Testing try*/catch*
3
4 (try* 123 (catch* e 456))
5 ;=>123
6
7 (try* (abc 1 2) (catch* exc (prn "exc is:" exc)))
8 ; "exc is:" "'abc' not found"
9 ;=>nil
10
11 (try* (throw "my exception") (catch* exc (do (prn "exc:" exc) 7)))
12 ; "exc:" "my exception"
13 ;=>7
14
15 ;;; Test that throw is a function:
16 (try* (map throw (list "my err")) (catch* exc exc))
17 ;=>"my err"
18
19
20 ;;
21 ;; Testing builtin functions
22
23 (symbol? 'abc)
24 ;=>true
25 (symbol? "abc")
26 ;=>false
27
28 (nil? nil)
29 ;=>true
30 (nil? true)
31 ;=>false
32
33 (true? true)
34 ;=>true
35 (true? false)
36 ;=>false
37 (true? true?)
38 ;=>false
39
40 (false? false)
41 ;=>true
42 (false? true)
43 ;=>false
44
45 ;; Testing apply function with core functions
46 (apply + (list 2 3))
47 ;=>5
48 (apply + 4 (list 5))
49 ;=>9
50 (apply prn (list 1 2 "3" (list)))
51 ; 1 2 "3" ()
52 ;=>nil
53 (apply prn 1 2 (list "3" (list)))
54 ; 1 2 "3" ()
55 ;=>nil
56 (apply list (list))
57 ;=>()
58 (apply symbol? (list (quote two)))
59 ;=>true
60
61 ;; Testing apply function with user functions
62 (apply (fn* (a b) (+ a b)) (list 2 3))
63 ;=>5
64 (apply (fn* (a b) (+ a b)) 4 (list 5))
65 ;=>9
66
67 ;; Testing map function
68 (def! nums (list 1 2 3))
69 (def! double (fn* (a) (* 2 a)))
70 (double 3)
71 ;=>6
72 (map double nums)
73 ;=>(2 4 6)
74 (map (fn* (x) (symbol? x)) (list 1 (quote two) "three"))
75 ;=>(false true false)
76
77 ;>>> deferrable=True
78 ;;
79 ;; ------- Deferrable Functionality ----------
80 ;; ------- (Needed for self-hosting) -------
81
82 ;; Testing symbol and keyword functions
83 (symbol? :abc)
84 ;=>false
85 (symbol? 'abc)
86 ;=>true
87 (symbol? "abc")
88 ;=>false
89 (symbol? (symbol "abc"))
90 ;=>true
91 (keyword? :abc)
92 ;=>true
93 (keyword? 'abc)
94 ;=>false
95 (keyword? "abc")
96 ;=>false
97 (keyword? "")
98 ;=>false
99 (keyword? (keyword "abc"))
100 ;=>true
101
102 (symbol "abc")
103 ;=>abc
104 ;;;TODO: all implementations should suppport this too
105 ;;;(keyword :abc)
106 ;;;;=>:abc
107 (keyword "abc")
108 ;=>:abc
109
110 ;; Testing sequential? function
111
112 (sequential? (list 1 2 3))
113 ;=>true
114 (sequential? [15])
115 ;=>true
116 (sequential? sequential?)
117 ;=>false
118 (sequential? nil)
119 ;=>false
120 (sequential? "abc")
121 ;=>false
122
123 ;; Testing apply function with core functions and arguments in vector
124 (apply + 4 [5])
125 ;=>9
126 (apply prn 1 2 ["3" 4])
127 ; 1 2 "3" 4
128 ;=>nil
129 (apply list [])
130 ;=>()
131 ;; Testing apply function with user functions and arguments in vector
132 (apply (fn* (a b) (+ a b)) [2 3])
133 ;=>5
134 (apply (fn* (a b) (+ a b)) 4 [5])
135 ;=>9
136
137
138 ;; Testing map function with vectors
139 (map (fn* (a) (* 2 a)) [1 2 3])
140 ;=>(2 4 6)
141
142 (map (fn* [& args] (list? args)) [1 2])
143 ;=>(true true)
144
145 ;; Testing vector functions
146
147 (vector? [10 11])
148 ;=>true
149 (vector? '(12 13))
150 ;=>false
151 (vector 3 4 5)
152 ;=>[3 4 5]
153
154 (map? {})
155 ;=>true
156 (map? '())
157 ;=>false
158 (map? [])
159 ;=>false
160 (map? 'abc)
161 ;=>false
162 (map? :abc)
163 ;=>false
164
165 ;;
166 ;; Testing hash-maps
167 (hash-map "a" 1)
168 ;=>{"a" 1}
169
170 {"a" 1}
171 ;=>{"a" 1}
172
173 (assoc {} "a" 1)
174 ;=>{"a" 1}
175
176 (get (assoc (assoc {"a" 1 } "b" 2) "c" 3) "a")
177 ;=>1
178
179 (def! hm1 (hash-map))
180 ;=>{}
181
182 (map? hm1)
183 ;=>true
184 (map? 1)
185 ;=>false
186 (map? "abc")
187 ;=>false
188
189 (get nil "a")
190 ;=>nil
191
192 (get hm1 "a")
193 ;=>nil
194
195 (contains? hm1 "a")
196 ;=>false
197
198 (def! hm2 (assoc hm1 "a" 1))
199 ;=>{"a" 1}
200
201 (get hm1 "a")
202 ;=>nil
203
204 (contains? hm1 "a")
205 ;=>false
206
207 (get hm2 "a")
208 ;=>1
209
210 (contains? hm2 "a")
211 ;=>true
212
213
214 ;;; TODO: fix. Clojure returns nil but this breaks mal impl
215 (keys hm1)
216 ;=>()
217
218 (keys hm2)
219 ;=>("a")
220
221 ;;; TODO: fix. Clojure returns nil but this breaks mal impl
222 (vals hm1)
223 ;=>()
224
225 (vals hm2)
226 ;=>(1)
227
228 (count (keys (assoc hm2 "b" 2 "c" 3)))
229 ;=>3
230
231 ;; Testing keywords as hash-map keys
232 (get {:abc 123} :abc)
233 ;=>123
234 (contains? {:abc 123} :abc)
235 ;=>true
236 (contains? {:abcd 123} :abc)
237 ;=>false
238 (assoc {} :bcd 234)
239 ;=>{:bcd 234}
240 (keyword? (nth (keys {:abc 123 :def 456}) 0))
241 ;=>true
242 ;;; TODO: support : in strings in make impl
243 ;;;(keyword? (nth (keys {":abc" 123 ":def" 456}) 0))
244 ;;;;=>false
245 (keyword? (nth (vals {"a" :abc "b" :def}) 0))
246 ;=>true
247
248 ;; Testing whether assoc updates properly
249 (def! hm4 (assoc {:a 1 :b 2} :a 3 :c 1))
250 (get hm4 :a)
251 ;=>3
252 (get hm4 :b)
253 ;=>2
254 (get hm4 :c)
255 ;=>1
256
257 ;; Testing nil as hash-map values
258 (contains? {:abc nil} :abc)
259 ;=>true
260 (assoc {} :bcd nil)
261 ;=>{:bcd nil}
262
263 ;;
264 ;; Additional str and pr-str tests
265
266 (str "A" {:abc "val"} "Z")
267 ;=>"A{:abc val}Z"
268
269 (str true "." false "." nil "." :keyw "." 'symb)
270 ;=>"true.false.nil.:keyw.symb"
271
272 (pr-str "A" {:abc "val"} "Z")
273 ;=>"\"A\" {:abc \"val\"} \"Z\""
274
275 (pr-str true "." false "." nil "." :keyw "." 'symb)
276 ;=>"true \".\" false \".\" nil \".\" :keyw \".\" symb"
277
278 (def! s (str {:abc "val1" :def "val2"}))
279 (or (= s "{:abc val1 :def val2}") (= s "{:def val2 :abc val1}"))
280 ;=>true
281
282 (def! p (pr-str {:abc "val1" :def "val2"}))
283 (or (= p "{:abc \"val1\" :def \"val2\"}") (= p "{:def \"val2\" :abc \"val1\"}"))
284 ;=>true
285
286 ;;
287 ;; Test extra function arguments as Mal List (bypassing TCO with apply)
288 (apply (fn* (& more) (list? more)) [1 2 3])
289 ;=>true
290 (apply (fn* (& more) (list? more)) [])
291 ;=>true
292 (apply (fn* (a & more) (list? more)) [1])
293 ;=>true
294
295 ;>>> soft=True
296 ;>>> optional=True
297 ;;
298 ;; ------- Optional Functionality --------------
299 ;; ------- (Not needed for self-hosting) -------
300
301
302 ;;;TODO: fix so long lines don't trigger ANSI escape codes ;;;(try*
303 ;;;(try* (throw ["data" "foo"]) (catch* exc (do (prn "exc is:" exc) 7))) ;;;;
304 ;;;; "exc is:" ["data" "foo"] ;;;;=>7
305 ;;;;=>7
306
307 ;;
308 ;; Testing throwing non-strings
309 (try* (throw (list 1 2 3)) (catch* exc (do (prn "err:" exc) 7)))
310 ; "err:" (1 2 3)
311 ;=>7
312
313 ;;
314 ;; Testing dissoc
315 (def! hm3 (assoc hm2 "b" 2))
316 (count (keys hm3))
317 ;=>2
318 (count (vals hm3))
319 ;=>2
320 (dissoc hm3 "a")
321 ;=>{"b" 2}
322 (dissoc hm3 "a" "b")
323 ;=>{}
324 (dissoc hm3 "a" "b" "c")
325 ;=>{}
326 (count (keys hm3))
327 ;=>2
328
329 (dissoc {:cde 345 :fgh 456} :cde)
330 ;=>{:fgh 456}
331 (dissoc {:cde nil :fgh 456} :cde)
332 ;=>{:fgh 456}
333
334 ;;
335 ;; Testing equality of hash-maps
336 (= {} {})
337 ;=>true
338 (= {:a 11 :b 22} (hash-map :b 22 :a 11))
339 ;=>true
340 (= {:a 11 :b [22 33]} (hash-map :b [22 33] :a 11))
341 ;=>true
342 (= {:a 11 :b {:c 33}} (hash-map :b {:c 33} :a 11))
343 ;=>true
344 (= {:a 11 :b 22} (hash-map :b 23 :a 11))
345 ;=>false
346 (= {:a 11 :b 22} (hash-map :a 11))
347 ;=>false
348 (= {:a [11 22]} {:a (list 11 22)})
349 ;=>true
350 (= {:a 11 :b 22} (list :a 11 :b 22))
351 ;=>false
352 (= {} [])
353 ;=>false
354 (= [] {})
355 ;=>false
356