Fix bit-count* bug
[bpt/guile.git] / test-suite / tests / tree-il.test
CommitLineData
ce09ee19
AW
1;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*-
2;;;; Andy Wingo <wingo@pobox.com> --- May 2009
3;;;;
0ce22459
MW
4;;;; Copyright (C) 2009, 2010, 2011, 2012, 2013,
5;;;; 2014 Free Software Foundation, Inc.
a4060f67 6;;;;
ce09ee19
AW
7;;;; This library is free software; you can redistribute it and/or
8;;;; modify it under the terms of the GNU Lesser General Public
9;;;; License as published by the Free Software Foundation; either
53befeb7 10;;;; version 3 of the License, or (at your option) any later version.
a4060f67 11;;;;
ce09ee19
AW
12;;;; This library is distributed in the hope that it will be useful,
13;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15;;;; Lesser General Public License for more details.
a4060f67 16;;;;
ce09ee19
AW
17;;;; You should have received a copy of the GNU Lesser General Public
18;;;; License along with this library; if not, write to the Free Software
19;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21(define-module (test-suite tree-il)
22 #:use-module (test-suite lib)
23 #:use-module (system base compile)
24 #:use-module (system base pmatch)
4b856371 25 #:use-module (system base message)
ce09ee19 26 #:use-module (language tree-il)
a4c7fe5c 27 #:use-module (language tree-il primitives)
4b856371
LC
28 #:use-module (language glil)
29 #:use-module (srfi srfi-13))
ce09ee19 30
e0c90f90
AW
31;; Of course, the GLIL that is emitted depends on the source info of the
32;; input. Here we're not concerned about that, so we strip source
33;; information from the incoming tree-il.
34
35(define (strip-source x)
36 (post-order! (lambda (x) (set! (tree-il-src x) #f))
37 x))
38
ce09ee19 39(define-syntax assert-tree-il->glil
11671bba
LC
40 (syntax-rules (with-partial-evaluation without-partial-evaluation
41 with-options)
42 ((_ with-partial-evaluation in pat test ...)
43 (assert-tree-il->glil with-options (#:partial-eval? #t)
44 in pat test ...))
45 ((_ without-partial-evaluation in pat test ...)
46 (assert-tree-il->glil with-options (#:partial-eval? #f)
47 in pat test ...))
48 ((_ with-options opts in pat test ...)
ce09ee19
AW
49 (let ((exp 'in))
50 (pass-if 'in
51 (let ((glil (unparse-glil
e0c90f90 52 (compile (strip-source (parse-tree-il exp))
11671bba
LC
53 #:from 'tree-il #:to 'glil
54 #:opts 'opts))))
ce09ee19
AW
55 (pmatch glil
56 (pat (guard test ...) #t)
11671bba
LC
57 (else #f))))))
58 ((_ in pat test ...)
59 (assert-tree-il->glil with-partial-evaluation
60 in pat test ...))))
ce09ee19 61
2446f8e1
LC
62(define-syntax-rule (pass-if-primitives-resolved in expected)
63 (pass-if (format #f "primitives-resolved in ~s" 'in)
64 (let* ((module (let ((m (make-module)))
65 (beautify-user-module! m)
66 m))
67 (orig (parse-tree-il 'in))
68 (resolved (expand-primitives! (resolve-primitives! orig module))))
69 (or (equal? (unparse-tree-il resolved) 'expected)
70 (begin
71 (format (current-error-port)
72 "primitive test failed: got ~s, expected ~s"
73 resolved 'expected)
74 #f)))))
75
335c8a89
AW
76(define-syntax pass-if-tree-il->scheme
77 (syntax-rules ()
78 ((_ in pat)
79 (assert-scheme->tree-il->scheme in pat #t))
80 ((_ in pat guard-exp)
81 (pass-if 'in
82 (pmatch (tree-il->scheme
83 (compile 'in #:from 'scheme #:to 'tree-il))
84 (pat (guard guard-exp) #t)
85 (_ #f))))))
86
11671bba 87\f
2446f8e1
LC
88(with-test-prefix "primitives"
89
75a5de18 90 (with-test-prefix "eqv?"
2446f8e1 91
75a5de18
MW
92 (pass-if-primitives-resolved
93 (apply (primitive eqv?) (const #f) (toplevel x))
94 (apply (primitive eq?) (const #f) (toplevel x)))
2446f8e1 95
75a5de18
MW
96 (pass-if-primitives-resolved
97 (apply (primitive eqv?) (const ()) (toplevel x))
98 (apply (primitive eq?) (const ()) (toplevel x)))
2446f8e1 99
75a5de18
MW
100 (pass-if-primitives-resolved
101 (apply (primitive eqv?) (const #t) (lexical x y))
102 (apply (primitive eq?) (const #t) (lexical x y)))
2446f8e1 103
75a5de18
MW
104 (pass-if-primitives-resolved
105 (apply (primitive eqv?) (const this-is-a-symbol) (toplevel x))
106 (apply (primitive eq?) (const this-is-a-symbol) (toplevel x)))
2446f8e1 107
75a5de18
MW
108 (pass-if-primitives-resolved
109 (apply (primitive eqv?) (const 42) (toplevel x))
110 (apply (primitive eq?) (const 42) (toplevel x)))
ebd36316 111
75a5de18
MW
112 (pass-if-primitives-resolved
113 (apply (primitive eqv?) (const 42.0) (toplevel x))
114 (apply (primitive eqv?) (const 42.0) (toplevel x)))
115
116 (pass-if-primitives-resolved
117 (apply (primitive eqv?) (const #nil) (toplevel x))
118 (apply (primitive eq?) (const #nil) (toplevel x))))
119
120 (with-test-prefix "equal?"
121
122 (pass-if-primitives-resolved
123 (apply (primitive equal?) (const #f) (toplevel x))
124 (apply (primitive eq?) (const #f) (toplevel x)))
125
126 (pass-if-primitives-resolved
127 (apply (primitive equal?) (const ()) (toplevel x))
128 (apply (primitive eq?) (const ()) (toplevel x)))
129
130 (pass-if-primitives-resolved
131 (apply (primitive equal?) (const #t) (lexical x y))
132 (apply (primitive eq?) (const #t) (lexical x y)))
133
134 (pass-if-primitives-resolved
135 (apply (primitive equal?) (const this-is-a-symbol) (toplevel x))
136 (apply (primitive eq?) (const this-is-a-symbol) (toplevel x)))
137
138 (pass-if-primitives-resolved
139 (apply (primitive equal?) (const 42) (toplevel x))
140 (apply (primitive eq?) (const 42) (toplevel x)))
141
142 (pass-if-primitives-resolved
143 (apply (primitive equal?) (const 42.0) (toplevel x))
144 (apply (primitive equal?) (const 42.0) (toplevel x)))
145
146 (pass-if-primitives-resolved
147 (apply (primitive equal?) (const #nil) (toplevel x))
148 (apply (primitive eq?) (const #nil) (toplevel x)))))
2446f8e1
LC
149
150\f
335c8a89
AW
151(with-test-prefix "tree-il->scheme"
152 (pass-if-tree-il->scheme
153 (case-lambda ((a) a) ((b c) (list b c)))
154 (case-lambda ((,a) ,a1) ((,b ,c) (list ,b1 ,c1)))
155 (and (eq? a a1) (eq? b b1) (eq? c c1))))
156
ce09ee19
AW
157(with-test-prefix "void"
158 (assert-tree-il->glil
159 (void)
8a4ca0ea 160 (program () (std-prelude 0 0 #f) (label _) (void) (call return 1)))
ce09ee19
AW
161 (assert-tree-il->glil
162 (begin (void) (const 1))
8a4ca0ea 163 (program () (std-prelude 0 0 #f) (label _) (const 1) (call return 1)))
ce09ee19
AW
164 (assert-tree-il->glil
165 (apply (primitive +) (void) (const 1))
8a4ca0ea 166 (program () (std-prelude 0 0 #f) (label _) (void) (call add1 1) (call return 1))))
ce09ee19
AW
167
168(with-test-prefix "application"
169 (assert-tree-il->glil
170 (apply (toplevel foo) (const 1))
a5bbb22e 171 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (const 1) (call tail-call 1)))
8a4ca0ea 172 (assert-tree-il->glil
ce09ee19 173 (begin (apply (toplevel foo) (const 1)) (void))
8a4ca0ea 174 (program () (std-prelude 0 0 #f) (label _) (call new-frame 0) (toplevel ref foo) (const 1) (mv-call 1 ,l1)
0f423f20 175 (call drop 1) (branch br ,l2)
05c51bcf 176 (label ,l3) (mv-bind 0 #f)
0f423f20 177 (label ,l4)
30a5e062 178 (void) (call return 1))
0f423f20 179 (and (eq? l1 l3) (eq? l2 l4)))
ce09ee19
AW
180 (assert-tree-il->glil
181 (apply (toplevel foo) (apply (toplevel bar)))
8a4ca0ea 182 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (call new-frame 0) (toplevel ref bar) (call call 0)
a5bbb22e 183 (call tail-call 1))))
ce09ee19
AW
184
185(with-test-prefix "conditional"
8a4ca0ea 186 (assert-tree-il->glil
0e4b7818
AW
187 (if (toplevel foo) (const 1) (const 2))
188 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (branch br-if-not ,l1)
ce09ee19
AW
189 (const 1) (call return 1)
190 (label ,l2) (const 2) (call return 1))
191 (eq? l1 l2))
11671bba
LC
192
193 (assert-tree-il->glil without-partial-evaluation
0e4b7818
AW
194 (begin (if (toplevel foo) (const 1) (const 2)) (const #f))
195 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (branch br-if-not ,l1) (branch br ,l2)
ce09ee19
AW
196 (label ,l3) (label ,l4) (const #f) (call return 1))
197 (eq? l1 l3) (eq? l2 l4))
198
8a4ca0ea 199 (assert-tree-il->glil
0e4b7818
AW
200 (apply (primitive null?) (if (toplevel foo) (const 1) (const 2)))
201 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (branch br-if-not ,l1)
ce09ee19
AW
202 (const 1) (branch br ,l2)
203 (label ,l3) (const 2) (label ,l4)
204 (call null? 1) (call return 1))
205 (eq? l1 l3) (eq? l2 l4)))
206
207(with-test-prefix "primitive-ref"
208 (assert-tree-il->glil
209 (primitive +)
8a4ca0ea 210 (program () (std-prelude 0 0 #f) (label _) (toplevel ref +) (call return 1)))
ce09ee19
AW
211
212 (assert-tree-il->glil
213 (begin (primitive +) (const #f))
8a4ca0ea 214 (program () (std-prelude 0 0 #f) (label _) (const #f) (call return 1)))
ce09ee19
AW
215
216 (assert-tree-il->glil
217 (apply (primitive null?) (primitive +))
8a4ca0ea 218 (program () (std-prelude 0 0 #f) (label _) (toplevel ref +) (call null? 1)
ce09ee19
AW
219 (call return 1))))
220
221(with-test-prefix "lexical refs"
11671bba 222 (assert-tree-il->glil without-partial-evaluation
ce09ee19 223 (let (x) (y) ((const 1)) (lexical x y))
8a4ca0ea 224 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
225 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
226 (lexical #t #f ref 0) (call return 1)
ce09ee19
AW
227 (unbind)))
228
9068f4f5 229 (assert-tree-il->glil with-options (#:partial-eval? #f #:cse? #f)
ce09ee19 230 (let (x) (y) ((const 1)) (begin (lexical x y) (const #f)))
8a4ca0ea 231 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3 232 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
ce09ee19
AW
233 (const #f) (call return 1)
234 (unbind)))
235
11671bba 236 (assert-tree-il->glil without-partial-evaluation
ce09ee19 237 (let (x) (y) ((const 1)) (apply (primitive null?) (lexical x y)))
8a4ca0ea 238 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
239 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
240 (lexical #t #f ref 0) (call null? 1) (call return 1)
ce09ee19
AW
241 (unbind))))
242
243(with-test-prefix "lexical sets"
244 (assert-tree-il->glil
aaae0d5a
AW
245 ;; unreferenced sets may be optimized away -- make sure they are ref'd
246 (let (x) (y) ((const 1))
247 (set! (lexical x y) (apply (primitive 1+) (lexical x y))))
8a4ca0ea 248 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3 249 (const 1) (bind (x #t 0)) (lexical #t #t box 0)
aaae0d5a
AW
250 (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0)
251 (void) (call return 1)
ce09ee19
AW
252 (unbind)))
253
254 (assert-tree-il->glil
aaae0d5a
AW
255 (let (x) (y) ((const 1))
256 (begin (set! (lexical x y) (apply (primitive 1+) (lexical x y)))
257 (lexical x y)))
8a4ca0ea 258 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3 259 (const 1) (bind (x #t 0)) (lexical #t #t box 0)
aaae0d5a
AW
260 (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0)
261 (lexical #t #t ref 0) (call return 1)
ce09ee19
AW
262 (unbind)))
263
264 (assert-tree-il->glil
265 (let (x) (y) ((const 1))
aaae0d5a
AW
266 (apply (primitive null?)
267 (set! (lexical x y) (apply (primitive 1+) (lexical x y)))))
8a4ca0ea 268 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3 269 (const 1) (bind (x #t 0)) (lexical #t #t box 0)
aaae0d5a
AW
270 (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0) (void)
271 (call null? 1) (call return 1)
ce09ee19
AW
272 (unbind))))
273
274(with-test-prefix "module refs"
275 (assert-tree-il->glil
276 (@ (foo) bar)
8a4ca0ea 277 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
278 (module public ref (foo) bar)
279 (call return 1)))
280
281 (assert-tree-il->glil
282 (begin (@ (foo) bar) (const #f))
8a4ca0ea 283 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
284 (module public ref (foo) bar) (call drop 1)
285 (const #f) (call return 1)))
286
287 (assert-tree-il->glil
288 (apply (primitive null?) (@ (foo) bar))
8a4ca0ea 289 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
290 (module public ref (foo) bar)
291 (call null? 1) (call return 1)))
292
293 (assert-tree-il->glil
294 (@@ (foo) bar)
8a4ca0ea 295 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
296 (module private ref (foo) bar)
297 (call return 1)))
298
299 (assert-tree-il->glil
300 (begin (@@ (foo) bar) (const #f))
8a4ca0ea 301 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
302 (module private ref (foo) bar) (call drop 1)
303 (const #f) (call return 1)))
304
305 (assert-tree-il->glil
306 (apply (primitive null?) (@@ (foo) bar))
8a4ca0ea 307 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
308 (module private ref (foo) bar)
309 (call null? 1) (call return 1))))
310
311(with-test-prefix "module sets"
312 (assert-tree-il->glil
313 (set! (@ (foo) bar) (const 2))
8a4ca0ea 314 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
315 (const 2) (module public set (foo) bar)
316 (void) (call return 1)))
317
318 (assert-tree-il->glil
319 (begin (set! (@ (foo) bar) (const 2)) (const #f))
8a4ca0ea 320 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
321 (const 2) (module public set (foo) bar)
322 (const #f) (call return 1)))
323
324 (assert-tree-il->glil
325 (apply (primitive null?) (set! (@ (foo) bar) (const 2)))
8a4ca0ea 326 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
327 (const 2) (module public set (foo) bar)
328 (void) (call null? 1) (call return 1)))
329
330 (assert-tree-il->glil
331 (set! (@@ (foo) bar) (const 2))
8a4ca0ea 332 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
333 (const 2) (module private set (foo) bar)
334 (void) (call return 1)))
335
336 (assert-tree-il->glil
337 (begin (set! (@@ (foo) bar) (const 2)) (const #f))
8a4ca0ea 338 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
339 (const 2) (module private set (foo) bar)
340 (const #f) (call return 1)))
341
342 (assert-tree-il->glil
343 (apply (primitive null?) (set! (@@ (foo) bar) (const 2)))
8a4ca0ea 344 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
345 (const 2) (module private set (foo) bar)
346 (void) (call null? 1) (call return 1))))
347
348(with-test-prefix "toplevel refs"
349 (assert-tree-il->glil
350 (toplevel bar)
8a4ca0ea 351 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
352 (toplevel ref bar)
353 (call return 1)))
354
11671bba 355 (assert-tree-il->glil without-partial-evaluation
ce09ee19 356 (begin (toplevel bar) (const #f))
8a4ca0ea 357 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
358 (toplevel ref bar) (call drop 1)
359 (const #f) (call return 1)))
360
361 (assert-tree-il->glil
362 (apply (primitive null?) (toplevel bar))
8a4ca0ea 363 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
364 (toplevel ref bar)
365 (call null? 1) (call return 1))))
366
367(with-test-prefix "toplevel sets"
368 (assert-tree-il->glil
369 (set! (toplevel bar) (const 2))
8a4ca0ea 370 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
371 (const 2) (toplevel set bar)
372 (void) (call return 1)))
373
374 (assert-tree-il->glil
375 (begin (set! (toplevel bar) (const 2)) (const #f))
8a4ca0ea 376 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
377 (const 2) (toplevel set bar)
378 (const #f) (call return 1)))
379
380 (assert-tree-il->glil
381 (apply (primitive null?) (set! (toplevel bar) (const 2)))
8a4ca0ea 382 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
383 (const 2) (toplevel set bar)
384 (void) (call null? 1) (call return 1))))
385
386(with-test-prefix "toplevel defines"
387 (assert-tree-il->glil
388 (define bar (const 2))
8a4ca0ea 389 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
390 (const 2) (toplevel define bar)
391 (void) (call return 1)))
392
393 (assert-tree-il->glil
394 (begin (define bar (const 2)) (const #f))
8a4ca0ea 395 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
396 (const 2) (toplevel define bar)
397 (const #f) (call return 1)))
398
399 (assert-tree-il->glil
400 (apply (primitive null?) (define bar (const 2)))
8a4ca0ea 401 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
402 (const 2) (toplevel define bar)
403 (void) (call null? 1) (call return 1))))
404
405(with-test-prefix "constants"
406 (assert-tree-il->glil
407 (const 2)
8a4ca0ea 408 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
409 (const 2) (call return 1)))
410
411 (assert-tree-il->glil
412 (begin (const 2) (const #f))
8a4ca0ea 413 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
414 (const #f) (call return 1)))
415
416 (assert-tree-il->glil
11671bba 417 ;; This gets simplified by `peval'.
ce09ee19 418 (apply (primitive null?) (const 2))
8a4ca0ea 419 (program () (std-prelude 0 0 #f) (label _)
11671bba 420 (const #f) (call return 1))))
ce09ee19 421
60d4b224
AW
422(with-test-prefix "letrec"
423 ;; simple bindings -> let
11671bba 424 (assert-tree-il->glil without-partial-evaluation
60d4b224
AW
425 (letrec (x y) (x1 y1) ((const 10) (const 20))
426 (apply (toplevel foo) (lexical x x1) (lexical y y1)))
427 (program () (std-prelude 0 2 #f) (label _)
428 (const 10) (const 20)
429 (bind (x #f 0) (y #f 1))
430 (lexical #t #f set 1) (lexical #t #f set 0)
431 (toplevel ref foo)
432 (lexical #t #f ref 0) (lexical #t #f ref 1)
433 (call tail-call 2)
434 (unbind)))
435
436 ;; complex bindings -> box and set! within let
11671bba 437 (assert-tree-il->glil without-partial-evaluation
60d4b224
AW
438 (letrec (x y) (x1 y1) ((apply (toplevel foo)) (apply (toplevel bar)))
439 (apply (primitive +) (lexical x x1) (lexical y y1)))
440 (program () (std-prelude 0 4 #f) (label _)
441 (void) (void) ;; what are these?
442 (bind (x #t 0) (y #t 1))
443 (lexical #t #t box 1) (lexical #t #t box 0)
444 (call new-frame 0) (toplevel ref foo) (call call 0)
445 (call new-frame 0) (toplevel ref bar) (call call 0)
446 (bind (x #f 2) (y #f 3)) (lexical #t #f set 3) (lexical #t #f set 2)
447 (lexical #t #f ref 2) (lexical #t #t set 0)
02060279
AW
448 (lexical #t #f ref 3) (lexical #t #t set 1)
449 (void) (lexical #t #f set 2) (void) (lexical #t #f set 3) ;; clear bindings
450 (unbind)
60d4b224
AW
451 (lexical #t #t ref 0) (lexical #t #t ref 1)
452 (call add 2) (call return 1) (unbind)))
453
454 ;; complex bindings in letrec* -> box and set! in order
11671bba 455 (assert-tree-il->glil without-partial-evaluation
60d4b224
AW
456 (letrec* (x y) (x1 y1) ((apply (toplevel foo)) (apply (toplevel bar)))
457 (apply (primitive +) (lexical x x1) (lexical y y1)))
458 (program () (std-prelude 0 2 #f) (label _)
459 (void) (void) ;; what are these?
460 (bind (x #t 0) (y #t 1))
461 (lexical #t #t box 1) (lexical #t #t box 0)
462 (call new-frame 0) (toplevel ref foo) (call call 0)
463 (lexical #t #t set 0)
464 (call new-frame 0) (toplevel ref bar) (call call 0)
465 (lexical #t #t set 1)
466 (lexical #t #t ref 0)
467 (lexical #t #t ref 1)
65ea26c5
LC
468 (call add 2) (call return 1) (unbind)))
469
470 ;; simple bindings in letrec* -> equivalent to letrec
11671bba 471 (assert-tree-il->glil without-partial-evaluation
65ea26c5
LC
472 (letrec* (x y) (xx yy) ((const 1) (const 2))
473 (lexical y yy))
474 (program () (std-prelude 0 1 #f) (label _)
475 (const 2)
476 (bind (y #f 0)) ;; X is removed, and Y is unboxed
477 (lexical #t #f set 0)
478 (lexical #t #f ref 0)
479 (call return 1) (unbind))))
60d4b224 480
ce09ee19
AW
481(with-test-prefix "lambda"
482 (assert-tree-il->glil
8a4ca0ea 483 (lambda ()
1e2a8edb 484 (lambda-case (((x) #f #f #f () (y)) (const 2)) #f))
8a4ca0ea 485 (program () (std-prelude 0 0 #f) (label _)
258344b4 486 (program () (std-prelude 1 1 #f)
8a4ca0ea
AW
487 (bind (x #f 0)) (label _)
488 (const 2) (call return 1) (unbind))
ce09ee19
AW
489 (call return 1)))
490
491 (assert-tree-il->glil
8a4ca0ea 492 (lambda ()
1e2a8edb 493 (lambda-case (((x y) #f #f #f () (x1 y1))
8a4ca0ea
AW
494 (const 2))
495 #f))
496 (program () (std-prelude 0 0 #f) (label _)
258344b4 497 (program () (std-prelude 2 2 #f)
8a4ca0ea
AW
498 (bind (x #f 0) (y #f 1)) (label _)
499 (const 2) (call return 1)
500 (unbind))
ce09ee19
AW
501 (call return 1)))
502
503 (assert-tree-il->glil
8a4ca0ea 504 (lambda ()
1e2a8edb 505 (lambda-case ((() #f x #f () (y)) (const 2))
8a4ca0ea
AW
506 #f))
507 (program () (std-prelude 0 0 #f) (label _)
899d37a6 508 (program () (opt-prelude 0 0 0 1 #f)
8a4ca0ea
AW
509 (bind (x #f 0)) (label _)
510 (const 2) (call return 1)
511 (unbind))
ce09ee19
AW
512 (call return 1)))
513
514 (assert-tree-il->glil
8a4ca0ea 515 (lambda ()
1e2a8edb 516 (lambda-case (((x) #f x1 #f () (y y1)) (const 2))
8a4ca0ea
AW
517 #f))
518 (program () (std-prelude 0 0 #f) (label _)
899d37a6 519 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
520 (bind (x #f 0) (x1 #f 1)) (label _)
521 (const 2) (call return 1)
522 (unbind))
ce09ee19
AW
523 (call return 1)))
524
525 (assert-tree-il->glil
8a4ca0ea 526 (lambda ()
1e2a8edb 527 (lambda-case (((x) #f x1 #f () (y y1)) (lexical x y))
8a4ca0ea
AW
528 #f))
529 (program () (std-prelude 0 0 #f) (label _)
899d37a6 530 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
531 (bind (x #f 0) (x1 #f 1)) (label _)
532 (lexical #t #f ref 0) (call return 1)
533 (unbind))
ce09ee19
AW
534 (call return 1)))
535
536 (assert-tree-il->glil
8a4ca0ea 537 (lambda ()
1e2a8edb 538 (lambda-case (((x) #f x1 #f () (y y1)) (lexical x1 y1))
8a4ca0ea
AW
539 #f))
540 (program () (std-prelude 0 0 #f) (label _)
899d37a6 541 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
542 (bind (x #f 0) (x1 #f 1)) (label _)
543 (lexical #t #f ref 1) (call return 1)
544 (unbind))
a1a482e0
AW
545 (call return 1)))
546
547 (assert-tree-il->glil
8a4ca0ea 548 (lambda ()
1e2a8edb 549 (lambda-case (((x) #f #f #f () (x1))
8a4ca0ea 550 (lambda ()
1e2a8edb 551 (lambda-case (((y) #f #f #f () (y1))
8a4ca0ea
AW
552 (lexical x x1))
553 #f)))
554 #f))
555 (program () (std-prelude 0 0 #f) (label _)
556 (program () (std-prelude 1 1 #f)
557 (bind (x #f 0)) (label _)
258344b4 558 (program () (std-prelude 1 1 #f)
8a4ca0ea
AW
559 (bind (y #f 0)) (label _)
560 (lexical #f #f ref 0) (call return 1)
561 (unbind))
66d3e9a3 562 (lexical #t #f ref 0)
6f16379e 563 (call make-closure 1)
8a4ca0ea
AW
564 (call return 1)
565 (unbind))
ce09ee19
AW
566 (call return 1))))
567
568(with-test-prefix "sequence"
569 (assert-tree-il->glil
570 (begin (begin (const 2) (const #f)) (const #t))
8a4ca0ea 571 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
572 (const #t) (call return 1)))
573
574 (assert-tree-il->glil
11671bba 575 ;; This gets simplified by `peval'.
ce09ee19 576 (apply (primitive null?) (begin (const #f) (const 2)))
8a4ca0ea 577 (program () (std-prelude 0 0 #f) (label _)
11671bba 578 (const #f) (call return 1))))
5af166bd 579
b88fef55
AW
580(with-test-prefix "values"
581 (assert-tree-il->glil
582 (apply (primitive values)
583 (apply (primitive values) (const 1) (const 2)))
584 (program () (std-prelude 0 0 #f) (label _)
585 (const 1) (call return 1)))
586
587 (assert-tree-il->glil
588 (apply (primitive values)
589 (apply (primitive values) (const 1) (const 2))
590 (const 3))
591 (program () (std-prelude 0 0 #f) (label _)
592 (const 1) (const 3) (call return/values 2)))
593
594 (assert-tree-il->glil
595 (apply (primitive +)
596 (apply (primitive values) (const 1) (const 2)))
597 (program () (std-prelude 0 0 #f) (label _)
c3d5344a
AW
598 (const 1) (call return 1)))
599
600 ;; Testing `(values foo)' in push context with RA.
601 (assert-tree-il->glil without-partial-evaluation
602 (apply (primitive cdr)
603 (letrec (lp) (#{lp ~V9KrhVD4PFEL6oCTrLg3A}#)
604 ((lambda ((name . lp))
605 (lambda-case ((() #f #f #f () ())
606 (apply (toplevel values) (const (one two)))))))
607 (apply (lexical lp #{lp ~V9KrhVD4PFEL6oCTrLg3A}#))))
608 (program () (std-prelude 0 0 #f) (label _)
609 (branch br _) ;; entering the fix, jump to :2
610 ;; :1 body of lp, jump to :3
611 (label _) (bind) (const (one two)) (branch br _) (unbind)
612 ;; :2 initial call of lp, jump to :1
613 (label _) (bind) (branch br _) (label _) (unbind)
614 ;; :3 the push continuation
615 (call cdr 1) (call return 1))))
b88fef55 616
5af166bd
AW
617;; FIXME: binding info for or-hacked locals might bork the disassembler,
618;; and could be tightened in any case
619(with-test-prefix "the or hack"
11671bba 620 (assert-tree-il->glil without-partial-evaluation
5af166bd
AW
621 (let (x) (y) ((const 1))
622 (if (lexical x y)
623 (lexical x y)
624 (let (a) (b) ((const 2))
625 (lexical a b))))
8a4ca0ea 626 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
627 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
628 (lexical #t #f ref 0) (branch br-if-not ,l1)
629 (lexical #t #f ref 0) (call return 1)
5af166bd 630 (label ,l2)
66d3e9a3
AW
631 (const 2) (bind (a #f 0)) (lexical #t #f set 0)
632 (lexical #t #f ref 0) (call return 1)
5af166bd
AW
633 (unbind)
634 (unbind))
635 (eq? l1 l2))
636
aaae0d5a 637 ;; second bound var is unreferenced
11671bba 638 (assert-tree-il->glil without-partial-evaluation
5af166bd
AW
639 (let (x) (y) ((const 1))
640 (if (lexical x y)
641 (lexical x y)
642 (let (a) (b) ((const 2))
643 (lexical x y))))
8a4ca0ea 644 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
645 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
646 (lexical #t #f ref 0) (branch br-if-not ,l1)
647 (lexical #t #f ref 0) (call return 1)
5af166bd 648 (label ,l2)
66d3e9a3 649 (lexical #t #f ref 0) (call return 1)
5af166bd
AW
650 (unbind))
651 (eq? l1 l2)))
0f423f20
AW
652
653(with-test-prefix "apply"
654 (assert-tree-il->glil
655 (apply (primitive @apply) (toplevel foo) (toplevel bar))
a5bbb22e 656 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (toplevel ref bar) (call tail-apply 2)))
8a4ca0ea 657 (assert-tree-il->glil
0f423f20 658 (begin (apply (primitive @apply) (toplevel foo) (toplevel bar)) (void))
8a4ca0ea 659 (program () (std-prelude 0 0 #f) (label _)
b7946e9e 660 (call new-frame 0) (toplevel ref apply) (toplevel ref foo) (toplevel ref bar) (mv-call 2 ,l1)
05c51bcf 661 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind 0 #f)
0f423f20
AW
662 (label ,l4)
663 (void) (call return 1))
664 (and (eq? l1 l3) (eq? l2 l4)))
665 (assert-tree-il->glil
666 (apply (toplevel foo) (apply (toplevel @apply) (toplevel bar) (toplevel baz)))
8a4ca0ea 667 (program () (std-prelude 0 0 #f) (label _)
0f423f20 668 (toplevel ref foo)
b7946e9e 669 (call new-frame 0) (toplevel ref bar) (toplevel ref baz) (call apply 2)
a5bbb22e 670 (call tail-call 1))))
0f423f20
AW
671
672(with-test-prefix "call/cc"
673 (assert-tree-il->glil
674 (apply (primitive @call-with-current-continuation) (toplevel foo))
a5bbb22e 675 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (call tail-call/cc 1)))
8a4ca0ea 676 (assert-tree-il->glil
0f423f20 677 (begin (apply (primitive @call-with-current-continuation) (toplevel foo)) (void))
8a4ca0ea 678 (program () (std-prelude 0 0 #f) (label _)
b7946e9e 679 (call new-frame 0) (toplevel ref call-with-current-continuation) (toplevel ref foo) (mv-call 1 ,l1)
05c51bcf 680 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind 0 #f)
0f423f20
AW
681 (label ,l4)
682 (void) (call return 1))
683 (and (eq? l1 l3) (eq? l2 l4)))
684 (assert-tree-il->glil
685 (apply (toplevel foo)
686 (apply (toplevel @call-with-current-continuation) (toplevel bar)))
8a4ca0ea 687 (program () (std-prelude 0 0 #f) (label _)
0f423f20
AW
688 (toplevel ref foo)
689 (toplevel ref bar) (call call/cc 1)
a5bbb22e 690 (call tail-call 1))))
0f423f20 691
f4aa0f10 692\f
aa9c1985
AW
693(with-test-prefix "labels allocation"
694 (pass-if "http://debbugs.gnu.org/9769"
695 ((compile '(lambda ()
696 (let ((fail (lambda () #f)))
697 (let ((test (lambda () (fail))))
698 (test))
699 #t))
700 ;; Prevent inlining. We're testing analyze.scm's
701 ;; labels allocator here, and inlining it will
702 ;; reduce the entire thing to #t.
703 #:opts '(#:partial-eval? #f)))))
704
705\f
d0ecf8eb
AW
706(define (sum . args)
707 (apply + args))
708
709(with-test-prefix "many args"
710 (pass-if "call with > 256 args"
711 (equal? (compile `(1+ (sum ,@(iota 1000)))
712 #:env (current-module))
713 (1+ (apply sum (iota 1000)))))
714
715 (pass-if "tail call with > 256 args"
716 (equal? (compile `(sum ,@(iota 1000))
717 #:env (current-module))
718 (apply sum (iota 1000)))))
719
720
721\f
f4aa0f10
LC
722(with-test-prefix "tree-il-fold"
723
724 (pass-if "empty tree"
725 (let ((leaf? #f) (up? #f) (down? #f) (mark (list 'mark)))
726 (and (eq? mark
727 (tree-il-fold (lambda (x y) (set! leaf? #t) y)
728 (lambda (x y) (set! down? #t) y)
729 (lambda (x y) (set! up? #t) y)
730 mark
731 '()))
732 (not leaf?)
733 (not up?)
734 (not down?))))
735
736 (pass-if "lambda and application"
737 (let* ((leaves '()) (ups '()) (downs '())
738 (result (tree-il-fold (lambda (x y)
739 (set! leaves (cons x leaves))
740 (1+ y))
741 (lambda (x y)
742 (set! downs (cons x downs))
743 (1+ y))
744 (lambda (x y)
745 (set! ups (cons x ups))
746 (1+ y))
747 0
748 (parse-tree-il
8a4ca0ea
AW
749 '(lambda ()
750 (lambda-case
1e2a8edb 751 (((x y) #f #f #f () (x1 y1))
8a4ca0ea
AW
752 (apply (toplevel +)
753 (lexical x x1)
754 (lexical y y1)))
755 #f))))))
f4aa0f10
LC
756 (and (equal? (map strip-source leaves)
757 (list (make-lexical-ref #f 'y 'y1)
758 (make-lexical-ref #f 'x 'x1)
759 (make-toplevel-ref #f '+)))
8a4ca0ea 760 (= (length downs) 3)
f4aa0f10
LC
761 (equal? (reverse (map strip-source ups))
762 (map strip-source downs))))))
4b856371
LC
763
764\f
765;;;
766;;; Warnings.
767;;;
768
769;; Make sure we get English messages.
0ce22459
MW
770(when (defined? 'setlocale)
771 (setlocale LC_ALL "C"))
4b856371
LC
772
773(define (call-with-warnings thunk)
774 (let ((port (open-output-string)))
a4060f67
LC
775 (with-fluids ((*current-warning-port* port)
776 (*current-warning-prefix* ""))
777 (thunk))
4b856371
LC
778 (let ((warnings (get-output-string port)))
779 (string-tokenize warnings
780 (char-set-complement (char-set #\newline))))))
781
782(define %opts-w-unused
783 '(#:warnings (unused-variable)))
784
bcae9a98
LC
785(define %opts-w-unused-toplevel
786 '(#:warnings (unused-toplevel)))
787
f67ddf9d
LC
788(define %opts-w-unbound
789 '(#:warnings (unbound-variable)))
4b856371 790
ae03cf1f
LC
791(define %opts-w-arity
792 '(#:warnings (arity-mismatch)))
793
75365375
LC
794(define %opts-w-format
795 '(#:warnings (format)))
796
5cd10307
LC
797(define %opts-w-duplicate-case-datum
798 '(#:warnings (duplicate-case-datum)))
799
800(define %opts-w-bad-case-datum
801 '(#:warnings (bad-case-datum)))
802
ae03cf1f 803
4b856371
LC
804(with-test-prefix "warnings"
805
806 (pass-if "unknown warning type"
807 (let ((w (call-with-warnings
808 (lambda ()
809 (compile #t #:opts '(#:warnings (does-not-exist)))))))
810 (and (= (length w) 1)
811 (number? (string-contains (car w) "unknown warning")))))
812
813 (with-test-prefix "unused-variable"
814
815 (pass-if "quiet"
816 (null? (call-with-warnings
817 (lambda ()
818 (compile '(lambda (x y) (+ x y))
819 #:opts %opts-w-unused)))))
820
821 (pass-if "let/unused"
822 (let ((w (call-with-warnings
823 (lambda ()
824 (compile '(lambda (x)
825 (let ((y (+ x 2)))
826 x))
827 #:opts %opts-w-unused)))))
828 (and (= (length w) 1)
829 (number? (string-contains (car w) "unused variable `y'")))))
830
831 (pass-if "shadowed variable"
832 (let ((w (call-with-warnings
833 (lambda ()
834 (compile '(lambda (x)
835 (let ((y x))
836 (let ((y (+ x 2)))
837 (+ x y))))
838 #:opts %opts-w-unused)))))
839 (and (= (length w) 1)
840 (number? (string-contains (car w) "unused variable `y'")))))
841
842 (pass-if "letrec"
843 (null? (call-with-warnings
844 (lambda ()
845 (compile '(lambda ()
846 (letrec ((x (lambda () (y)))
847 (y (lambda () (x))))
848 y))
849 #:opts %opts-w-unused)))))
850
851 (pass-if "unused argument"
852 ;; Unused arguments should not be reported.
853 (null? (call-with-warnings
854 (lambda ()
855 (compile '(lambda (x y z) #t)
3a1a883b
LC
856 #:opts %opts-w-unused)))))
857
858 (pass-if "special variable names"
859 (null? (call-with-warnings
860 (lambda ()
861 (compile '(lambda ()
862 (let ((_ 'underscore)
863 (#{gensym name}# 'ignore-me))
864 #t))
865 #:to 'assembly
f67ddf9d
LC
866 #:opts %opts-w-unused))))))
867
bcae9a98
LC
868 (with-test-prefix "unused-toplevel"
869
870 (pass-if "used after definition"
871 (null? (call-with-warnings
872 (lambda ()
873 (let ((in (open-input-string
874 "(define foo 2) foo")))
875 (read-and-compile in
876 #:to 'assembly
877 #:opts %opts-w-unused-toplevel))))))
878
879 (pass-if "used before definition"
880 (null? (call-with-warnings
881 (lambda ()
882 (let ((in (open-input-string
883 "(define (bar) foo) (define foo 2) (bar)")))
884 (read-and-compile in
885 #:to 'assembly
886 #:opts %opts-w-unused-toplevel))))))
887
888 (pass-if "unused but public"
889 (let ((in (open-input-string
890 "(define-module (test-suite tree-il x) #:export (bar))
891 (define (bar) #t)")))
892 (null? (call-with-warnings
893 (lambda ()
894 (read-and-compile in
895 #:to 'assembly
896 #:opts %opts-w-unused-toplevel))))))
897
898 (pass-if "unused but public (more)"
899 (let ((in (open-input-string
900 "(define-module (test-suite tree-il x) #:export (bar))
901 (define (bar) (baz))
902 (define (baz) (foo))
903 (define (foo) #t)")))
904 (null? (call-with-warnings
905 (lambda ()
906 (read-and-compile in
907 #:to 'assembly
908 #:opts %opts-w-unused-toplevel))))))
909
910 (pass-if "unused but define-public"
bcae9a98
LC
911 (null? (call-with-warnings
912 (lambda ()
913 (compile '(define-public foo 2)
914 #:to 'assembly
915 #:opts %opts-w-unused-toplevel)))))
916
917 (pass-if "used by macro"
918 ;; FIXME: See comment about macros at `unused-toplevel-analysis'.
919 (throw 'unresolved)
920
921 (null? (call-with-warnings
922 (lambda ()
923 (let ((in (open-input-string
924 "(define (bar) 'foo)
925 (define-syntax baz
926 (syntax-rules () ((_) (bar))))")))
927 (read-and-compile in
928 #:to 'assembly
929 #:opts %opts-w-unused-toplevel))))))
930
931 (pass-if "unused"
932 (let ((w (call-with-warnings
933 (lambda ()
934 (compile '(define foo 2)
935 #:to 'assembly
936 #:opts %opts-w-unused-toplevel)))))
937 (and (= (length w) 1)
938 (number? (string-contains (car w)
939 (format #f "top-level variable `~A'"
940 'foo))))))
941
942 (pass-if "unused recursive"
943 (let ((w (call-with-warnings
944 (lambda ()
945 (compile '(define (foo) (foo))
946 #:to 'assembly
947 #:opts %opts-w-unused-toplevel)))))
948 (and (= (length w) 1)
949 (number? (string-contains (car w)
950 (format #f "top-level variable `~A'"
951 'foo))))))
952
953 (pass-if "unused mutually recursive"
954 (let* ((in (open-input-string
955 "(define (foo) (bar)) (define (bar) (foo))"))
956 (w (call-with-warnings
957 (lambda ()
958 (read-and-compile in
959 #:to 'assembly
960 #:opts %opts-w-unused-toplevel)))))
961 (and (= (length w) 2)
962 (number? (string-contains (car w)
963 (format #f "top-level variable `~A'"
964 'foo)))
965 (number? (string-contains (cadr w)
966 (format #f "top-level variable `~A'"
3a1a883b
LC
967 'bar))))))
968
969 (pass-if "special variable names"
970 (null? (call-with-warnings
971 (lambda ()
972 (compile '(define #{gensym name}# 'ignore-me)
973 #:to 'assembly
974 #:opts %opts-w-unused-toplevel))))))
bcae9a98 975
f67ddf9d
LC
976 (with-test-prefix "unbound variable"
977
978 (pass-if "quiet"
979 (null? (call-with-warnings
980 (lambda ()
981 (compile '+ #:opts %opts-w-unbound)))))
982
983 (pass-if "ref"
984 (let* ((v (gensym))
985 (w (call-with-warnings
986 (lambda ()
987 (compile v
988 #:to 'assembly
989 #:opts %opts-w-unbound)))))
990 (and (= (length w) 1)
991 (number? (string-contains (car w)
992 (format #f "unbound variable `~A'"
993 v))))))
994
995 (pass-if "set!"
996 (let* ((v (gensym))
997 (w (call-with-warnings
998 (lambda ()
999 (compile `(set! ,v 7)
1000 #:to 'assembly
1001 #:opts %opts-w-unbound)))))
1002 (and (= (length w) 1)
1003 (number? (string-contains (car w)
1004 (format #f "unbound variable `~A'"
1005 v))))))
1006
1007 (pass-if "module-local top-level is visible"
1008 (let ((m (make-module))
1009 (v (gensym)))
1010 (beautify-user-module! m)
1011 (compile `(define ,v 123)
1012 #:env m #:opts %opts-w-unbound)
1013 (null? (call-with-warnings
1014 (lambda ()
1015 (compile v
1016 #:env m
1017 #:to 'assembly
1018 #:opts %opts-w-unbound))))))
1019
1020 (pass-if "module-local top-level is visible after"
1021 (let ((m (make-module))
1022 (v (gensym)))
1023 (beautify-user-module! m)
1024 (null? (call-with-warnings
1025 (lambda ()
1026 (let ((in (open-input-string
1027 "(define (f)
1028 (set! chbouib 3))
1029 (define chbouib 5)")))
b6d2306d
LC
1030 (read-and-compile in
1031 #:env m
1032 #:opts %opts-w-unbound)))))))
1033
bd36e901
LC
1034 (pass-if "optional arguments are visible"
1035 (null? (call-with-warnings
1036 (lambda ()
1037 (compile '(lambda* (x #:optional y z) (list x y z))
1038 #:opts %opts-w-unbound
1039 #:to 'assembly)))))
1040
1041 (pass-if "keyword arguments are visible"
1042 (null? (call-with-warnings
1043 (lambda ()
1044 (compile '(lambda* (x #:key y z) (list x y z))
1045 #:opts %opts-w-unbound
1046 #:to 'assembly)))))
1047
b6d2306d
LC
1048 (pass-if "GOOPS definitions are visible"
1049 (let ((m (make-module))
1050 (v (gensym)))
1051 (beautify-user-module! m)
1052 (module-use! m (resolve-interface '(oop goops)))
1053 (null? (call-with-warnings
1054 (lambda ()
1055 (let ((in (open-input-string
1056 "(define-class <foo> ()
1057 (bar #:getter foo-bar))
1058 (define z (foo-bar (make <foo>)))")))
f67ddf9d
LC
1059 (read-and-compile in
1060 #:env m
ae03cf1f
LC
1061 #:opts %opts-w-unbound))))))))
1062
1063 (with-test-prefix "arity mismatch"
1064
1065 (pass-if "quiet"
1066 (null? (call-with-warnings
1067 (lambda ()
1068 (compile '(cons 'a 'b) #:opts %opts-w-arity)))))
1069
1070 (pass-if "direct application"
1071 (let ((w (call-with-warnings
1072 (lambda ()
1073 (compile '((lambda (x y) (or x y)) 1 2 3 4 5)
1074 #:opts %opts-w-arity
1075 #:to 'assembly)))))
1076 (and (= (length w) 1)
1077 (number? (string-contains (car w)
1078 "wrong number of arguments to")))))
1079 (pass-if "local"
1080 (let ((w (call-with-warnings
1081 (lambda ()
1082 (compile '(let ((f (lambda (x y) (+ x y))))
1083 (f 2))
1084 #:opts %opts-w-arity
1085 #:to 'assembly)))))
1086 (and (= (length w) 1)
1087 (number? (string-contains (car w)
1088 "wrong number of arguments to")))))
1089
1090 (pass-if "global"
1091 (let ((w (call-with-warnings
1092 (lambda ()
1093 (compile '(cons 1 2 3 4)
1094 #:opts %opts-w-arity
1095 #:to 'assembly)))))
1096 (and (= (length w) 1)
1097 (number? (string-contains (car w)
1098 "wrong number of arguments to")))))
1099
1100 (pass-if "alias to global"
1101 (let ((w (call-with-warnings
1102 (lambda ()
1103 (compile '(let ((f cons)) (f 1 2 3 4))
1104 #:opts %opts-w-arity
1105 #:to 'assembly)))))
1106 (and (= (length w) 1)
1107 (number? (string-contains (car w)
1108 "wrong number of arguments to")))))
1109
1110 (pass-if "alias to lexical to global"
1111 (let ((w (call-with-warnings
1112 (lambda ()
1113 (compile '(let ((f number?))
1114 (let ((g f))
1115 (f 1 2 3 4)))
1116 #:opts %opts-w-arity
1117 #:to 'assembly)))))
1118 (and (= (length w) 1)
1119 (number? (string-contains (car w)
1120 "wrong number of arguments to")))))
1121
1122 (pass-if "alias to lexical"
1123 (let ((w (call-with-warnings
1124 (lambda ()
1125 (compile '(let ((f (lambda (x y z) (+ x y z))))
1126 (let ((g f))
1127 (g 1)))
1128 #:opts %opts-w-arity
1129 #:to 'assembly)))))
1130 (and (= (length w) 1)
1131 (number? (string-contains (car w)
1132 "wrong number of arguments to")))))
1133
1134 (pass-if "letrec"
1135 (let ((w (call-with-warnings
1136 (lambda ()
1137 (compile '(letrec ((odd? (lambda (x) (even? (1- x))))
1138 (even? (lambda (x)
1139 (or (= 0 x)
1140 (odd?)))))
1141 (odd? 1))
1142 #:opts %opts-w-arity
1143 #:to 'assembly)))))
1144 (and (= (length w) 1)
1145 (number? (string-contains (car w)
1146 "wrong number of arguments to")))))
1147
99480e11
LC
1148 (pass-if "case-lambda"
1149 (null? (call-with-warnings
1150 (lambda ()
1151 (compile '(let ((f (case-lambda
1152 ((x) 1)
1153 ((x y) 2)
1154 ((x y z) 3))))
1155 (list (f 1)
1156 (f 1 2)
1157 (f 1 2 3)))
1158 #:opts %opts-w-arity
1159 #:to 'assembly)))))
1160
1161 (pass-if "case-lambda with wrong number of arguments"
1162 (let ((w (call-with-warnings
1163 (lambda ()
1164 (compile '(let ((f (case-lambda
1165 ((x) 1)
1166 ((x y) 2))))
1167 (f 1 2 3))
1168 #:opts %opts-w-arity
1169 #:to 'assembly)))))
1170 (and (= (length w) 1)
1171 (number? (string-contains (car w)
1172 "wrong number of arguments to")))))
1173
1174 (pass-if "case-lambda*"
1175 (null? (call-with-warnings
1176 (lambda ()
1177 (compile '(let ((f (case-lambda*
1178 ((x #:optional y) 1)
1179 ((x #:key y) 2)
1180 ((x y #:key z) 3))))
1181 (list (f 1)
1182 (f 1 2)
1183 (f #:y 2)
1184 (f 1 2 #:z 3)))
1185 #:opts %opts-w-arity
1186 #:to 'assembly)))))
1187
1188 (pass-if "case-lambda* with wrong arguments"
1189 (let ((w (call-with-warnings
1190 (lambda ()
1191 (compile '(let ((f (case-lambda*
1192 ((x #:optional y) 1)
1193 ((x #:key y) 2)
1194 ((x y #:key z) 3))))
1195 (list (f)
1196 (f 1 #:z 3)))
1197 #:opts %opts-w-arity
1198 #:to 'assembly)))))
1199 (and (= (length w) 2)
1200 (null? (filter (lambda (w)
1201 (not
1202 (number?
1203 (string-contains
1204 w "wrong number of arguments to"))))
1205 w)))))
1206
2c5f0bdb
LC
1207 (pass-if "top-level applicable struct"
1208 (null? (call-with-warnings
1209 (lambda ()
1210 (compile '(let ((p current-warning-port))
1211 (p (+ (p) 1))
1212 (p))
1213 #:opts %opts-w-arity
1214 #:to 'assembly)))))
1215
1216 (pass-if "top-level applicable struct with wrong arguments"
1217 (let ((w (call-with-warnings
1218 (lambda ()
1219 (compile '(let ((p current-warning-port))
1220 (p 1 2 3))
1221 #:opts %opts-w-arity
1222 #:to 'assembly)))))
1223 (and (= (length w) 1)
1224 (number? (string-contains (car w)
1225 "wrong number of arguments to")))))
1226
ae03cf1f
LC
1227 (pass-if "local toplevel-defines"
1228 (let ((w (call-with-warnings
1229 (lambda ()
1230 (let ((in (open-input-string "
1231 (define (g x) (f x))
1232 (define (f) 1)")))
1233 (read-and-compile in
1234 #:opts %opts-w-arity
1235 #:to 'assembly))))))
1236 (and (= (length w) 1)
1237 (number? (string-contains (car w)
1238 "wrong number of arguments to")))))
1239
1240 (pass-if "global toplevel alias"
1241 (let ((w (call-with-warnings
1242 (lambda ()
1243 (let ((in (open-input-string "
1244 (define f cons)
1245 (define (g) (f))")))
1246 (read-and-compile in
1247 #:opts %opts-w-arity
1248 #:to 'assembly))))))
1249 (and (= (length w) 1)
1250 (number? (string-contains (car w)
1251 "wrong number of arguments to")))))
1252
1253 (pass-if "local toplevel overrides global"
1254 (null? (call-with-warnings
1255 (lambda ()
1256 (let ((in (open-input-string "
1257 (define (cons) 0)
1258 (define (foo x) (cons))")))
1259 (read-and-compile in
1260 #:opts %opts-w-arity
af5ed549
LC
1261 #:to 'assembly))))))
1262
1263 (pass-if "keyword not passed and quiet"
1264 (null? (call-with-warnings
1265 (lambda ()
1266 (compile '(let ((f (lambda* (x #:key y) y)))
1267 (f 2))
1268 #:opts %opts-w-arity
1269 #:to 'assembly)))))
1270
1271 (pass-if "keyword passed and quiet"
1272 (null? (call-with-warnings
1273 (lambda ()
1274 (compile '(let ((f (lambda* (x #:key y) y)))
1275 (f 2 #:y 3))
1276 #:opts %opts-w-arity
1277 #:to 'assembly)))))
1278
1279 (pass-if "keyword passed to global and quiet"
1280 (null? (call-with-warnings
1281 (lambda ()
1282 (let ((in (open-input-string "
1283 (use-modules (system base compile))
1284 (compile '(+ 2 3) #:env (current-module))")))
1285 (read-and-compile in
1286 #:opts %opts-w-arity
1287 #:to 'assembly))))))
1288
1289 (pass-if "extra keyword"
1290 (let ((w (call-with-warnings
1291 (lambda ()
1292 (compile '(let ((f (lambda* (x #:key y) y)))
1293 (f 2 #:Z 3))
1294 #:opts %opts-w-arity
1295 #:to 'assembly)))))
1296 (and (= (length w) 1)
1297 (number? (string-contains (car w)
1298 "wrong number of arguments to")))))
1299
1300 (pass-if "extra keywords allowed"
1301 (null? (call-with-warnings
1302 (lambda ()
1303 (compile '(let ((f (lambda* (x #:key y #:allow-other-keys)
1304 y)))
1305 (f 2 #:Z 3))
1306 #:opts %opts-w-arity
75365375
LC
1307 #:to 'assembly))))))
1308
1309 (with-test-prefix "format"
1310
1311 (pass-if "quiet (no args)"
1312 (null? (call-with-warnings
1313 (lambda ()
1314 (compile '(format #t "hey!")
1315 #:opts %opts-w-format
1316 #:to 'assembly)))))
1317
1318 (pass-if "quiet (1 arg)"
1319 (null? (call-with-warnings
1320 (lambda ()
1321 (compile '(format #t "hey ~A!" "you")
1322 #:opts %opts-w-format
1323 #:to 'assembly)))))
1324
1325 (pass-if "quiet (2 args)"
1326 (null? (call-with-warnings
1327 (lambda ()
1328 (compile '(format #t "~A ~A!" "hello" "world")
1329 #:opts %opts-w-format
1330 #:to 'assembly)))))
1331
60f01304
LC
1332 (pass-if "wrong port arg"
1333 (let ((w (call-with-warnings
1334 (lambda ()
1335 (compile '(format 10 "foo")
1336 #:opts %opts-w-format
1337 #:to 'assembly)))))
1338 (and (= (length w) 1)
1339 (number? (string-contains (car w)
1340 "wrong port argument")))))
1341
1342 (pass-if "non-literal format string"
1343 (let ((w (call-with-warnings
1344 (lambda ()
1345 (compile '(format #f fmt)
1346 #:opts %opts-w-format
1347 #:to 'assembly)))))
1348 (and (= (length w) 1)
1349 (number? (string-contains (car w)
1350 "non-literal format string")))))
1351
022ae742 1352 (pass-if "non-literal format string using gettext"
afc98031
LC
1353 (null? (call-with-warnings
1354 (lambda ()
1355 (compile '(format #t (gettext "~A ~A!") "hello" "world")
1356 #:opts %opts-w-format
1357 #:to 'assembly)))))
1358
1359 (pass-if "non-literal format string using gettext as _"
022ae742
LC
1360 (null? (call-with-warnings
1361 (lambda ()
1362 (compile '(format #t (_ "~A ~A!") "hello" "world")
1363 #:opts %opts-w-format
4c984747
LC
1364 #:to 'assembly)))))
1365
8a74ffe8
LC
1366 (pass-if "non-literal format string using gettext as top-level _"
1367 (null? (call-with-warnings
1368 (lambda ()
1369 (compile '(begin
1370 (define (_ s) (gettext s "my-domain"))
1371 (format #t (_ "~A ~A!") "hello" "world"))
1372 #:opts %opts-w-format
1373 #:to 'assembly)))))
1374
4c984747
LC
1375 (pass-if "non-literal format string using gettext as module-ref _"
1376 (null? (call-with-warnings
1377 (lambda ()
1378 (compile '(format #t ((@@ (foo) _) "~A ~A!") "hello" "world")
1379 #:opts %opts-w-format
1380 #:to 'assembly)))))
1381
1382 (pass-if "non-literal format string using gettext as lexical _"
1383 (null? (call-with-warnings
1384 (lambda ()
1385 (compile '(let ((_ (lambda (s)
1386 (gettext s "my-domain"))))
1387 (format #t (_ "~A ~A!") "hello" "world"))
1388 #:opts %opts-w-format
022ae742
LC
1389 #:to 'assembly)))))
1390
98385ed2
LC
1391 (pass-if "non-literal format string using ngettext"
1392 (null? (call-with-warnings
1393 (lambda ()
1394 (compile '(format #t
1395 (ngettext "~a thing" "~a things" n "dom") n)
1396 #:opts %opts-w-format
1397 #:to 'assembly)))))
1398
1399 (pass-if "non-literal format string using ngettext as N_"
1400 (null? (call-with-warnings
1401 (lambda ()
1402 (compile '(format #t (N_ "~a thing" "~a things" n) n)
1403 #:opts %opts-w-format
1404 #:to 'assembly)))))
1405
dab48cc5
AW
1406 (pass-if "non-literal format string with (define _ gettext)"
1407 (null? (call-with-warnings
1408 (lambda ()
1409 (compile '(begin
1410 (define _ gettext)
1411 (define (foo)
1412 (format #t (_ "~A ~A!") "hello" "world")))
1413 #:opts %opts-w-format
1414 #:to 'assembly)))))
d3160473 1415
60f01304
LC
1416 (pass-if "wrong format string"
1417 (let ((w (call-with-warnings
1418 (lambda ()
1419 (compile '(format #f 'not-a-string)
1420 #:opts %opts-w-format
1421 #:to 'assembly)))))
1422 (and (= (length w) 1)
1423 (number? (string-contains (car w)
1424 "wrong format string")))))
1425
1426 (pass-if "wrong number of args"
1427 (let ((w (call-with-warnings
1428 (lambda ()
1429 (compile '(format "shbweeb")
1430 #:opts %opts-w-format
1431 #:to 'assembly)))))
1432 (and (= (length w) 1)
1433 (number? (string-contains (car w)
1434 "wrong number of arguments")))))
1435
90baf8cd 1436 (pass-if "~%, ~~, ~&, ~t, ~_, ~!, ~|, ~/, ~q and ~\\n"
75365375
LC
1437 (null? (call-with-warnings
1438 (lambda ()
60273407 1439 (compile '((@ (ice-9 format) format) some-port
90baf8cd 1440 "~&~3_~~ ~\n~12they~% ~!~|~/~q")
75365375
LC
1441 #:opts %opts-w-format
1442 #:to 'assembly)))))
1443
1444 (pass-if "one missing argument"
1445 (let ((w (call-with-warnings
1446 (lambda ()
1447 (compile '(format some-port "foo ~A~%")
1448 #:opts %opts-w-format
1449 #:to 'assembly)))))
1450 (and (= (length w) 1)
1451 (number? (string-contains (car w)
1452 "expected 1, got 0")))))
1453
022ae742
LC
1454 (pass-if "one missing argument, gettext"
1455 (let ((w (call-with-warnings
1456 (lambda ()
afc98031 1457 (compile '(format some-port (gettext "foo ~A~%"))
022ae742
LC
1458 #:opts %opts-w-format
1459 #:to 'assembly)))))
1460 (and (= (length w) 1)
1461 (number? (string-contains (car w)
1462 "expected 1, got 0")))))
1463
75365375
LC
1464 (pass-if "two missing arguments"
1465 (let ((w (call-with-warnings
1466 (lambda ()
60273407
LC
1467 (compile '((@ (ice-9 format) format) #f
1468 "foo ~10,2f and bar ~S~%")
75365375
LC
1469 #:opts %opts-w-format
1470 #:to 'assembly)))))
1471 (and (= (length w) 1)
1472 (number? (string-contains (car w)
1473 "expected 2, got 0")))))
1474
1475 (pass-if "one given, one missing argument"
1476 (let ((w (call-with-warnings
1477 (lambda ()
1478 (compile '(format #t "foo ~A and ~S~%" hey)
1479 #:opts %opts-w-format
1480 #:to 'assembly)))))
1481 (and (= (length w) 1)
1482 (number? (string-contains (car w)
1483 "expected 2, got 1")))))
1484
1485 (pass-if "too many arguments"
1486 (let ((w (call-with-warnings
1487 (lambda ()
1488 (compile '(format #t "foo ~A~%" 1 2)
1489 #:opts %opts-w-format
1490 #:to 'assembly)))))
1491 (and (= (length w) 1)
1492 (number? (string-contains (car w)
1493 "expected 1, got 2")))))
1494
b4af80a4
LC
1495 (pass-if "~h"
1496 (null? (call-with-warnings
1497 (lambda ()
1498 (compile '((@ (ice-9 format) format) #t
1499 "foo ~h ~a~%" 123.4 'bar)
1500 #:opts %opts-w-format
1501 #:to 'assembly)))))
1502
1503 (pass-if "~:h with locale object"
1504 (null? (call-with-warnings
1505 (lambda ()
1506 (compile '((@ (ice-9 format) format) #t
1507 "foo ~:h~%" 123.4 %global-locale)
1508 #:opts %opts-w-format
1509 #:to 'assembly)))))
1510
1511 (pass-if "~:h without locale object"
1512 (let ((w (call-with-warnings
1513 (lambda ()
1514 (compile '((@ (ice-9 format) format) #t "foo ~,2:h" 123.4)
1515 #:opts %opts-w-format
1516 #:to 'assembly)))))
1517 (and (= (length w) 1)
1518 (number? (string-contains (car w)
1519 "expected 2, got 1")))))
1520
e0697241
LC
1521 (with-test-prefix "conditionals"
1522 (pass-if "literals"
1523 (null? (call-with-warnings
1524 (lambda ()
60273407 1525 (compile '((@ (ice-9 format) format) #f "~A ~[foo~;bar~;baz~;~] ~10,2f"
e0697241
LC
1526 'a 1 3.14)
1527 #:opts %opts-w-format
1528 #:to 'assembly)))))
1529
1530 (pass-if "literals with selector"
1531 (let ((w (call-with-warnings
1532 (lambda ()
60273407 1533 (compile '((@ (ice-9 format) format) #f "~2[foo~;bar~;baz~;~] ~A"
e0697241
LC
1534 1 'dont-ignore-me)
1535 #:opts %opts-w-format
1536 #:to 'assembly)))))
1537 (and (= (length w) 1)
1538 (number? (string-contains (car w)
1539 "expected 1, got 2")))))
1540
1541 (pass-if "escapes (exact count)"
1542 (let ((w (call-with-warnings
1543 (lambda ()
60273407 1544 (compile '((@ (ice-9 format) format) #f "~[~a~;~a~]")
e0697241
LC
1545 #:opts %opts-w-format
1546 #:to 'assembly)))))
1547 (and (= (length w) 1)
1548 (number? (string-contains (car w)
1549 "expected 2, got 0")))))
1550
1551 (pass-if "escapes with selector"
1552 (let ((w (call-with-warnings
1553 (lambda ()
60273407 1554 (compile '((@ (ice-9 format) format) #f "~1[chbouib~;~a~]")
e0697241
LC
1555 #:opts %opts-w-format
1556 #:to 'assembly)))))
1557 (and (= (length w) 1)
1558 (number? (string-contains (car w)
1559 "expected 1, got 0")))))
1560
1561 (pass-if "escapes, range"
1562 (let ((w (call-with-warnings
1563 (lambda ()
60273407 1564 (compile '((@ (ice-9 format) format) #f "~[chbouib~;~a~;~2*~a~]")
e0697241
LC
1565 #:opts %opts-w-format
1566 #:to 'assembly)))))
1567 (and (= (length w) 1)
1568 (number? (string-contains (car w)
1569 "expected 1 to 4, got 0")))))
1570
1571 (pass-if "@"
1572 (let ((w (call-with-warnings
1573 (lambda ()
60273407 1574 (compile '((@ (ice-9 format) format) #f "~@[temperature=~d~]")
e0697241
LC
1575 #:opts %opts-w-format
1576 #:to 'assembly)))))
1577 (and (= (length w) 1)
1578 (number? (string-contains (car w)
1579 "expected 1, got 0")))))
1580
1581 (pass-if "nested"
1582 (let ((w (call-with-warnings
1583 (lambda ()
60273407 1584 (compile '((@ (ice-9 format) format) #f "~:[~[hey~;~a~;~va~]~;~3*~]")
e0697241
LC
1585 #:opts %opts-w-format
1586 #:to 'assembly)))))
1587 (and (= (length w) 1)
1588 (number? (string-contains (car w)
1589 "expected 2 to 4, got 0")))))
1590
8e6c15a6
LC
1591 (pass-if "unterminated"
1592 (let ((w (call-with-warnings
1593 (lambda ()
60273407 1594 (compile '((@ (ice-9 format) format) #f "~[unterminated")
8e6c15a6
LC
1595 #:opts %opts-w-format
1596 #:to 'assembly)))))
1597 (and (= (length w) 1)
1598 (number? (string-contains (car w)
1599 "unterminated conditional")))))
1600
1601 (pass-if "unexpected ~;"
1602 (let ((w (call-with-warnings
1603 (lambda ()
60273407 1604 (compile '((@ (ice-9 format) format) #f "foo~;bar")
8e6c15a6
LC
1605 #:opts %opts-w-format
1606 #:to 'assembly)))))
1607 (and (= (length w) 1)
1608 (number? (string-contains (car w)
1609 "unexpected")))))
1610
1611 (pass-if "unexpected ~]"
1612 (let ((w (call-with-warnings
1613 (lambda ()
60273407 1614 (compile '((@ (ice-9 format) format) #f "foo~]")
8e6c15a6
LC
1615 #:opts %opts-w-format
1616 #:to 'assembly)))))
1617 (and (= (length w) 1)
1618 (number? (string-contains (car w)
1619 "unexpected"))))))
e0697241
LC
1620
1621 (pass-if "~{...~}"
1622 (null? (call-with-warnings
1623 (lambda ()
60273407 1624 (compile '((@ (ice-9 format) format) #f "~A ~{~S~} ~A"
e0697241
LC
1625 'hello '("ladies" "and")
1626 'gentlemen)
1627 #:opts %opts-w-format
1628 #:to 'assembly)))))
1629
1630 (pass-if "~{...~}, too many args"
1631 (let ((w (call-with-warnings
1632 (lambda ()
60273407 1633 (compile '((@ (ice-9 format) format) #f "~{~S~}" 1 2 3)
e0697241
LC
1634 #:opts %opts-w-format
1635 #:to 'assembly)))))
1636 (and (= (length w) 1)
1637 (number? (string-contains (car w)
1638 "expected 1, got 3")))))
1639
1640 (pass-if "~@{...~}"
1641 (null? (call-with-warnings
1642 (lambda ()
60273407 1643 (compile '((@ (ice-9 format) format) #f "~@{~S~}" 1 2 3)
e0697241
LC
1644 #:opts %opts-w-format
1645 #:to 'assembly)))))
1646
1647 (pass-if "~@{...~}, too few args"
1648 (let ((w (call-with-warnings
1649 (lambda ()
60273407 1650 (compile '((@ (ice-9 format) format) #f "~A ~@{~S~}")
e0697241
LC
1651 #:opts %opts-w-format
1652 #:to 'assembly)))))
1653 (and (= (length w) 1)
1654 (number? (string-contains (car w)
1655 "expected at least 1, got 0")))))
1656
8e6c15a6
LC
1657 (pass-if "unterminated ~{...~}"
1658 (let ((w (call-with-warnings
1659 (lambda ()
60273407 1660 (compile '((@ (ice-9 format) format) #f "~{")
8e6c15a6
LC
1661 #:opts %opts-w-format
1662 #:to 'assembly)))))
1663 (and (= (length w) 1)
1664 (number? (string-contains (car w)
1665 "unterminated")))))
1666
e0697241
LC
1667 (pass-if "~(...~)"
1668 (null? (call-with-warnings
1669 (lambda ()
60273407 1670 (compile '((@ (ice-9 format) format) #f "~:@(~A ~A~)" 'foo 'bar)
e0697241
LC
1671 #:opts %opts-w-format
1672 #:to 'assembly)))))
1673
1674 (pass-if "~v"
1675 (let ((w (call-with-warnings
1676 (lambda ()
60273407 1677 (compile '((@ (ice-9 format) format) #f "~v_foo")
e0697241
LC
1678 #:opts %opts-w-format
1679 #:to 'assembly)))))
1680 (and (= (length w) 1)
1681 (number? (string-contains (car w)
1682 "expected 1, got 0")))))
1683 (pass-if "~v:@y"
1684 (null? (call-with-warnings
1685 (lambda ()
60273407 1686 (compile '((@ (ice-9 format) format) #f "~v:@y" 1 123)
e0697241
LC
1687 #:opts %opts-w-format
1688 #:to 'assembly)))))
1689
1690
1691 (pass-if "~*"
1692 (let ((w (call-with-warnings
1693 (lambda ()
60273407 1694 (compile '((@ (ice-9 format) format) #f "~2*~a" 'a 'b)
e0697241
LC
1695 #:opts %opts-w-format
1696 #:to 'assembly)))))
1697 (and (= (length w) 1)
1698 (number? (string-contains (car w)
1699 "expected 3, got 2")))))
1700
1701 (pass-if "~?"
1702 (null? (call-with-warnings
1703 (lambda ()
60273407 1704 (compile '((@ (ice-9 format) format) #f "~?" "~d ~d" '(1 2))
e0697241
LC
1705 #:opts %opts-w-format
1706 #:to 'assembly)))))
1707
90baf8cd
IP
1708 (pass-if "~^"
1709 (null? (call-with-warnings
1710 (lambda ()
1711 (compile '((@ (ice-9 format) format) #f "~a ~^ ~a" 0 1)
1712 #:opts %opts-w-format
1713 #:to 'assembly)))))
1714
1715 (pass-if "~^, too few args"
1716 (let ((w (call-with-warnings
1717 (lambda ()
1718 (compile '((@ (ice-9 format) format) #f "~a ~^ ~a")
1719 #:opts %opts-w-format
1720 #:to 'assembly)))))
1721 (and (= (length w) 1)
1722 (number? (string-contains (car w)
1723 "expected at least 1, got 0")))))
1724
1725 (pass-if "parameters: +,-,#, and '"
1726 (null? (call-with-warnings
1727 (lambda ()
1728 (compile '((@ (ice-9 format) format) some-port
1729 "~#~ ~,,-2f ~,,+2f ~'A~" 1234 1234)
1730 #:opts %opts-w-format
1731 #:to 'assembly)))))
1732
e0697241
LC
1733 (pass-if "complex 1"
1734 (let ((w (call-with-warnings
1735 (lambda ()
60273407 1736 (compile '((@ (ice-9 format) format) #f
e0697241
LC
1737 "~4@S ~32S~@[;; ~1{~@?~}~]~@[~61t at ~a~]\n"
1738 1 2 3 4 5 6)
1739 #:opts %opts-w-format
1740 #:to 'assembly)))))
1741 (and (= (length w) 1)
1742 (number? (string-contains (car w)
1743 "expected 4, got 6")))))
1744
1745 (pass-if "complex 2"
1746 (let ((w (call-with-warnings
1747 (lambda ()
60273407 1748 (compile '((@ (ice-9 format) format) #f
e0697241
LC
1749 "~:(~A~) Commands~:[~; [abbrev]~]:~2%"
1750 1 2 3 4)
1751 #:opts %opts-w-format
1752 #:to 'assembly)))))
1753 (and (= (length w) 1)
1754 (number? (string-contains (car w)
1755 "expected 2, got 4")))))
1756
1757 (pass-if "complex 3"
1758 (let ((w (call-with-warnings
1759 (lambda ()
60273407 1760 (compile '((@ (ice-9 format) format) #f "~9@a~:[~*~3_~;~3d~] ~v:@y~%")
e0697241
LC
1761 #:opts %opts-w-format
1762 #:to 'assembly)))))
1763 (and (= (length w) 1)
1764 (number? (string-contains (car w)
1765 "expected 5, got 0")))))
1766
75365375
LC
1767 (pass-if "ice-9 format"
1768 (let ((w (call-with-warnings
1769 (lambda ()
1770 (let ((in (open-input-string
1771 "(use-modules ((ice-9 format)
1772 #:renamer (symbol-prefix-proc 'i9-)))
1773 (i9-format #t \"yo! ~A\" 1 2)")))
1774 (read-and-compile in
1775 #:opts %opts-w-format
1776 #:to 'assembly))))))
1777 (and (= (length w) 1)
1778 (number? (string-contains (car w)
1779 "expected 1, got 2")))))
1780
1781 (pass-if "not format"
1782 (null? (call-with-warnings
1783 (lambda ()
1784 (compile '(let ((format chbouib))
1785 (format #t "not ~A a format string"))
1786 #:opts %opts-w-format
60273407
LC
1787 #:to 'assembly)))))
1788
1789 (with-test-prefix "simple-format"
1790
1791 (pass-if "good"
1792 (null? (call-with-warnings
1793 (lambda ()
1794 (compile '(simple-format #t "foo ~a bar ~s ~%~~" 1 2)
1795 #:opts %opts-w-format
1796 #:to 'assembly)))))
1797
1798 (pass-if "wrong number of args"
1799 (let ((w (call-with-warnings
1800 (lambda ()
1801 (compile '(simple-format #t "foo ~a ~s~%" 'one-missing)
1802 #:opts %opts-w-format
1803 #:to 'assembly)))))
1804 (and (= (length w) 1)
1805 (number? (string-contains (car w) "wrong number")))))
1806
1807 (pass-if "unsupported"
1808 (let ((w (call-with-warnings
1809 (lambda ()
1810 (compile '(simple-format #t "foo ~x~%" 16)
1811 #:opts %opts-w-format
1812 #:to 'assembly)))))
afc98031
LC
1813 (and (= (length w) 1)
1814 (number? (string-contains (car w) "unsupported format option")))))
1815
1816 (pass-if "unsupported, gettext"
1817 (let ((w (call-with-warnings
1818 (lambda ()
1819 (compile '(simple-format #t (gettext "foo ~2f~%") 3.14)
1820 #:opts %opts-w-format
1821 #:to 'assembly)))))
98385ed2
LC
1822 (and (= (length w) 1)
1823 (number? (string-contains (car w) "unsupported format option")))))
1824
1825 (pass-if "unsupported, ngettext"
1826 (let ((w (call-with-warnings
1827 (lambda ()
1828 (compile '(simple-format #t (ngettext "s ~x" "p ~x" x) x)
1829 #:opts %opts-w-format
1830 #:to 'assembly)))))
60273407 1831 (and (= (length w) 1)
5cd10307
LC
1832 (number? (string-contains (car w) "unsupported format option")))))))
1833
1834 (with-test-prefix "duplicate-case-datum"
1835
1836 (pass-if "quiet"
1837 (null? (call-with-warnings
1838 (lambda ()
1839 (compile '(case x ((1) 'one) ((2) 'two))
1840 #:opts %opts-w-duplicate-case-datum
1841 #:to 'assembly)))))
1842
1843 (pass-if "one duplicate"
1844 (let ((w (call-with-warnings
1845 (lambda ()
1846 (compile '(case x
1847 ((1) 'one)
1848 ((2) 'two)
1849 ((1) 'one-again))
1850 #:opts %opts-w-duplicate-case-datum
1851 #:to 'assembly)))))
1852 (and (= (length w) 1)
1853 (number? (string-contains (car w) "duplicate")))))
1854
1855 (pass-if "one duplicate"
1856 (let ((w (call-with-warnings
1857 (lambda ()
1858 (compile '(case x
1859 ((1 2 3) 'a)
1860 ((1) 'one))
1861 #:opts %opts-w-duplicate-case-datum
1862 #:to 'assembly)))))
1863 (and (= (length w) 1)
1864 (number? (string-contains (car w) "duplicate"))))))
1865
1866 (with-test-prefix "bad-case-datum"
1867
1868 (pass-if "quiet"
1869 (null? (call-with-warnings
1870 (lambda ()
1871 (compile '(case x ((1) 'one) ((2) 'two))
1872 #:opts %opts-w-bad-case-datum
1873 #:to 'assembly)))))
1874
1875 (pass-if "not eqv?"
1876 (let ((w (call-with-warnings
1877 (lambda ()
1878 (compile '(case x
1879 ((1) 'one)
1880 (("bad") 'bad))
1881 #:opts %opts-w-bad-case-datum
1882 #:to 'assembly)))))
1883 (and (= (length w) 1)
1884 (number? (string-contains (car w)
1885 "cannot be meaningfully compared")))))
1886
1887 (pass-if "one clause element not eqv?"
1888 (let ((w (call-with-warnings
1889 (lambda ()
1890 (compile '(case x
1891 ((1 (2) 3) 'a))
1892 #:opts %opts-w-duplicate-case-datum
1893 #:to 'assembly)))))
1894 (and (= (length w) 1)
1895 (number? (string-contains (car w)
1896 "cannot be meaningfully compared")))))))
2446f8e1
LC
1897
1898;; Local Variables:
1899;; eval: (put 'pass-if-primitives-resolved 'scheme-indent-function 1)
1900;; eval: (put 'pass-if-tree-il->scheme 'scheme-indent-function 1)
1901;; End: