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, 2013,
5 ;;;; 2014 Free Software Foundation, Inc.
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
10 ;;;; version 3 of the License, or (at your option) any later version.
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.
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
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)
25 #:use-module (system base message)
26 #:use-module (language tree-il)
27 #:use-module (language tree-il primitives)
28 #:use-module (srfi srfi-13))
30 (define-syntax-rule (pass-if-primitives-resolved in expected)
31 (pass-if (format #f "primitives-resolved in ~s" 'in)
32 (let* ((module (let ((m (make-module)))
33 (beautify-user-module! m)
35 (orig (parse-tree-il 'in))
36 (resolved (expand-primitives (resolve-primitives orig module))))
37 (or (equal? (unparse-tree-il resolved) 'expected)
39 (format (current-error-port)
40 "primitive test failed: got ~s, expected ~s"
44 (define-syntax pass-if-tree-il->scheme
47 (assert-scheme->tree-il->scheme in pat #t))
50 (pmatch (tree-il->scheme
51 (compile 'in #:from 'scheme #:to 'tree-il))
52 (pat (guard guard-exp) #t)
56 (with-test-prefix "primitives"
58 (with-test-prefix "eqv?"
60 (pass-if-primitives-resolved
61 (primcall eqv? (toplevel x) (const #f))
62 (primcall eq? (const #f) (toplevel x)))
64 (pass-if-primitives-resolved
65 (primcall eqv? (toplevel x) (const ()))
66 (primcall eq? (const ()) (toplevel x)))
68 (pass-if-primitives-resolved
69 (primcall eqv? (const #t) (lexical x y))
70 (primcall eq? (const #t) (lexical x y)))
72 (pass-if-primitives-resolved
73 (primcall eqv? (const this-is-a-symbol) (toplevel x))
74 (primcall eq? (const this-is-a-symbol) (toplevel x)))
76 (pass-if-primitives-resolved
77 (primcall eqv? (const 42) (toplevel x))
78 (primcall eq? (const 42) (toplevel x)))
80 (pass-if-primitives-resolved
81 (primcall eqv? (const 42.0) (toplevel x))
82 (primcall eqv? (const 42.0) (toplevel x)))
84 (pass-if-primitives-resolved
85 (primcall eqv? (const #nil) (toplevel x))
86 (primcall eq? (const #nil) (toplevel x))))
88 (with-test-prefix "equal?"
90 (pass-if-primitives-resolved
91 (primcall equal? (toplevel x) (const #f))
92 (primcall eq? (const #f) (toplevel x)))
94 (pass-if-primitives-resolved
95 (primcall equal? (toplevel x) (const ()))
96 (primcall eq? (const ()) (toplevel x)))
98 (pass-if-primitives-resolved
99 (primcall equal? (const #t) (lexical x y))
100 (primcall eq? (const #t) (lexical x y)))
102 (pass-if-primitives-resolved
103 (primcall equal? (const this-is-a-symbol) (toplevel x))
104 (primcall eq? (const this-is-a-symbol) (toplevel x)))
106 (pass-if-primitives-resolved
107 (primcall equal? (const 42) (toplevel x))
108 (primcall eq? (const 42) (toplevel x)))
110 (pass-if-primitives-resolved
111 (primcall equal? (const 42.0) (toplevel x))
112 (primcall equal? (const 42.0) (toplevel x)))
114 (pass-if-primitives-resolved
115 (primcall equal? (const #nil) (toplevel x))
116 (primcall eq? (const #nil) (toplevel x)))))
119 (with-test-prefix "tree-il->scheme"
120 (pass-if-tree-il->scheme
121 (case-lambda ((a) a) ((b c) (list b c)))
122 (case-lambda ((,a) ,a1) ((,b ,c) (list ,b1 ,c1)))
123 (and (eq? a a1) (eq? b b1) (eq? c c1))))
126 (with-test-prefix "contification"
127 (pass-if "http://debbugs.gnu.org/9769"
128 ((compile '(lambda ()
129 (let ((fail (lambda () #f)))
130 (let ((test (lambda () (fail))))
133 ;; Prevent inlining. We're testing contificatoin here,
134 ;; and inlining it will reduce the entire thing to #t.
135 #:opts '(#:partial-eval? #f)))))
141 (with-test-prefix "many args"
142 (pass-if "call with > 256 args"
143 (equal? (compile `(1+ (sum ,@(iota 1000)))
144 #:env (current-module))
145 (1+ (apply sum (iota 1000)))))
147 (pass-if "tail call with > 256 args"
148 (equal? (compile `(sum ,@(iota 1000))
149 #:env (current-module))
150 (apply sum (iota 1000)))))
154 (with-test-prefix "tree-il-fold"
157 (let ((up 0) (down 0) (mark (list 'mark)))
159 (tree-il-fold (lambda (x y) (set! down (1+ down)) y)
160 (lambda (x y) (set! up (1+ up)) y)
166 (pass-if "lambda and application"
167 (let* ((ups '()) (downs '())
168 (result (tree-il-fold (lambda (x y)
169 (set! downs (cons x downs))
172 (set! ups (cons x ups))
178 (((x y) #f #f #f () (x1 y1))
183 (define (strip-source x)
184 (post-order (lambda (x)
185 (set! (tree-il-src x) #f)
189 (equal? (map strip-source (list-head (reverse ups) 3))
190 (list (make-toplevel-ref #f '+)
191 (make-lexical-ref #f 'x 'x1)
192 (make-lexical-ref #f 'y 'y1)))
193 (equal? (map strip-source (reverse (list-head downs 3)))
194 (list (make-toplevel-ref #f '+)
195 (make-lexical-ref #f 'x 'x1)
196 (make-lexical-ref #f 'y 'y1)))))))
203 ;; Make sure we get English messages.
204 (when (defined? 'setlocale)
205 (setlocale LC_ALL "C"))
207 (define (call-with-warnings thunk)
208 (let ((port (open-output-string)))
209 (with-fluids ((*current-warning-port* port)
210 (*current-warning-prefix* ""))
212 (let ((warnings (get-output-string port)))
213 (string-tokenize warnings
214 (char-set-complement (char-set #\newline))))))
216 (define %opts-w-unused
217 '(#:warnings (unused-variable)))
219 (define %opts-w-unused-toplevel
220 '(#:warnings (unused-toplevel)))
222 (define %opts-w-unbound
223 '(#:warnings (unbound-variable)))
225 (define %opts-w-arity
226 '(#:warnings (arity-mismatch)))
228 (define %opts-w-format
229 '(#:warnings (format)))
231 (define %opts-w-duplicate-case-datum
232 '(#:warnings (duplicate-case-datum)))
234 (define %opts-w-bad-case-datum
235 '(#:warnings (bad-case-datum)))
238 (with-test-prefix "warnings"
240 (pass-if "unknown warning type"
241 (let ((w (call-with-warnings
243 (compile #t #:opts '(#:warnings (does-not-exist)))))))
244 (and (= (length w) 1)
245 (number? (string-contains (car w) "unknown warning")))))
247 (with-test-prefix "unused-variable"
250 (null? (call-with-warnings
252 (compile '(lambda (x y) (+ x y))
253 #:opts %opts-w-unused)))))
255 (pass-if "let/unused"
256 (let ((w (call-with-warnings
258 (compile '(lambda (x)
261 #:opts %opts-w-unused)))))
262 (and (= (length w) 1)
263 (number? (string-contains (car w) "unused variable `y'")))))
265 (pass-if "shadowed variable"
266 (let ((w (call-with-warnings
268 (compile '(lambda (x)
272 #:opts %opts-w-unused)))))
273 (and (= (length w) 1)
274 (number? (string-contains (car w) "unused variable `y'")))))
277 (null? (call-with-warnings
280 (letrec ((x (lambda () (y)))
283 #:opts %opts-w-unused)))))
285 (pass-if "unused argument"
286 ;; Unused arguments should not be reported.
287 (null? (call-with-warnings
289 (compile '(lambda (x y z) #t)
290 #:opts %opts-w-unused)))))
292 (pass-if "special variable names"
293 (null? (call-with-warnings
296 (let ((_ 'underscore)
297 (#{gensym name}# 'ignore-me))
300 #:opts %opts-w-unused))))))
302 (with-test-prefix "unused-toplevel"
304 (pass-if "used after definition"
305 (null? (call-with-warnings
307 (let ((in (open-input-string
308 "(define foo 2) foo")))
311 #:opts %opts-w-unused-toplevel))))))
313 (pass-if "used before definition"
314 (null? (call-with-warnings
316 (let ((in (open-input-string
317 "(define (bar) foo) (define foo 2) (bar)")))
320 #:opts %opts-w-unused-toplevel))))))
322 (pass-if "unused but public"
323 (let ((in (open-input-string
324 "(define-module (test-suite tree-il x) #:export (bar))
325 (define (bar) #t)")))
326 (null? (call-with-warnings
330 #:opts %opts-w-unused-toplevel))))))
332 (pass-if "unused but public (more)"
333 (let ((in (open-input-string
334 "(define-module (test-suite tree-il x) #:export (bar))
337 (define (foo) #t)")))
338 (null? (call-with-warnings
342 #:opts %opts-w-unused-toplevel))))))
344 (pass-if "unused but define-public"
345 (null? (call-with-warnings
347 (compile '(define-public foo 2)
349 #:opts %opts-w-unused-toplevel)))))
351 (pass-if "used by macro"
352 ;; FIXME: See comment about macros at `unused-toplevel-analysis'.
355 (null? (call-with-warnings
357 (let ((in (open-input-string
360 (syntax-rules () ((_) (bar))))")))
363 #:opts %opts-w-unused-toplevel))))))
366 (let ((w (call-with-warnings
368 (compile '(define foo 2)
370 #:opts %opts-w-unused-toplevel)))))
371 (and (= (length w) 1)
372 (number? (string-contains (car w)
373 (format #f "top-level variable `~A'"
376 (pass-if "unused recursive"
377 (let ((w (call-with-warnings
379 (compile '(define (foo) (foo))
381 #:opts %opts-w-unused-toplevel)))))
382 (and (= (length w) 1)
383 (number? (string-contains (car w)
384 (format #f "top-level variable `~A'"
387 (pass-if "unused mutually recursive"
388 (let* ((in (open-input-string
389 "(define (foo) (bar)) (define (bar) (foo))"))
390 (w (call-with-warnings
394 #:opts %opts-w-unused-toplevel)))))
395 (and (= (length w) 2)
396 (number? (string-contains (car w)
397 (format #f "top-level variable `~A'"
399 (number? (string-contains (cadr w)
400 (format #f "top-level variable `~A'"
403 (pass-if "special variable names"
404 (null? (call-with-warnings
406 (compile '(define #{gensym name}# 'ignore-me)
408 #:opts %opts-w-unused-toplevel))))))
410 (with-test-prefix "unbound variable"
413 (null? (call-with-warnings
415 (compile '+ #:opts %opts-w-unbound)))))
419 (w (call-with-warnings
423 #:opts %opts-w-unbound)))))
424 (and (= (length w) 1)
425 (number? (string-contains (car w)
426 (format #f "unbound variable `~A'"
431 (w (call-with-warnings
433 (compile `(set! ,v 7)
435 #:opts %opts-w-unbound)))))
436 (and (= (length w) 1)
437 (number? (string-contains (car w)
438 (format #f "unbound variable `~A'"
441 (pass-if "module-local top-level is visible"
442 (let ((m (make-module))
444 (beautify-user-module! m)
445 (compile `(define ,v 123)
446 #:env m #:opts %opts-w-unbound)
447 (null? (call-with-warnings
452 #:opts %opts-w-unbound))))))
454 (pass-if "module-local top-level is visible after"
455 (let ((m (make-module))
457 (beautify-user-module! m)
458 (null? (call-with-warnings
460 (let ((in (open-input-string
463 (define chbouib 5)")))
466 #:opts %opts-w-unbound)))))))
468 (pass-if "optional arguments are visible"
469 (null? (call-with-warnings
471 (compile '(lambda* (x #:optional y z) (list x y z))
472 #:opts %opts-w-unbound
475 (pass-if "keyword arguments are visible"
476 (null? (call-with-warnings
478 (compile '(lambda* (x #:key y z) (list x y z))
479 #:opts %opts-w-unbound
482 (pass-if "GOOPS definitions are visible"
483 (let ((m (make-module))
485 (beautify-user-module! m)
486 (module-use! m (resolve-interface '(oop goops)))
487 (null? (call-with-warnings
489 (let ((in (open-input-string
490 "(define-class <foo> ()
491 (bar #:getter foo-bar))
492 (define z (foo-bar (make <foo>)))")))
495 #:opts %opts-w-unbound))))))))
497 (with-test-prefix "arity mismatch"
500 (null? (call-with-warnings
502 (compile '(cons 'a 'b) #:opts %opts-w-arity)))))
504 (pass-if "direct application"
505 (let ((w (call-with-warnings
507 (compile '((lambda (x y) (or x y)) 1 2 3 4 5)
510 (and (= (length w) 1)
511 (number? (string-contains (car w)
512 "wrong number of arguments to")))))
514 (let ((w (call-with-warnings
516 (compile '(let ((f (lambda (x y) (+ x y))))
520 (and (= (length w) 1)
521 (number? (string-contains (car w)
522 "wrong number of arguments to")))))
525 (let ((w (call-with-warnings
527 (compile '(cons 1 2 3 4)
530 (and (= (length w) 1)
531 (number? (string-contains (car w)
532 "wrong number of arguments to")))))
534 (pass-if "alias to global"
535 (let ((w (call-with-warnings
537 (compile '(let ((f cons)) (f 1 2 3 4))
540 (and (= (length w) 1)
541 (number? (string-contains (car w)
542 "wrong number of arguments to")))))
544 (pass-if "alias to lexical to global"
545 (let ((w (call-with-warnings
547 (compile '(let ((f number?))
552 (and (= (length w) 1)
553 (number? (string-contains (car w)
554 "wrong number of arguments to")))))
556 (pass-if "alias to lexical"
557 (let ((w (call-with-warnings
559 (compile '(let ((f (lambda (x y z) (+ x y z))))
564 (and (= (length w) 1)
565 (number? (string-contains (car w)
566 "wrong number of arguments to")))))
569 (let ((w (call-with-warnings
571 (compile '(letrec ((odd? (lambda (x) (even? (1- x))))
578 (and (= (length w) 1)
579 (number? (string-contains (car w)
580 "wrong number of arguments to")))))
582 (pass-if "case-lambda"
583 (null? (call-with-warnings
585 (compile '(let ((f (case-lambda
595 (pass-if "case-lambda with wrong number of arguments"
596 (let ((w (call-with-warnings
598 (compile '(let ((f (case-lambda
604 (and (= (length w) 1)
605 (number? (string-contains (car w)
606 "wrong number of arguments to")))))
608 (pass-if "case-lambda*"
609 (null? (call-with-warnings
611 (compile '(let ((f (case-lambda*
622 (pass-if "case-lambda* with wrong arguments"
623 (let ((w (call-with-warnings
625 (compile '(let ((f (case-lambda*
633 (and (= (length w) 2)
634 (null? (filter (lambda (w)
638 w "wrong number of arguments to"))))
641 (pass-if "top-level applicable struct"
642 (null? (call-with-warnings
644 (compile '(let ((p current-warning-port))
650 (pass-if "top-level applicable struct with wrong arguments"
651 (let ((w (call-with-warnings
653 (compile '(let ((p current-warning-port))
657 (and (= (length w) 1)
658 (number? (string-contains (car w)
659 "wrong number of arguments to")))))
661 (pass-if "local toplevel-defines"
662 (let ((w (call-with-warnings
664 (let ((in (open-input-string "
670 (and (= (length w) 1)
671 (number? (string-contains (car w)
672 "wrong number of arguments to")))))
674 (pass-if "global toplevel alias"
675 (let ((w (call-with-warnings
677 (let ((in (open-input-string "
683 (and (= (length w) 1)
684 (number? (string-contains (car w)
685 "wrong number of arguments to")))))
687 (pass-if "local toplevel overrides global"
688 (null? (call-with-warnings
690 (let ((in (open-input-string "
692 (define (foo x) (cons))")))
697 (pass-if "keyword not passed and quiet"
698 (null? (call-with-warnings
700 (compile '(let ((f (lambda* (x #:key y) y)))
705 (pass-if "keyword passed and quiet"
706 (null? (call-with-warnings
708 (compile '(let ((f (lambda* (x #:key y) y)))
713 (pass-if "keyword passed to global and quiet"
714 (null? (call-with-warnings
716 (let ((in (open-input-string "
717 (use-modules (system base compile))
718 (compile '(+ 2 3) #:env (current-module))")))
723 (pass-if "extra keyword"
724 (let ((w (call-with-warnings
726 (compile '(let ((f (lambda* (x #:key y) y)))
730 (and (= (length w) 1)
731 (number? (string-contains (car w)
732 "wrong number of arguments to")))))
734 (pass-if "extra keywords allowed"
735 (null? (call-with-warnings
737 (compile '(let ((f (lambda* (x #:key y #:allow-other-keys)
743 (with-test-prefix "format"
745 (pass-if "quiet (no args)"
746 (null? (call-with-warnings
748 (compile '(format #t "hey!")
749 #:opts %opts-w-format
752 (pass-if "quiet (1 arg)"
753 (null? (call-with-warnings
755 (compile '(format #t "hey ~A!" "you")
756 #:opts %opts-w-format
759 (pass-if "quiet (2 args)"
760 (null? (call-with-warnings
762 (compile '(format #t "~A ~A!" "hello" "world")
763 #:opts %opts-w-format
766 (pass-if "wrong port arg"
767 (let ((w (call-with-warnings
769 (compile '(format 10 "foo")
770 #:opts %opts-w-format
772 (and (= (length w) 1)
773 (number? (string-contains (car w)
774 "wrong port argument")))))
776 (pass-if "non-literal format string"
777 (let ((w (call-with-warnings
779 (compile '(format #f fmt)
780 #:opts %opts-w-format
782 (and (= (length w) 1)
783 (number? (string-contains (car w)
784 "non-literal format string")))))
786 (pass-if "non-literal format string using gettext"
787 (null? (call-with-warnings
789 (compile '(format #t (gettext "~A ~A!") "hello" "world")
790 #:opts %opts-w-format
793 (pass-if "non-literal format string using gettext as _"
794 (null? (call-with-warnings
796 (compile '(format #t (_ "~A ~A!") "hello" "world")
797 #:opts %opts-w-format
800 (pass-if "non-literal format string using gettext as top-level _"
801 (null? (call-with-warnings
804 (define (_ s) (gettext s "my-domain"))
805 (format #t (_ "~A ~A!") "hello" "world"))
806 #:opts %opts-w-format
809 (pass-if "non-literal format string using gettext as module-ref _"
810 (null? (call-with-warnings
812 (compile '(format #t ((@@ (foo) _) "~A ~A!") "hello" "world")
813 #:opts %opts-w-format
816 (pass-if "non-literal format string using gettext as lexical _"
817 (null? (call-with-warnings
819 (compile '(let ((_ (lambda (s)
820 (gettext s "my-domain"))))
821 (format #t (_ "~A ~A!") "hello" "world"))
822 #:opts %opts-w-format
825 (pass-if "non-literal format string using ngettext"
826 (null? (call-with-warnings
829 (ngettext "~a thing" "~a things" n "dom") n)
830 #:opts %opts-w-format
833 (pass-if "non-literal format string using ngettext as N_"
834 (null? (call-with-warnings
836 (compile '(format #t (N_ "~a thing" "~a things" n) n)
837 #:opts %opts-w-format
840 (pass-if "non-literal format string with (define _ gettext)"
841 (null? (call-with-warnings
846 (format #t (_ "~A ~A!") "hello" "world")))
847 #:opts %opts-w-format
850 (pass-if "wrong format string"
851 (let ((w (call-with-warnings
853 (compile '(format #f 'not-a-string)
854 #:opts %opts-w-format
856 (and (= (length w) 1)
857 (number? (string-contains (car w)
858 "wrong format string")))))
860 (pass-if "wrong number of args"
861 (let ((w (call-with-warnings
863 (compile '(format "shbweeb")
864 #:opts %opts-w-format
866 (and (= (length w) 1)
867 (number? (string-contains (car w)
868 "wrong number of arguments")))))
870 (pass-if "~%, ~~, ~&, ~t, ~_, ~!, ~|, ~/, ~q and ~\\n"
871 (null? (call-with-warnings
873 (compile '((@ (ice-9 format) format) some-port
874 "~&~3_~~ ~\n~12they~% ~!~|~/~q")
875 #:opts %opts-w-format
878 (pass-if "one missing argument"
879 (let ((w (call-with-warnings
881 (compile '(format some-port "foo ~A~%")
882 #:opts %opts-w-format
884 (and (= (length w) 1)
885 (number? (string-contains (car w)
886 "expected 1, got 0")))))
888 (pass-if "one missing argument, gettext"
889 (let ((w (call-with-warnings
891 (compile '(format some-port (gettext "foo ~A~%"))
892 #:opts %opts-w-format
894 (and (= (length w) 1)
895 (number? (string-contains (car w)
896 "expected 1, got 0")))))
898 (pass-if "two missing arguments"
899 (let ((w (call-with-warnings
901 (compile '((@ (ice-9 format) format) #f
902 "foo ~10,2f and bar ~S~%")
903 #:opts %opts-w-format
905 (and (= (length w) 1)
906 (number? (string-contains (car w)
907 "expected 2, got 0")))))
909 (pass-if "one given, one missing argument"
910 (let ((w (call-with-warnings
912 (compile '(format #t "foo ~A and ~S~%" hey)
913 #:opts %opts-w-format
915 (and (= (length w) 1)
916 (number? (string-contains (car w)
917 "expected 2, got 1")))))
919 (pass-if "too many arguments"
920 (let ((w (call-with-warnings
922 (compile '(format #t "foo ~A~%" 1 2)
923 #:opts %opts-w-format
925 (and (= (length w) 1)
926 (number? (string-contains (car w)
927 "expected 1, got 2")))))
930 (null? (call-with-warnings
932 (compile '((@ (ice-9 format) format) #t
933 "foo ~h ~a~%" 123.4 'bar)
934 #:opts %opts-w-format
937 (pass-if "~:h with locale object"
938 (null? (call-with-warnings
940 (compile '((@ (ice-9 format) format) #t
941 "foo ~:h~%" 123.4 %global-locale)
942 #:opts %opts-w-format
945 (pass-if "~:h without locale object"
946 (let ((w (call-with-warnings
948 (compile '((@ (ice-9 format) format) #t "foo ~,2:h" 123.4)
949 #:opts %opts-w-format
951 (and (= (length w) 1)
952 (number? (string-contains (car w)
953 "expected 2, got 1")))))
955 (with-test-prefix "conditionals"
957 (null? (call-with-warnings
959 (compile '((@ (ice-9 format) format) #f "~A ~[foo~;bar~;baz~;~] ~10,2f"
961 #:opts %opts-w-format
964 (pass-if "literals with selector"
965 (let ((w (call-with-warnings
967 (compile '((@ (ice-9 format) format) #f "~2[foo~;bar~;baz~;~] ~A"
969 #:opts %opts-w-format
971 (and (= (length w) 1)
972 (number? (string-contains (car w)
973 "expected 1, got 2")))))
975 (pass-if "escapes (exact count)"
976 (let ((w (call-with-warnings
978 (compile '((@ (ice-9 format) format) #f "~[~a~;~a~]")
979 #:opts %opts-w-format
981 (and (= (length w) 1)
982 (number? (string-contains (car w)
983 "expected 2, got 0")))))
985 (pass-if "escapes with selector"
986 (let ((w (call-with-warnings
988 (compile '((@ (ice-9 format) format) #f "~1[chbouib~;~a~]")
989 #:opts %opts-w-format
991 (and (= (length w) 1)
992 (number? (string-contains (car w)
993 "expected 1, got 0")))))
995 (pass-if "escapes, range"
996 (let ((w (call-with-warnings
998 (compile '((@ (ice-9 format) format) #f "~[chbouib~;~a~;~2*~a~]")
999 #:opts %opts-w-format
1001 (and (= (length w) 1)
1002 (number? (string-contains (car w)
1003 "expected 1 to 4, got 0")))))
1006 (let ((w (call-with-warnings
1008 (compile '((@ (ice-9 format) format) #f "~@[temperature=~d~]")
1009 #:opts %opts-w-format
1011 (and (= (length w) 1)
1012 (number? (string-contains (car w)
1013 "expected 1, got 0")))))
1016 (let ((w (call-with-warnings
1018 (compile '((@ (ice-9 format) format) #f "~:[~[hey~;~a~;~va~]~;~3*~]")
1019 #:opts %opts-w-format
1021 (and (= (length w) 1)
1022 (number? (string-contains (car w)
1023 "expected 2 to 4, got 0")))))
1025 (pass-if "unterminated"
1026 (let ((w (call-with-warnings
1028 (compile '((@ (ice-9 format) format) #f "~[unterminated")
1029 #:opts %opts-w-format
1031 (and (= (length w) 1)
1032 (number? (string-contains (car w)
1033 "unterminated conditional")))))
1035 (pass-if "unexpected ~;"
1036 (let ((w (call-with-warnings
1038 (compile '((@ (ice-9 format) format) #f "foo~;bar")
1039 #:opts %opts-w-format
1041 (and (= (length w) 1)
1042 (number? (string-contains (car w)
1045 (pass-if "unexpected ~]"
1046 (let ((w (call-with-warnings
1048 (compile '((@ (ice-9 format) format) #f "foo~]")
1049 #:opts %opts-w-format
1051 (and (= (length w) 1)
1052 (number? (string-contains (car w)
1056 (null? (call-with-warnings
1058 (compile '((@ (ice-9 format) format) #f "~A ~{~S~} ~A"
1059 'hello '("ladies" "and")
1061 #:opts %opts-w-format
1064 (pass-if "~{...~}, too many args"
1065 (let ((w (call-with-warnings
1067 (compile '((@ (ice-9 format) format) #f "~{~S~}" 1 2 3)
1068 #:opts %opts-w-format
1070 (and (= (length w) 1)
1071 (number? (string-contains (car w)
1072 "expected 1, got 3")))))
1075 (null? (call-with-warnings
1077 (compile '((@ (ice-9 format) format) #f "~@{~S~}" 1 2 3)
1078 #:opts %opts-w-format
1081 (pass-if "~@{...~}, too few args"
1082 (let ((w (call-with-warnings
1084 (compile '((@ (ice-9 format) format) #f "~A ~@{~S~}")
1085 #:opts %opts-w-format
1087 (and (= (length w) 1)
1088 (number? (string-contains (car w)
1089 "expected at least 1, got 0")))))
1091 (pass-if "unterminated ~{...~}"
1092 (let ((w (call-with-warnings
1094 (compile '((@ (ice-9 format) format) #f "~{")
1095 #:opts %opts-w-format
1097 (and (= (length w) 1)
1098 (number? (string-contains (car w)
1102 (null? (call-with-warnings
1104 (compile '((@ (ice-9 format) format) #f "~:@(~A ~A~)" 'foo 'bar)
1105 #:opts %opts-w-format
1109 (let ((w (call-with-warnings
1111 (compile '((@ (ice-9 format) format) #f "~v_foo")
1112 #:opts %opts-w-format
1114 (and (= (length w) 1)
1115 (number? (string-contains (car w)
1116 "expected 1, got 0")))))
1118 (null? (call-with-warnings
1120 (compile '((@ (ice-9 format) format) #f "~v:@y" 1 123)
1121 #:opts %opts-w-format
1126 (let ((w (call-with-warnings
1128 (compile '((@ (ice-9 format) format) #f "~2*~a" 'a 'b)
1129 #:opts %opts-w-format
1131 (and (= (length w) 1)
1132 (number? (string-contains (car w)
1133 "expected 3, got 2")))))
1136 (null? (call-with-warnings
1138 (compile '((@ (ice-9 format) format) #f "~?" "~d ~d" '(1 2))
1139 #:opts %opts-w-format
1143 (null? (call-with-warnings
1145 (compile '((@ (ice-9 format) format) #f "~a ~^ ~a" 0 1)
1146 #:opts %opts-w-format
1149 (pass-if "~^, too few args"
1150 (let ((w (call-with-warnings
1152 (compile '((@ (ice-9 format) format) #f "~a ~^ ~a")
1153 #:opts %opts-w-format
1155 (and (= (length w) 1)
1156 (number? (string-contains (car w)
1157 "expected at least 1, got 0")))))
1159 (pass-if "parameters: +,-,#, and '"
1160 (null? (call-with-warnings
1162 (compile '((@ (ice-9 format) format) some-port
1163 "~#~ ~,,-2f ~,,+2f ~'A~" 1234 1234)
1164 #:opts %opts-w-format
1167 (pass-if "complex 1"
1168 (let ((w (call-with-warnings
1170 (compile '((@ (ice-9 format) format) #f
1171 "~4@S ~32S~@[;; ~1{~@?~}~]~@[~61t at ~a~]\n"
1173 #:opts %opts-w-format
1175 (and (= (length w) 1)
1176 (number? (string-contains (car w)
1177 "expected 4, got 6")))))
1179 (pass-if "complex 2"
1180 (let ((w (call-with-warnings
1182 (compile '((@ (ice-9 format) format) #f
1183 "~:(~A~) Commands~:[~; [abbrev]~]:~2%"
1185 #:opts %opts-w-format
1187 (and (= (length w) 1)
1188 (number? (string-contains (car w)
1189 "expected 2, got 4")))))
1191 (pass-if "complex 3"
1192 (let ((w (call-with-warnings
1194 (compile '((@ (ice-9 format) format) #f "~9@a~:[~*~3_~;~3d~] ~v:@y~%")
1195 #:opts %opts-w-format
1197 (and (= (length w) 1)
1198 (number? (string-contains (car w)
1199 "expected 5, got 0")))))
1201 (pass-if "ice-9 format"
1202 (let ((w (call-with-warnings
1204 (let ((in (open-input-string
1205 "(use-modules ((ice-9 format)
1206 #:renamer (symbol-prefix-proc 'i9-)))
1207 (i9-format #t \"yo! ~A\" 1 2)")))
1208 (read-and-compile in
1209 #:opts %opts-w-format
1211 (and (= (length w) 1)
1212 (number? (string-contains (car w)
1213 "expected 1, got 2")))))
1215 (pass-if "not format"
1216 (null? (call-with-warnings
1218 (compile '(let ((format chbouib))
1219 (format #t "not ~A a format string"))
1220 #:opts %opts-w-format
1223 (with-test-prefix "simple-format"
1226 (null? (call-with-warnings
1228 (compile '(simple-format #t "foo ~a bar ~s ~%~~" 1 2)
1229 #:opts %opts-w-format
1232 (pass-if "wrong number of args"
1233 (let ((w (call-with-warnings
1235 (compile '(simple-format #t "foo ~a ~s~%" 'one-missing)
1236 #:opts %opts-w-format
1238 (and (= (length w) 1)
1239 (number? (string-contains (car w) "wrong number")))))
1241 (pass-if "unsupported"
1242 (let ((w (call-with-warnings
1244 (compile '(simple-format #t "foo ~x~%" 16)
1245 #:opts %opts-w-format
1247 (and (= (length w) 1)
1248 (number? (string-contains (car w) "unsupported format option")))))
1250 (pass-if "unsupported, gettext"
1251 (let ((w (call-with-warnings
1253 (compile '(simple-format #t (gettext "foo ~2f~%") 3.14)
1254 #:opts %opts-w-format
1256 (and (= (length w) 1)
1257 (number? (string-contains (car w) "unsupported format option")))))
1259 (pass-if "unsupported, ngettext"
1260 (let ((w (call-with-warnings
1262 (compile '(simple-format #t (ngettext "s ~x" "p ~x" x) x)
1263 #:opts %opts-w-format
1265 (and (= (length w) 1)
1266 (number? (string-contains (car w) "unsupported format option")))))))
1268 (with-test-prefix "duplicate-case-datum"
1271 (null? (call-with-warnings
1273 (compile '(case x ((1) 'one) ((2) 'two))
1274 #:opts %opts-w-duplicate-case-datum
1277 (pass-if "one duplicate"
1278 (let ((w (call-with-warnings
1284 #:opts %opts-w-duplicate-case-datum
1286 (and (= (length w) 1)
1287 (number? (string-contains (car w) "duplicate")))))
1289 (pass-if "one duplicate"
1290 (let ((w (call-with-warnings
1295 #:opts %opts-w-duplicate-case-datum
1297 (and (= (length w) 1)
1298 (number? (string-contains (car w) "duplicate"))))))
1300 (with-test-prefix "bad-case-datum"
1303 (null? (call-with-warnings
1305 (compile '(case x ((1) 'one) ((2) 'two))
1306 #:opts %opts-w-bad-case-datum
1310 (let ((w (call-with-warnings
1315 #:opts %opts-w-bad-case-datum
1317 (and (= (length w) 1)
1318 (number? (string-contains (car w)
1319 "cannot be meaningfully compared")))))
1321 (pass-if "one clause element not eqv?"
1322 (let ((w (call-with-warnings
1326 #:opts %opts-w-duplicate-case-datum
1328 (and (= (length w) 1)
1329 (number? (string-contains (car w)
1330 "cannot be meaningfully compared")))))))
1333 ;; eval: (put 'pass-if-primitives-resolved 'scheme-indent-function 1)
1334 ;; eval: (put 'pass-if-tree-il->scheme 'scheme-indent-function 1)