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