1 ;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*-
2 ;;;; Andy Wingo <wingo@pobox.com> --- May 2009
4 ;;;; Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
6 ;;;; This library is free software; you can redistribute it and/or
7 ;;;; modify it under the terms of the GNU Lesser General Public
8 ;;;; License as published by the Free Software Foundation; either
9 ;;;; version 3 of the License, or (at your option) any later version.
11 ;;;; This library is distributed in the hope that it will be useful,
12 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ;;;; Lesser General Public License for more details.
16 ;;;; You should have received a copy of the GNU Lesser General Public
17 ;;;; License along with this library; if not, write to the Free Software
18 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 (define-module (test-suite tree-il)
21 #:use-module (test-suite lib)
22 #:use-module (system base compile)
23 #:use-module (system base pmatch)
24 #:use-module (system base message)
25 #:use-module (language tree-il)
26 #:use-module (language tree-il primitives)
27 #:use-module (language glil)
28 #:use-module (srfi srfi-13))
30 ;; Of course, the GLIL that is emitted depends on the source info of the
31 ;; input. Here we're not concerned about that, so we strip source
32 ;; information from the incoming tree-il.
34 (define (strip-source x)
35 (post-order! (lambda (x) (set! (tree-il-src x) #f))
38 (define-syntax assert-tree-il->glil
39 (syntax-rules (with-partial-evaluation without-partial-evaluation
41 ((_ with-partial-evaluation in pat test ...)
42 (assert-tree-il->glil with-options (#:partial-eval? #t)
44 ((_ without-partial-evaluation in pat test ...)
45 (assert-tree-il->glil with-options (#:partial-eval? #f)
47 ((_ with-options opts in pat test ...)
50 (let ((glil (unparse-glil
51 (compile (strip-source (parse-tree-il exp))
52 #:from 'tree-il #:to 'glil
55 (pat (guard test ...) #t)
58 (assert-tree-il->glil with-partial-evaluation
61 (define-syntax-rule (pass-if-primitives-resolved in expected)
62 (pass-if (format #f "primitives-resolved in ~s" 'in)
63 (let* ((module (let ((m (make-module)))
64 (beautify-user-module! m)
66 (orig (parse-tree-il 'in))
67 (resolved (expand-primitives! (resolve-primitives! orig module))))
68 (or (equal? (unparse-tree-il resolved) 'expected)
70 (format (current-error-port)
71 "primitive test failed: got ~s, expected ~s"
75 (define-syntax pass-if-tree-il->scheme
78 (assert-scheme->tree-il->scheme in pat #t))
81 (pmatch (tree-il->scheme
82 (compile 'in #:from 'scheme #:to 'tree-il))
83 (pat (guard guard-exp) #t)
87 (with-test-prefix "primitives"
89 (with-test-prefix "eqv?"
91 (pass-if-primitives-resolved
92 (primcall eqv? (toplevel x) (const #f))
93 (primcall eq? (const #f) (toplevel x)))
95 (pass-if-primitives-resolved
96 (primcall eqv? (toplevel x) (const ()))
97 (primcall eq? (const ()) (toplevel x)))
99 (pass-if-primitives-resolved
100 (primcall eqv? (const #t) (lexical x y))
101 (primcall eq? (const #t) (lexical x y)))
103 (pass-if-primitives-resolved
104 (primcall eqv? (const this-is-a-symbol) (toplevel x))
105 (primcall eq? (const this-is-a-symbol) (toplevel x)))
107 (pass-if-primitives-resolved
108 (primcall eqv? (const 42) (toplevel x))
109 (primcall eq? (const 42) (toplevel x)))
111 (pass-if-primitives-resolved
112 (primcall eqv? (const 42.0) (toplevel x))
113 (primcall eqv? (const 42.0) (toplevel x)))
115 (pass-if-primitives-resolved
116 (primcall eqv? (const #nil) (toplevel x))
117 (primcall eq? (const #nil) (toplevel x))))
119 (with-test-prefix "equal?"
121 (pass-if-primitives-resolved
122 (primcall equal? (toplevel x) (const #f))
123 (primcall eq? (const #f) (toplevel x)))
125 (pass-if-primitives-resolved
126 (primcall equal? (toplevel x) (const ()))
127 (primcall eq? (const ()) (toplevel x)))
129 (pass-if-primitives-resolved
130 (primcall equal? (const #t) (lexical x y))
131 (primcall eq? (const #t) (lexical x y)))
133 (pass-if-primitives-resolved
134 (primcall equal? (const this-is-a-symbol) (toplevel x))
135 (primcall eq? (const this-is-a-symbol) (toplevel x)))
137 (pass-if-primitives-resolved
138 (primcall equal? (const 42) (toplevel x))
139 (primcall eq? (const 42) (toplevel x)))
141 (pass-if-primitives-resolved
142 (primcall equal? (const 42.0) (toplevel x))
143 (primcall equal? (const 42.0) (toplevel x)))
145 (pass-if-primitives-resolved
146 (primcall equal? (const #nil) (toplevel x))
147 (primcall eq? (const #nil) (toplevel x)))))
150 (with-test-prefix "tree-il->scheme"
151 (pass-if-tree-il->scheme
152 (case-lambda ((a) a) ((b c) (list b c)))
153 (case-lambda ((,a) ,a1) ((,b ,c) (list ,b1 ,c1)))
154 (and (eq? a a1) (eq? b b1) (eq? c c1))))
156 (with-test-prefix "void"
157 (assert-tree-il->glil
159 (program () (std-prelude 0 0 #f) (label _) (void) (call return 1)))
160 (assert-tree-il->glil
161 (begin (void) (const 1))
162 (program () (std-prelude 0 0 #f) (label _) (const 1) (call return 1)))
163 (assert-tree-il->glil
164 (primcall + (void) (const 1))
165 (program () (std-prelude 0 0 #f) (label _) (void) (call add1 1) (call return 1))))
167 (with-test-prefix "application"
168 (assert-tree-il->glil
169 (call (toplevel foo) (const 1))
170 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (const 1) (call tail-call 1)))
171 (assert-tree-il->glil
172 (begin (call (toplevel foo) (const 1)) (void))
173 (program () (std-prelude 0 0 #f) (label _) (call new-frame 0) (toplevel ref foo) (const 1) (mv-call 1 ,l1)
174 (call drop 1) (branch br ,l2)
175 (label ,l3) (mv-bind 0 #f)
177 (void) (call return 1))
178 (and (eq? l1 l3) (eq? l2 l4)))
179 (assert-tree-il->glil
180 (call (toplevel foo) (call (toplevel bar)))
181 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (call new-frame 0) (toplevel ref bar) (call call 0)
182 (call tail-call 1))))
184 (with-test-prefix "conditional"
185 (assert-tree-il->glil
186 (if (toplevel foo) (const 1) (const 2))
187 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (branch br-if-not ,l1)
188 (const 1) (call return 1)
189 (label ,l2) (const 2) (call return 1))
192 (assert-tree-il->glil without-partial-evaluation
193 (begin (if (toplevel foo) (const 1) (const 2)) (const #f))
194 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (branch br-if-not ,l1) (branch br ,l2)
195 (label ,l3) (label ,l4) (const #f) (call return 1))
196 (eq? l1 l3) (eq? l2 l4))
198 (assert-tree-il->glil
199 (primcall null? (if (toplevel foo) (const 1) (const 2)))
200 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (branch br-if-not ,l1)
201 (const 1) (branch br ,l2)
202 (label ,l3) (const 2) (label ,l4)
203 (call null? 1) (call return 1))
204 (eq? l1 l3) (eq? l2 l4)))
206 (with-test-prefix "primitive-ref"
207 (assert-tree-il->glil
209 (program () (std-prelude 0 0 #f) (label _) (toplevel ref +) (call return 1)))
211 (assert-tree-il->glil
212 (begin (primitive +) (const #f))
213 (program () (std-prelude 0 0 #f) (label _) (const #f) (call return 1)))
215 (assert-tree-il->glil
216 (primcall null? (primitive +))
217 (program () (std-prelude 0 0 #f) (label _) (toplevel ref +) (call null? 1)
220 (with-test-prefix "lexical refs"
221 (assert-tree-il->glil without-partial-evaluation
222 (let (x) (y) ((const 1)) (lexical x y))
223 (program () (std-prelude 0 1 #f) (label _)
224 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
225 (lexical #t #f ref 0) (call return 1)
228 (assert-tree-il->glil with-options (#:partial-eval? #f #:cse? #f)
229 (let (x) (y) ((const 1)) (begin (lexical x y) (const #f)))
230 (program () (std-prelude 0 1 #f) (label _)
231 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
232 (const #f) (call return 1)
235 (assert-tree-il->glil without-partial-evaluation
236 (let (x) (y) ((const 1)) (primcall null? (lexical x y)))
237 (program () (std-prelude 0 1 #f) (label _)
238 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
239 (lexical #t #f ref 0) (call null? 1) (call return 1)
242 (with-test-prefix "lexical sets"
243 (assert-tree-il->glil
244 ;; unreferenced sets may be optimized away -- make sure they are ref'd
245 (let (x) (y) ((const 1))
246 (set! (lexical x y) (primcall 1+ (lexical x y))))
247 (program () (std-prelude 0 1 #f) (label _)
248 (const 1) (bind (x #t 0)) (lexical #t #t box 0)
249 (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0)
250 (void) (call return 1)
253 (assert-tree-il->glil
254 (let (x) (y) ((const 1))
255 (begin (set! (lexical x y) (primcall 1+ (lexical x y)))
257 (program () (std-prelude 0 1 #f) (label _)
258 (const 1) (bind (x #t 0)) (lexical #t #t box 0)
259 (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0)
260 (lexical #t #t ref 0) (call return 1)
263 (assert-tree-il->glil
264 (let (x) (y) ((const 1))
266 (set! (lexical x y) (primcall 1+ (lexical x y)))))
267 (program () (std-prelude 0 1 #f) (label _)
268 (const 1) (bind (x #t 0)) (lexical #t #t box 0)
269 (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0) (void)
270 (call null? 1) (call return 1)
273 (with-test-prefix "module refs"
274 (assert-tree-il->glil
276 (program () (std-prelude 0 0 #f) (label _)
277 (module public ref (foo) bar)
280 (assert-tree-il->glil
281 (begin (@ (foo) bar) (const #f))
282 (program () (std-prelude 0 0 #f) (label _)
283 (module public ref (foo) bar) (call drop 1)
284 (const #f) (call return 1)))
286 (assert-tree-il->glil
287 (primcall null? (@ (foo) bar))
288 (program () (std-prelude 0 0 #f) (label _)
289 (module public ref (foo) bar)
290 (call null? 1) (call return 1)))
292 (assert-tree-il->glil
294 (program () (std-prelude 0 0 #f) (label _)
295 (module private ref (foo) bar)
298 (assert-tree-il->glil
299 (begin (@@ (foo) bar) (const #f))
300 (program () (std-prelude 0 0 #f) (label _)
301 (module private ref (foo) bar) (call drop 1)
302 (const #f) (call return 1)))
304 (assert-tree-il->glil
305 (primcall null? (@@ (foo) bar))
306 (program () (std-prelude 0 0 #f) (label _)
307 (module private ref (foo) bar)
308 (call null? 1) (call return 1))))
310 (with-test-prefix "module sets"
311 (assert-tree-il->glil
312 (set! (@ (foo) bar) (const 2))
313 (program () (std-prelude 0 0 #f) (label _)
314 (const 2) (module public set (foo) bar)
315 (void) (call return 1)))
317 (assert-tree-il->glil
318 (begin (set! (@ (foo) bar) (const 2)) (const #f))
319 (program () (std-prelude 0 0 #f) (label _)
320 (const 2) (module public set (foo) bar)
321 (const #f) (call return 1)))
323 (assert-tree-il->glil
324 (primcall null? (set! (@ (foo) bar) (const 2)))
325 (program () (std-prelude 0 0 #f) (label _)
326 (const 2) (module public set (foo) bar)
327 (void) (call null? 1) (call return 1)))
329 (assert-tree-il->glil
330 (set! (@@ (foo) bar) (const 2))
331 (program () (std-prelude 0 0 #f) (label _)
332 (const 2) (module private set (foo) bar)
333 (void) (call return 1)))
335 (assert-tree-il->glil
336 (begin (set! (@@ (foo) bar) (const 2)) (const #f))
337 (program () (std-prelude 0 0 #f) (label _)
338 (const 2) (module private set (foo) bar)
339 (const #f) (call return 1)))
341 (assert-tree-il->glil
342 (primcall null? (set! (@@ (foo) bar) (const 2)))
343 (program () (std-prelude 0 0 #f) (label _)
344 (const 2) (module private set (foo) bar)
345 (void) (call null? 1) (call return 1))))
347 (with-test-prefix "toplevel refs"
348 (assert-tree-il->glil
350 (program () (std-prelude 0 0 #f) (label _)
354 (assert-tree-il->glil without-partial-evaluation
355 (begin (toplevel bar) (const #f))
356 (program () (std-prelude 0 0 #f) (label _)
357 (toplevel ref bar) (call drop 1)
358 (const #f) (call return 1)))
360 (assert-tree-il->glil
361 (primcall null? (toplevel bar))
362 (program () (std-prelude 0 0 #f) (label _)
364 (call null? 1) (call return 1))))
366 (with-test-prefix "toplevel sets"
367 (assert-tree-il->glil
368 (set! (toplevel bar) (const 2))
369 (program () (std-prelude 0 0 #f) (label _)
370 (const 2) (toplevel set bar)
371 (void) (call return 1)))
373 (assert-tree-il->glil
374 (begin (set! (toplevel bar) (const 2)) (const #f))
375 (program () (std-prelude 0 0 #f) (label _)
376 (const 2) (toplevel set bar)
377 (const #f) (call return 1)))
379 (assert-tree-il->glil
380 (primcall null? (set! (toplevel bar) (const 2)))
381 (program () (std-prelude 0 0 #f) (label _)
382 (const 2) (toplevel set bar)
383 (void) (call null? 1) (call return 1))))
385 (with-test-prefix "toplevel defines"
386 (assert-tree-il->glil
387 (define bar (const 2))
388 (program () (std-prelude 0 0 #f) (label _)
389 (const 2) (toplevel define bar)
390 (void) (call return 1)))
392 (assert-tree-il->glil
393 (begin (define bar (const 2)) (const #f))
394 (program () (std-prelude 0 0 #f) (label _)
395 (const 2) (toplevel define bar)
396 (const #f) (call return 1)))
398 (assert-tree-il->glil
399 (primcall null? (define bar (const 2)))
400 (program () (std-prelude 0 0 #f) (label _)
401 (const 2) (toplevel define bar)
402 (void) (call null? 1) (call return 1))))
404 (with-test-prefix "constants"
405 (assert-tree-il->glil
407 (program () (std-prelude 0 0 #f) (label _)
408 (const 2) (call return 1)))
410 (assert-tree-il->glil
411 (begin (const 2) (const #f))
412 (program () (std-prelude 0 0 #f) (label _)
413 (const #f) (call return 1)))
415 (assert-tree-il->glil
416 ;; This gets simplified by `peval'.
417 (primcall null? (const 2))
418 (program () (std-prelude 0 0 #f) (label _)
419 (const #f) (call return 1))))
421 (with-test-prefix "letrec"
422 ;; simple bindings -> let
423 (assert-tree-il->glil without-partial-evaluation
424 (letrec (x y) (x1 y1) ((const 10) (const 20))
425 (call (toplevel foo) (lexical x x1) (lexical y y1)))
426 (program () (std-prelude 0 2 #f) (label _)
427 (const 10) (const 20)
428 (bind (x #f 0) (y #f 1))
429 (lexical #t #f set 1) (lexical #t #f set 0)
431 (lexical #t #f ref 0) (lexical #t #f ref 1)
435 ;; complex bindings -> box and set! within let
436 (assert-tree-il->glil without-partial-evaluation
437 (letrec (x y) (x1 y1) ((call (toplevel foo)) (call (toplevel bar)))
438 (primcall + (lexical x x1) (lexical y y1)))
439 (program () (std-prelude 0 4 #f) (label _)
440 (void) (void) ;; what are these?
441 (bind (x #t 0) (y #t 1))
442 (lexical #t #t box 1) (lexical #t #t box 0)
443 (call new-frame 0) (toplevel ref foo) (call call 0)
444 (call new-frame 0) (toplevel ref bar) (call call 0)
445 (bind (x #f 2) (y #f 3)) (lexical #t #f set 3) (lexical #t #f set 2)
446 (lexical #t #f ref 2) (lexical #t #t set 0)
447 (lexical #t #f ref 3) (lexical #t #t set 1)
448 (void) (lexical #t #f set 2) (void) (lexical #t #f set 3) ;; clear bindings
450 (lexical #t #t ref 0) (lexical #t #t ref 1)
451 (call add 2) (call return 1) (unbind)))
453 ;; complex bindings in letrec* -> box and set! in order
454 (assert-tree-il->glil without-partial-evaluation
455 (letrec* (x y) (x1 y1) ((call (toplevel foo)) (call (toplevel bar)))
456 (primcall + (lexical x x1) (lexical y y1)))
457 (program () (std-prelude 0 2 #f) (label _)
458 (void) (void) ;; what are these?
459 (bind (x #t 0) (y #t 1))
460 (lexical #t #t box 1) (lexical #t #t box 0)
461 (call new-frame 0) (toplevel ref foo) (call call 0)
462 (lexical #t #t set 0)
463 (call new-frame 0) (toplevel ref bar) (call call 0)
464 (lexical #t #t set 1)
465 (lexical #t #t ref 0)
466 (lexical #t #t ref 1)
467 (call add 2) (call return 1) (unbind)))
469 ;; simple bindings in letrec* -> equivalent to letrec
470 (assert-tree-il->glil without-partial-evaluation
471 (letrec* (x y) (xx yy) ((const 1) (const 2))
473 (program () (std-prelude 0 1 #f) (label _)
475 (bind (y #f 0)) ;; X is removed, and Y is unboxed
476 (lexical #t #f set 0)
477 (lexical #t #f ref 0)
478 (call return 1) (unbind))))
480 (with-test-prefix "lambda"
481 (assert-tree-il->glil
483 (lambda-case (((x) #f #f #f () (y)) (const 2)) #f))
484 (program () (std-prelude 0 0 #f) (label _)
485 (program () (std-prelude 1 1 #f)
486 (bind (x #f 0)) (label _)
487 (const 2) (call return 1) (unbind))
490 (assert-tree-il->glil
492 (lambda-case (((x y) #f #f #f () (x1 y1))
495 (program () (std-prelude 0 0 #f) (label _)
496 (program () (std-prelude 2 2 #f)
497 (bind (x #f 0) (y #f 1)) (label _)
498 (const 2) (call return 1)
502 (assert-tree-il->glil
504 (lambda-case ((() #f x #f () (y)) (const 2))
506 (program () (std-prelude 0 0 #f) (label _)
507 (program () (opt-prelude 0 0 0 1 #f)
508 (bind (x #f 0)) (label _)
509 (const 2) (call return 1)
513 (assert-tree-il->glil
515 (lambda-case (((x) #f x1 #f () (y y1)) (const 2))
517 (program () (std-prelude 0 0 #f) (label _)
518 (program () (opt-prelude 1 0 1 2 #f)
519 (bind (x #f 0) (x1 #f 1)) (label _)
520 (const 2) (call return 1)
524 (assert-tree-il->glil
526 (lambda-case (((x) #f x1 #f () (y y1)) (lexical x y))
528 (program () (std-prelude 0 0 #f) (label _)
529 (program () (opt-prelude 1 0 1 2 #f)
530 (bind (x #f 0) (x1 #f 1)) (label _)
531 (lexical #t #f ref 0) (call return 1)
535 (assert-tree-il->glil
537 (lambda-case (((x) #f x1 #f () (y y1)) (lexical x1 y1))
539 (program () (std-prelude 0 0 #f) (label _)
540 (program () (opt-prelude 1 0 1 2 #f)
541 (bind (x #f 0) (x1 #f 1)) (label _)
542 (lexical #t #f ref 1) (call return 1)
546 (assert-tree-il->glil
548 (lambda-case (((x) #f #f #f () (x1))
550 (lambda-case (((y) #f #f #f () (y1))
554 (program () (std-prelude 0 0 #f) (label _)
555 (program () (std-prelude 1 1 #f)
556 (bind (x #f 0)) (label _)
557 (program () (std-prelude 1 1 #f)
558 (bind (y #f 0)) (label _)
559 (lexical #f #f ref 0) (call return 1)
561 (lexical #t #f ref 0)
562 (call make-closure 1)
567 (with-test-prefix "sequence"
568 (assert-tree-il->glil
569 (begin (begin (const 2) (const #f)) (const #t))
570 (program () (std-prelude 0 0 #f) (label _)
571 (const #t) (call return 1)))
573 (assert-tree-il->glil
574 ;; This gets simplified by `peval'.
575 (primcall null? (begin (const #f) (const 2)))
576 (program () (std-prelude 0 0 #f) (label _)
577 (const #f) (call return 1))))
579 (with-test-prefix "values"
580 (assert-tree-il->glil
582 (primcall values (const 1) (const 2)))
583 (program () (std-prelude 0 0 #f) (label _)
584 (const 1) (call return 1)))
586 (assert-tree-il->glil
588 (primcall values (const 1) (const 2))
590 (program () (std-prelude 0 0 #f) (label _)
591 (const 1) (const 3) (call return/values 2)))
593 (assert-tree-il->glil
595 (primcall values (const 1) (const 2)))
596 (program () (std-prelude 0 0 #f) (label _)
597 (const 1) (call return 1)))
599 ;; Testing `(values foo)' in push context with RA.
600 (assert-tree-il->glil without-partial-evaluation
602 (letrec (lp) (#{lp ~V9KrhVD4PFEL6oCTrLg3A}#)
603 ((lambda ((name . lp))
604 (lambda-case ((() #f #f #f () ())
605 (primcall values (const (one two)))))))
606 (call (lexical lp #{lp ~V9KrhVD4PFEL6oCTrLg3A}#))))
607 (program () (std-prelude 0 0 #f) (label _)
608 (branch br _) ;; entering the fix, jump to :2
609 ;; :1 body of lp, jump to :3
610 (label _) (bind) (const (one two)) (branch br _) (unbind)
611 ;; :2 initial call of lp, jump to :1
612 (label _) (bind) (branch br _) (label _) (unbind)
613 ;; :3 the push continuation
614 (call cdr 1) (call return 1))))
616 ;; FIXME: binding info for or-hacked locals might bork the disassembler,
617 ;; and could be tightened in any case
618 (with-test-prefix "the or hack"
619 (assert-tree-il->glil without-partial-evaluation
620 (let (x) (y) ((const 1))
623 (let (a) (b) ((const 2))
625 (program () (std-prelude 0 1 #f) (label _)
626 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
627 (lexical #t #f ref 0) (branch br-if-not ,l1)
628 (lexical #t #f ref 0) (call return 1)
630 (const 2) (bind (a #f 0)) (lexical #t #f set 0)
631 (lexical #t #f ref 0) (call return 1)
636 ;; second bound var is unreferenced
637 (assert-tree-il->glil without-partial-evaluation
638 (let (x) (y) ((const 1))
641 (let (a) (b) ((const 2))
643 (program () (std-prelude 0 1 #f) (label _)
644 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
645 (lexical #t #f ref 0) (branch br-if-not ,l1)
646 (lexical #t #f ref 0) (call return 1)
648 (lexical #t #f ref 0) (call return 1)
652 (with-test-prefix "apply"
653 (assert-tree-il->glil
654 (primcall @apply (toplevel foo) (toplevel bar))
655 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (toplevel ref bar) (call tail-apply 2)))
656 (assert-tree-il->glil
657 (begin (primcall @apply (toplevel foo) (toplevel bar)) (void))
658 (program () (std-prelude 0 0 #f) (label _)
659 (call new-frame 0) (toplevel ref apply) (toplevel ref foo) (toplevel ref bar) (mv-call 2 ,l1)
660 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind 0 #f)
662 (void) (call return 1))
663 (and (eq? l1 l3) (eq? l2 l4)))
664 (assert-tree-il->glil
665 (call (toplevel foo) (call (toplevel @apply) (toplevel bar) (toplevel baz)))
666 (program () (std-prelude 0 0 #f) (label _)
668 (call new-frame 0) (toplevel ref bar) (toplevel ref baz) (call apply 2)
669 (call tail-call 1))))
671 (with-test-prefix "call/cc"
672 (assert-tree-il->glil
673 (primcall @call-with-current-continuation (toplevel foo))
674 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (call tail-call/cc 1)))
675 (assert-tree-il->glil
676 (begin (primcall @call-with-current-continuation (toplevel foo)) (void))
677 (program () (std-prelude 0 0 #f) (label _)
678 (call new-frame 0) (toplevel ref call-with-current-continuation) (toplevel ref foo) (mv-call 1 ,l1)
679 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind 0 #f)
681 (void) (call return 1))
682 (and (eq? l1 l3) (eq? l2 l4)))
683 (assert-tree-il->glil
685 (call (toplevel @call-with-current-continuation) (toplevel bar)))
686 (program () (std-prelude 0 0 #f) (label _)
688 (toplevel ref bar) (call call/cc 1)
689 (call tail-call 1))))
692 (with-test-prefix "labels allocation"
693 (pass-if "http://debbugs.gnu.org/9769"
694 ((compile '(lambda ()
695 (let ((fail (lambda () #f)))
696 (let ((test (lambda () (fail))))
699 ;; Prevent inlining. We're testing analyze.scm's
700 ;; labels allocator here, and inlining it will
701 ;; reduce the entire thing to #t.
702 #:opts '(#:partial-eval? #f)))))
705 (with-test-prefix "tree-il-fold"
707 (pass-if "empty tree"
708 (let ((leaf? #f) (up? #f) (down? #f) (mark (list 'mark)))
710 (tree-il-fold (lambda (x y) (set! leaf? #t) y)
711 (lambda (x y) (set! down? #t) y)
712 (lambda (x y) (set! up? #t) y)
719 (pass-if "lambda and application"
720 (let* ((leaves '()) (ups '()) (downs '())
721 (result (tree-il-fold (lambda (x y)
722 (set! leaves (cons x leaves))
725 (set! downs (cons x downs))
728 (set! ups (cons x ups))
734 (((x y) #f #f #f () (x1 y1))
739 (and (equal? (map strip-source leaves)
740 (list (make-lexical-ref #f 'y 'y1)
741 (make-lexical-ref #f 'x 'x1)
742 (make-toplevel-ref #f '+)))
744 (equal? (reverse (map strip-source ups))
745 (map strip-source downs))))))
752 ;; Make sure we get English messages.
753 (setlocale LC_ALL "C")
755 (define (call-with-warnings thunk)
756 (let ((port (open-output-string)))
757 (with-fluids ((*current-warning-port* port)
758 (*current-warning-prefix* ""))
760 (let ((warnings (get-output-string port)))
761 (string-tokenize warnings
762 (char-set-complement (char-set #\newline))))))
764 (define %opts-w-unused
765 '(#:warnings (unused-variable)))
767 (define %opts-w-unused-toplevel
768 '(#:warnings (unused-toplevel)))
770 (define %opts-w-unbound
771 '(#:warnings (unbound-variable)))
773 (define %opts-w-arity
774 '(#:warnings (arity-mismatch)))
776 (define %opts-w-format
777 '(#:warnings (format)))
780 (with-test-prefix "warnings"
782 (pass-if "unknown warning type"
783 (let ((w (call-with-warnings
785 (compile #t #:opts '(#:warnings (does-not-exist)))))))
786 (and (= (length w) 1)
787 (number? (string-contains (car w) "unknown warning")))))
789 (with-test-prefix "unused-variable"
792 (null? (call-with-warnings
794 (compile '(lambda (x y) (+ x y))
795 #:opts %opts-w-unused)))))
797 (pass-if "let/unused"
798 (let ((w (call-with-warnings
800 (compile '(lambda (x)
803 #:opts %opts-w-unused)))))
804 (and (= (length w) 1)
805 (number? (string-contains (car w) "unused variable `y'")))))
807 (pass-if "shadowed variable"
808 (let ((w (call-with-warnings
810 (compile '(lambda (x)
814 #:opts %opts-w-unused)))))
815 (and (= (length w) 1)
816 (number? (string-contains (car w) "unused variable `y'")))))
819 (null? (call-with-warnings
822 (letrec ((x (lambda () (y)))
825 #:opts %opts-w-unused)))))
827 (pass-if "unused argument"
828 ;; Unused arguments should not be reported.
829 (null? (call-with-warnings
831 (compile '(lambda (x y z) #t)
832 #:opts %opts-w-unused)))))
834 (pass-if "special variable names"
835 (null? (call-with-warnings
838 (let ((_ 'underscore)
839 (#{gensym name}# 'ignore-me))
842 #:opts %opts-w-unused))))))
844 (with-test-prefix "unused-toplevel"
846 (pass-if "used after definition"
847 (null? (call-with-warnings
849 (let ((in (open-input-string
850 "(define foo 2) foo")))
853 #:opts %opts-w-unused-toplevel))))))
855 (pass-if "used before definition"
856 (null? (call-with-warnings
858 (let ((in (open-input-string
859 "(define (bar) foo) (define foo 2) (bar)")))
862 #:opts %opts-w-unused-toplevel))))))
864 (pass-if "unused but public"
865 (let ((in (open-input-string
866 "(define-module (test-suite tree-il x) #:export (bar))
867 (define (bar) #t)")))
868 (null? (call-with-warnings
872 #:opts %opts-w-unused-toplevel))))))
874 (pass-if "unused but public (more)"
875 (let ((in (open-input-string
876 "(define-module (test-suite tree-il x) #:export (bar))
879 (define (foo) #t)")))
880 (null? (call-with-warnings
884 #:opts %opts-w-unused-toplevel))))))
886 (pass-if "unused but define-public"
887 (null? (call-with-warnings
889 (compile '(define-public foo 2)
891 #:opts %opts-w-unused-toplevel)))))
893 (pass-if "used by macro"
894 ;; FIXME: See comment about macros at `unused-toplevel-analysis'.
897 (null? (call-with-warnings
899 (let ((in (open-input-string
902 (syntax-rules () ((_) (bar))))")))
905 #:opts %opts-w-unused-toplevel))))))
908 (let ((w (call-with-warnings
910 (compile '(define foo 2)
912 #:opts %opts-w-unused-toplevel)))))
913 (and (= (length w) 1)
914 (number? (string-contains (car w)
915 (format #f "top-level variable `~A'"
918 (pass-if "unused recursive"
919 (let ((w (call-with-warnings
921 (compile '(define (foo) (foo))
923 #:opts %opts-w-unused-toplevel)))))
924 (and (= (length w) 1)
925 (number? (string-contains (car w)
926 (format #f "top-level variable `~A'"
929 (pass-if "unused mutually recursive"
930 (let* ((in (open-input-string
931 "(define (foo) (bar)) (define (bar) (foo))"))
932 (w (call-with-warnings
936 #:opts %opts-w-unused-toplevel)))))
937 (and (= (length w) 2)
938 (number? (string-contains (car w)
939 (format #f "top-level variable `~A'"
941 (number? (string-contains (cadr w)
942 (format #f "top-level variable `~A'"
945 (pass-if "special variable names"
946 (null? (call-with-warnings
948 (compile '(define #{gensym name}# 'ignore-me)
950 #:opts %opts-w-unused-toplevel))))))
952 (with-test-prefix "unbound variable"
955 (null? (call-with-warnings
957 (compile '+ #:opts %opts-w-unbound)))))
961 (w (call-with-warnings
965 #:opts %opts-w-unbound)))))
966 (and (= (length w) 1)
967 (number? (string-contains (car w)
968 (format #f "unbound variable `~A'"
973 (w (call-with-warnings
975 (compile `(set! ,v 7)
977 #:opts %opts-w-unbound)))))
978 (and (= (length w) 1)
979 (number? (string-contains (car w)
980 (format #f "unbound variable `~A'"
983 (pass-if "module-local top-level is visible"
984 (let ((m (make-module))
986 (beautify-user-module! m)
987 (compile `(define ,v 123)
988 #:env m #:opts %opts-w-unbound)
989 (null? (call-with-warnings
994 #:opts %opts-w-unbound))))))
996 (pass-if "module-local top-level is visible after"
997 (let ((m (make-module))
999 (beautify-user-module! m)
1000 (null? (call-with-warnings
1002 (let ((in (open-input-string
1005 (define chbouib 5)")))
1006 (read-and-compile in
1008 #:opts %opts-w-unbound)))))))
1010 (pass-if "optional arguments are visible"
1011 (null? (call-with-warnings
1013 (compile '(lambda* (x #:optional y z) (list x y z))
1014 #:opts %opts-w-unbound
1017 (pass-if "keyword arguments are visible"
1018 (null? (call-with-warnings
1020 (compile '(lambda* (x #:key y z) (list x y z))
1021 #:opts %opts-w-unbound
1024 (pass-if "GOOPS definitions are visible"
1025 (let ((m (make-module))
1027 (beautify-user-module! m)
1028 (module-use! m (resolve-interface '(oop goops)))
1029 (null? (call-with-warnings
1031 (let ((in (open-input-string
1032 "(define-class <foo> ()
1033 (bar #:getter foo-bar))
1034 (define z (foo-bar (make <foo>)))")))
1035 (read-and-compile in
1037 #:opts %opts-w-unbound))))))))
1039 (with-test-prefix "arity mismatch"
1042 (null? (call-with-warnings
1044 (compile '(cons 'a 'b) #:opts %opts-w-arity)))))
1046 (pass-if "direct application"
1047 (let ((w (call-with-warnings
1049 (compile '((lambda (x y) (or x y)) 1 2 3 4 5)
1050 #:opts %opts-w-arity
1052 (and (= (length w) 1)
1053 (number? (string-contains (car w)
1054 "wrong number of arguments to")))))
1056 (let ((w (call-with-warnings
1058 (compile '(let ((f (lambda (x y) (+ x y))))
1060 #:opts %opts-w-arity
1062 (and (= (length w) 1)
1063 (number? (string-contains (car w)
1064 "wrong number of arguments to")))))
1067 (let ((w (call-with-warnings
1069 (compile '(cons 1 2 3 4)
1070 #:opts %opts-w-arity
1072 (and (= (length w) 1)
1073 (number? (string-contains (car w)
1074 "wrong number of arguments to")))))
1076 (pass-if "alias to global"
1077 (let ((w (call-with-warnings
1079 (compile '(let ((f cons)) (f 1 2 3 4))
1080 #:opts %opts-w-arity
1082 (and (= (length w) 1)
1083 (number? (string-contains (car w)
1084 "wrong number of arguments to")))))
1086 (pass-if "alias to lexical to global"
1087 (let ((w (call-with-warnings
1089 (compile '(let ((f number?))
1092 #:opts %opts-w-arity
1094 (and (= (length w) 1)
1095 (number? (string-contains (car w)
1096 "wrong number of arguments to")))))
1098 (pass-if "alias to lexical"
1099 (let ((w (call-with-warnings
1101 (compile '(let ((f (lambda (x y z) (+ x y z))))
1104 #:opts %opts-w-arity
1106 (and (= (length w) 1)
1107 (number? (string-contains (car w)
1108 "wrong number of arguments to")))))
1111 (let ((w (call-with-warnings
1113 (compile '(letrec ((odd? (lambda (x) (even? (1- x))))
1118 #:opts %opts-w-arity
1120 (and (= (length w) 1)
1121 (number? (string-contains (car w)
1122 "wrong number of arguments to")))))
1124 (pass-if "case-lambda"
1125 (null? (call-with-warnings
1127 (compile '(let ((f (case-lambda
1134 #:opts %opts-w-arity
1137 (pass-if "case-lambda with wrong number of arguments"
1138 (let ((w (call-with-warnings
1140 (compile '(let ((f (case-lambda
1144 #:opts %opts-w-arity
1146 (and (= (length w) 1)
1147 (number? (string-contains (car w)
1148 "wrong number of arguments to")))))
1150 (pass-if "case-lambda*"
1151 (null? (call-with-warnings
1153 (compile '(let ((f (case-lambda*
1154 ((x #:optional y) 1)
1156 ((x y #:key z) 3))))
1161 #:opts %opts-w-arity
1164 (pass-if "case-lambda* with wrong arguments"
1165 (let ((w (call-with-warnings
1167 (compile '(let ((f (case-lambda*
1168 ((x #:optional y) 1)
1170 ((x y #:key z) 3))))
1173 #:opts %opts-w-arity
1175 (and (= (length w) 2)
1176 (null? (filter (lambda (w)
1180 w "wrong number of arguments to"))))
1183 (pass-if "top-level applicable struct"
1184 (null? (call-with-warnings
1186 (compile '(let ((p current-warning-port))
1189 #:opts %opts-w-arity
1192 (pass-if "top-level applicable struct with wrong arguments"
1193 (let ((w (call-with-warnings
1195 (compile '(let ((p current-warning-port))
1197 #:opts %opts-w-arity
1199 (and (= (length w) 1)
1200 (number? (string-contains (car w)
1201 "wrong number of arguments to")))))
1203 (pass-if "local toplevel-defines"
1204 (let ((w (call-with-warnings
1206 (let ((in (open-input-string "
1207 (define (g x) (f x))
1209 (read-and-compile in
1210 #:opts %opts-w-arity
1211 #:to 'assembly))))))
1212 (and (= (length w) 1)
1213 (number? (string-contains (car w)
1214 "wrong number of arguments to")))))
1216 (pass-if "global toplevel alias"
1217 (let ((w (call-with-warnings
1219 (let ((in (open-input-string "
1221 (define (g) (f))")))
1222 (read-and-compile in
1223 #:opts %opts-w-arity
1224 #:to 'assembly))))))
1225 (and (= (length w) 1)
1226 (number? (string-contains (car w)
1227 "wrong number of arguments to")))))
1229 (pass-if "local toplevel overrides global"
1230 (null? (call-with-warnings
1232 (let ((in (open-input-string "
1234 (define (foo x) (cons))")))
1235 (read-and-compile in
1236 #:opts %opts-w-arity
1237 #:to 'assembly))))))
1239 (pass-if "keyword not passed and quiet"
1240 (null? (call-with-warnings
1242 (compile '(let ((f (lambda* (x #:key y) y)))
1244 #:opts %opts-w-arity
1247 (pass-if "keyword passed and quiet"
1248 (null? (call-with-warnings
1250 (compile '(let ((f (lambda* (x #:key y) y)))
1252 #:opts %opts-w-arity
1255 (pass-if "keyword passed to global and quiet"
1256 (null? (call-with-warnings
1258 (let ((in (open-input-string "
1259 (use-modules (system base compile))
1260 (compile '(+ 2 3) #:env (current-module))")))
1261 (read-and-compile in
1262 #:opts %opts-w-arity
1263 #:to 'assembly))))))
1265 (pass-if "extra keyword"
1266 (let ((w (call-with-warnings
1268 (compile '(let ((f (lambda* (x #:key y) y)))
1270 #:opts %opts-w-arity
1272 (and (= (length w) 1)
1273 (number? (string-contains (car w)
1274 "wrong number of arguments to")))))
1276 (pass-if "extra keywords allowed"
1277 (null? (call-with-warnings
1279 (compile '(let ((f (lambda* (x #:key y #:allow-other-keys)
1282 #:opts %opts-w-arity
1283 #:to 'assembly))))))
1285 (with-test-prefix "format"
1287 (pass-if "quiet (no args)"
1288 (null? (call-with-warnings
1290 (compile '(format #t "hey!")
1291 #:opts %opts-w-format
1294 (pass-if "quiet (1 arg)"
1295 (null? (call-with-warnings
1297 (compile '(format #t "hey ~A!" "you")
1298 #:opts %opts-w-format
1301 (pass-if "quiet (2 args)"
1302 (null? (call-with-warnings
1304 (compile '(format #t "~A ~A!" "hello" "world")
1305 #:opts %opts-w-format
1308 (pass-if "wrong port arg"
1309 (let ((w (call-with-warnings
1311 (compile '(format 10 "foo")
1312 #:opts %opts-w-format
1314 (and (= (length w) 1)
1315 (number? (string-contains (car w)
1316 "wrong port argument")))))
1318 (pass-if "non-literal format string"
1319 (let ((w (call-with-warnings
1321 (compile '(format #f fmt)
1322 #:opts %opts-w-format
1324 (and (= (length w) 1)
1325 (number? (string-contains (car w)
1326 "non-literal format string")))))
1328 (pass-if "non-literal format string using gettext"
1329 (null? (call-with-warnings
1331 (compile '(format #t (gettext "~A ~A!") "hello" "world")
1332 #:opts %opts-w-format
1335 (pass-if "non-literal format string using gettext as _"
1336 (null? (call-with-warnings
1338 (compile '(format #t (_ "~A ~A!") "hello" "world")
1339 #:opts %opts-w-format
1342 (pass-if "non-literal format string using gettext as top-level _"
1343 (null? (call-with-warnings
1346 (define (_ s) (gettext s "my-domain"))
1347 (format #t (_ "~A ~A!") "hello" "world"))
1348 #:opts %opts-w-format
1351 (pass-if "non-literal format string using gettext as module-ref _"
1352 (null? (call-with-warnings
1354 (compile '(format #t ((@@ (foo) _) "~A ~A!") "hello" "world")
1355 #:opts %opts-w-format
1358 (pass-if "non-literal format string using gettext as lexical _"
1359 (null? (call-with-warnings
1361 (compile '(let ((_ (lambda (s)
1362 (gettext s "my-domain"))))
1363 (format #t (_ "~A ~A!") "hello" "world"))
1364 #:opts %opts-w-format
1367 (pass-if "non-literal format string using ngettext"
1368 (null? (call-with-warnings
1370 (compile '(format #t
1371 (ngettext "~a thing" "~a things" n "dom") n)
1372 #:opts %opts-w-format
1375 (pass-if "non-literal format string using ngettext as N_"
1376 (null? (call-with-warnings
1378 (compile '(format #t (N_ "~a thing" "~a things" n) n)
1379 #:opts %opts-w-format
1382 (pass-if "non-literal format string with (define _ gettext)"
1383 (null? (call-with-warnings
1388 (format #t (_ "~A ~A!") "hello" "world")))
1389 #:opts %opts-w-format
1392 (pass-if "wrong format string"
1393 (let ((w (call-with-warnings
1395 (compile '(format #f 'not-a-string)
1396 #:opts %opts-w-format
1398 (and (= (length w) 1)
1399 (number? (string-contains (car w)
1400 "wrong format string")))))
1402 (pass-if "wrong number of args"
1403 (let ((w (call-with-warnings
1405 (compile '(format "shbweeb")
1406 #:opts %opts-w-format
1408 (and (= (length w) 1)
1409 (number? (string-contains (car w)
1410 "wrong number of arguments")))))
1412 (pass-if "~%, ~~, ~&, ~t, ~_, and ~\\n"
1413 (null? (call-with-warnings
1415 (compile '((@ (ice-9 format) format) some-port
1416 "~&~3_~~ ~\n~12they~%")
1417 #:opts %opts-w-format
1420 (pass-if "one missing argument"
1421 (let ((w (call-with-warnings
1423 (compile '(format some-port "foo ~A~%")
1424 #:opts %opts-w-format
1426 (and (= (length w) 1)
1427 (number? (string-contains (car w)
1428 "expected 1, got 0")))))
1430 (pass-if "one missing argument, gettext"
1431 (let ((w (call-with-warnings
1433 (compile '(format some-port (gettext "foo ~A~%"))
1434 #:opts %opts-w-format
1436 (and (= (length w) 1)
1437 (number? (string-contains (car w)
1438 "expected 1, got 0")))))
1440 (pass-if "two missing arguments"
1441 (let ((w (call-with-warnings
1443 (compile '((@ (ice-9 format) format) #f
1444 "foo ~10,2f and bar ~S~%")
1445 #:opts %opts-w-format
1447 (and (= (length w) 1)
1448 (number? (string-contains (car w)
1449 "expected 2, got 0")))))
1451 (pass-if "one given, one missing argument"
1452 (let ((w (call-with-warnings
1454 (compile '(format #t "foo ~A and ~S~%" hey)
1455 #:opts %opts-w-format
1457 (and (= (length w) 1)
1458 (number? (string-contains (car w)
1459 "expected 2, got 1")))))
1461 (pass-if "too many arguments"
1462 (let ((w (call-with-warnings
1464 (compile '(format #t "foo ~A~%" 1 2)
1465 #:opts %opts-w-format
1467 (and (= (length w) 1)
1468 (number? (string-contains (car w)
1469 "expected 1, got 2")))))
1472 (null? (call-with-warnings
1474 (compile '((@ (ice-9 format) format) #t
1475 "foo ~h ~a~%" 123.4 'bar)
1476 #:opts %opts-w-format
1479 (pass-if "~:h with locale object"
1480 (null? (call-with-warnings
1482 (compile '((@ (ice-9 format) format) #t
1483 "foo ~:h~%" 123.4 %global-locale)
1484 #:opts %opts-w-format
1487 (pass-if "~:h without locale object"
1488 (let ((w (call-with-warnings
1490 (compile '((@ (ice-9 format) format) #t "foo ~,2:h" 123.4)
1491 #:opts %opts-w-format
1493 (and (= (length w) 1)
1494 (number? (string-contains (car w)
1495 "expected 2, got 1")))))
1497 (with-test-prefix "conditionals"
1499 (null? (call-with-warnings
1501 (compile '((@ (ice-9 format) format) #f "~A ~[foo~;bar~;baz~;~] ~10,2f"
1503 #:opts %opts-w-format
1506 (pass-if "literals with selector"
1507 (let ((w (call-with-warnings
1509 (compile '((@ (ice-9 format) format) #f "~2[foo~;bar~;baz~;~] ~A"
1511 #:opts %opts-w-format
1513 (and (= (length w) 1)
1514 (number? (string-contains (car w)
1515 "expected 1, got 2")))))
1517 (pass-if "escapes (exact count)"
1518 (let ((w (call-with-warnings
1520 (compile '((@ (ice-9 format) format) #f "~[~a~;~a~]")
1521 #:opts %opts-w-format
1523 (and (= (length w) 1)
1524 (number? (string-contains (car w)
1525 "expected 2, got 0")))))
1527 (pass-if "escapes with selector"
1528 (let ((w (call-with-warnings
1530 (compile '((@ (ice-9 format) format) #f "~1[chbouib~;~a~]")
1531 #:opts %opts-w-format
1533 (and (= (length w) 1)
1534 (number? (string-contains (car w)
1535 "expected 1, got 0")))))
1537 (pass-if "escapes, range"
1538 (let ((w (call-with-warnings
1540 (compile '((@ (ice-9 format) format) #f "~[chbouib~;~a~;~2*~a~]")
1541 #:opts %opts-w-format
1543 (and (= (length w) 1)
1544 (number? (string-contains (car w)
1545 "expected 1 to 4, got 0")))))
1548 (let ((w (call-with-warnings
1550 (compile '((@ (ice-9 format) format) #f "~@[temperature=~d~]")
1551 #:opts %opts-w-format
1553 (and (= (length w) 1)
1554 (number? (string-contains (car w)
1555 "expected 1, got 0")))))
1558 (let ((w (call-with-warnings
1560 (compile '((@ (ice-9 format) format) #f "~:[~[hey~;~a~;~va~]~;~3*~]")
1561 #:opts %opts-w-format
1563 (and (= (length w) 1)
1564 (number? (string-contains (car w)
1565 "expected 2 to 4, got 0")))))
1567 (pass-if "unterminated"
1568 (let ((w (call-with-warnings
1570 (compile '((@ (ice-9 format) format) #f "~[unterminated")
1571 #:opts %opts-w-format
1573 (and (= (length w) 1)
1574 (number? (string-contains (car w)
1575 "unterminated conditional")))))
1577 (pass-if "unexpected ~;"
1578 (let ((w (call-with-warnings
1580 (compile '((@ (ice-9 format) format) #f "foo~;bar")
1581 #:opts %opts-w-format
1583 (and (= (length w) 1)
1584 (number? (string-contains (car w)
1587 (pass-if "unexpected ~]"
1588 (let ((w (call-with-warnings
1590 (compile '((@ (ice-9 format) format) #f "foo~]")
1591 #:opts %opts-w-format
1593 (and (= (length w) 1)
1594 (number? (string-contains (car w)
1598 (null? (call-with-warnings
1600 (compile '((@ (ice-9 format) format) #f "~A ~{~S~} ~A"
1601 'hello '("ladies" "and")
1603 #:opts %opts-w-format
1606 (pass-if "~{...~}, too many args"
1607 (let ((w (call-with-warnings
1609 (compile '((@ (ice-9 format) format) #f "~{~S~}" 1 2 3)
1610 #:opts %opts-w-format
1612 (and (= (length w) 1)
1613 (number? (string-contains (car w)
1614 "expected 1, got 3")))))
1617 (null? (call-with-warnings
1619 (compile '((@ (ice-9 format) format) #f "~@{~S~}" 1 2 3)
1620 #:opts %opts-w-format
1623 (pass-if "~@{...~}, too few args"
1624 (let ((w (call-with-warnings
1626 (compile '((@ (ice-9 format) format) #f "~A ~@{~S~}")
1627 #:opts %opts-w-format
1629 (and (= (length w) 1)
1630 (number? (string-contains (car w)
1631 "expected at least 1, got 0")))))
1633 (pass-if "unterminated ~{...~}"
1634 (let ((w (call-with-warnings
1636 (compile '((@ (ice-9 format) format) #f "~{")
1637 #:opts %opts-w-format
1639 (and (= (length w) 1)
1640 (number? (string-contains (car w)
1644 (null? (call-with-warnings
1646 (compile '((@ (ice-9 format) format) #f "~:@(~A ~A~)" 'foo 'bar)
1647 #:opts %opts-w-format
1651 (let ((w (call-with-warnings
1653 (compile '((@ (ice-9 format) format) #f "~v_foo")
1654 #:opts %opts-w-format
1656 (and (= (length w) 1)
1657 (number? (string-contains (car w)
1658 "expected 1, got 0")))))
1660 (null? (call-with-warnings
1662 (compile '((@ (ice-9 format) format) #f "~v:@y" 1 123)
1663 #:opts %opts-w-format
1668 (let ((w (call-with-warnings
1670 (compile '((@ (ice-9 format) format) #f "~2*~a" 'a 'b)
1671 #:opts %opts-w-format
1673 (and (= (length w) 1)
1674 (number? (string-contains (car w)
1675 "expected 3, got 2")))))
1678 (null? (call-with-warnings
1680 (compile '((@ (ice-9 format) format) #f "~?" "~d ~d" '(1 2))
1681 #:opts %opts-w-format
1684 (pass-if "complex 1"
1685 (let ((w (call-with-warnings
1687 (compile '((@ (ice-9 format) format) #f
1688 "~4@S ~32S~@[;; ~1{~@?~}~]~@[~61t at ~a~]\n"
1690 #:opts %opts-w-format
1692 (and (= (length w) 1)
1693 (number? (string-contains (car w)
1694 "expected 4, got 6")))))
1696 (pass-if "complex 2"
1697 (let ((w (call-with-warnings
1699 (compile '((@ (ice-9 format) format) #f
1700 "~:(~A~) Commands~:[~; [abbrev]~]:~2%"
1702 #:opts %opts-w-format
1704 (and (= (length w) 1)
1705 (number? (string-contains (car w)
1706 "expected 2, got 4")))))
1708 (pass-if "complex 3"
1709 (let ((w (call-with-warnings
1711 (compile '((@ (ice-9 format) format) #f "~9@a~:[~*~3_~;~3d~] ~v:@y~%")
1712 #:opts %opts-w-format
1714 (and (= (length w) 1)
1715 (number? (string-contains (car w)
1716 "expected 5, got 0")))))
1718 (pass-if "ice-9 format"
1719 (let ((w (call-with-warnings
1721 (let ((in (open-input-string
1722 "(use-modules ((ice-9 format)
1723 #:renamer (symbol-prefix-proc 'i9-)))
1724 (i9-format #t \"yo! ~A\" 1 2)")))
1725 (read-and-compile in
1726 #:opts %opts-w-format
1727 #:to 'assembly))))))
1728 (and (= (length w) 1)
1729 (number? (string-contains (car w)
1730 "expected 1, got 2")))))
1732 (pass-if "not format"
1733 (null? (call-with-warnings
1735 (compile '(let ((format chbouib))
1736 (format #t "not ~A a format string"))
1737 #:opts %opts-w-format
1740 (with-test-prefix "simple-format"
1743 (null? (call-with-warnings
1745 (compile '(simple-format #t "foo ~a bar ~s ~%~~" 1 2)
1746 #:opts %opts-w-format
1749 (pass-if "wrong number of args"
1750 (let ((w (call-with-warnings
1752 (compile '(simple-format #t "foo ~a ~s~%" 'one-missing)
1753 #:opts %opts-w-format
1755 (and (= (length w) 1)
1756 (number? (string-contains (car w) "wrong number")))))
1758 (pass-if "unsupported"
1759 (let ((w (call-with-warnings
1761 (compile '(simple-format #t "foo ~x~%" 16)
1762 #:opts %opts-w-format
1764 (and (= (length w) 1)
1765 (number? (string-contains (car w) "unsupported format option")))))
1767 (pass-if "unsupported, gettext"
1768 (let ((w (call-with-warnings
1770 (compile '(simple-format #t (gettext "foo ~2f~%") 3.14)
1771 #:opts %opts-w-format
1773 (and (= (length w) 1)
1774 (number? (string-contains (car w) "unsupported format option")))))
1776 (pass-if "unsupported, ngettext"
1777 (let ((w (call-with-warnings
1779 (compile '(simple-format #t (ngettext "s ~x" "p ~x" x) x)
1780 #:opts %opts-w-format
1782 (and (= (length w) 1)
1783 (number? (string-contains (car w) "unsupported format option"))))))))
1786 ;; eval: (put 'pass-if-primitives-resolved 'scheme-indent-function 1)
1787 ;; eval: (put 'pass-if-tree-il->scheme 'scheme-indent-function 1)