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