1 ;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*-
2 ;;;; Andy Wingo <wingo@pobox.com> --- May 2009
4 ;;;; Copyright (C) 2009-2014 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 (srfi srfi-13))
29 (define-syntax-rule (pass-if-primitives-resolved in expected)
30 (pass-if (format #f "primitives-resolved in ~s" 'in)
31 (let* ((module (let ((m (make-module)))
32 (beautify-user-module! m)
34 (orig (parse-tree-il 'in))
35 (resolved (expand-primitives (resolve-primitives orig module))))
36 (or (equal? (unparse-tree-il resolved) 'expected)
38 (format (current-error-port)
39 "primitive test failed: got ~s, expected ~s"
43 (define-syntax pass-if-tree-il->scheme
46 (assert-scheme->tree-il->scheme in pat #t))
49 (pmatch (tree-il->scheme
50 (compile 'in #:from 'scheme #:to 'tree-il))
51 (pat (guard guard-exp) #t)
55 (with-test-prefix "primitives"
57 (with-test-prefix "eqv?"
59 (pass-if-primitives-resolved
60 (primcall eqv? (toplevel x) (const #f))
61 (primcall eq? (const #f) (toplevel x)))
63 (pass-if-primitives-resolved
64 (primcall eqv? (toplevel x) (const ()))
65 (primcall eq? (const ()) (toplevel x)))
67 (pass-if-primitives-resolved
68 (primcall eqv? (const #t) (lexical x y))
69 (primcall eq? (const #t) (lexical x y)))
71 (pass-if-primitives-resolved
72 (primcall eqv? (const this-is-a-symbol) (toplevel x))
73 (primcall eq? (const this-is-a-symbol) (toplevel x)))
75 (pass-if-primitives-resolved
76 (primcall eqv? (const 42) (toplevel x))
77 (primcall eq? (const 42) (toplevel x)))
79 (pass-if-primitives-resolved
80 (primcall eqv? (const 42.0) (toplevel x))
81 (primcall eqv? (const 42.0) (toplevel x)))
83 (pass-if-primitives-resolved
84 (primcall eqv? (const #nil) (toplevel x))
85 (primcall eq? (const #nil) (toplevel x))))
87 (with-test-prefix "equal?"
89 (pass-if-primitives-resolved
90 (primcall equal? (toplevel x) (const #f))
91 (primcall eq? (const #f) (toplevel x)))
93 (pass-if-primitives-resolved
94 (primcall equal? (toplevel x) (const ()))
95 (primcall eq? (const ()) (toplevel x)))
97 (pass-if-primitives-resolved
98 (primcall equal? (const #t) (lexical x y))
99 (primcall eq? (const #t) (lexical x y)))
101 (pass-if-primitives-resolved
102 (primcall equal? (const this-is-a-symbol) (toplevel x))
103 (primcall eq? (const this-is-a-symbol) (toplevel x)))
105 (pass-if-primitives-resolved
106 (primcall equal? (const 42) (toplevel x))
107 (primcall eq? (const 42) (toplevel x)))
109 (pass-if-primitives-resolved
110 (primcall equal? (const 42.0) (toplevel x))
111 (primcall equal? (const 42.0) (toplevel x)))
113 (pass-if-primitives-resolved
114 (primcall equal? (const #nil) (toplevel x))
115 (primcall eq? (const #nil) (toplevel x)))))
118 (with-test-prefix "tree-il->scheme"
119 (pass-if-tree-il->scheme
120 (case-lambda ((a) a) ((b c) (list b c)))
121 (case-lambda ((,a) ,a1) ((,b ,c) (list ,b1 ,c1)))
122 (and (eq? a a1) (eq? b b1) (eq? c c1))))
125 (with-test-prefix "contification"
126 (pass-if "http://debbugs.gnu.org/9769"
127 ((compile '(lambda ()
128 (let ((fail (lambda () #f)))
129 (let ((test (lambda () (fail))))
132 ;; Prevent inlining. We're testing contificatoin here,
133 ;; and inlining it will reduce the entire thing to #t.
134 #:opts '(#:partial-eval? #f)))))
140 (with-test-prefix "many args"
141 (pass-if "call with > 256 args"
142 (equal? (compile `(1+ (sum ,@(iota 1000)))
143 #:env (current-module))
144 (1+ (apply sum (iota 1000)))))
146 (pass-if "tail call with > 256 args"
147 (equal? (compile `(sum ,@(iota 1000))
148 #:env (current-module))
149 (apply sum (iota 1000)))))
153 (with-test-prefix "tree-il-fold"
156 (let ((up 0) (down 0) (mark (list 'mark)))
158 (tree-il-fold (lambda (x y) (set! down (1+ down)) y)
159 (lambda (x y) (set! up (1+ up)) y)
165 (pass-if "lambda and application"
166 (let* ((ups '()) (downs '())
167 (result (tree-il-fold (lambda (x y)
168 (set! downs (cons x downs))
171 (set! ups (cons x ups))
177 (((x y) #f #f #f () (x1 y1))
182 (define (strip-source x)
183 (post-order (lambda (x)
184 (set! (tree-il-src x) #f)
188 (equal? (map strip-source (list-head (reverse ups) 3))
189 (list (make-toplevel-ref #f '+)
190 (make-lexical-ref #f 'x 'x1)
191 (make-lexical-ref #f 'y 'y1)))
192 (equal? (map strip-source (reverse (list-head downs 3)))
193 (list (make-toplevel-ref #f '+)
194 (make-lexical-ref #f 'x 'x1)
195 (make-lexical-ref #f 'y 'y1)))))))
202 ;; Make sure we get English messages.
203 (when (defined? 'setlocale)
204 (setlocale LC_ALL "C"))
206 (define (call-with-warnings thunk)
207 (let ((port (open-output-string)))
208 (with-fluids ((*current-warning-port* port)
209 (*current-warning-prefix* ""))
211 (let ((warnings (get-output-string port)))
212 (string-tokenize warnings
213 (char-set-complement (char-set #\newline))))))
215 (define %opts-w-unused
216 '(#:warnings (unused-variable)))
218 (define %opts-w-unused-toplevel
219 '(#:warnings (unused-toplevel)))
221 (define %opts-w-unbound
222 '(#:warnings (unbound-variable)))
224 (define %opts-w-arity
225 '(#:warnings (arity-mismatch)))
227 (define %opts-w-format
228 '(#:warnings (format)))
230 (define %opts-w-duplicate-case-datum
231 '(#:warnings (duplicate-case-datum)))
233 (define %opts-w-bad-case-datum
234 '(#:warnings (bad-case-datum)))
237 (with-test-prefix "warnings"
239 (pass-if "unknown warning type"
240 (let ((w (call-with-warnings
242 (compile #t #:opts '(#:warnings (does-not-exist)))))))
243 (and (= (length w) 1)
244 (number? (string-contains (car w) "unknown warning")))))
246 (with-test-prefix "unused-variable"
249 (null? (call-with-warnings
251 (compile '(lambda (x y) (+ x y))
252 #:opts %opts-w-unused)))))
254 (pass-if "let/unused"
255 (let ((w (call-with-warnings
257 (compile '(lambda (x)
260 #:opts %opts-w-unused)))))
261 (and (= (length w) 1)
262 (number? (string-contains (car w) "unused variable `y'")))))
264 (pass-if "shadowed variable"
265 (let ((w (call-with-warnings
267 (compile '(lambda (x)
271 #:opts %opts-w-unused)))))
272 (and (= (length w) 1)
273 (number? (string-contains (car w) "unused variable `y'")))))
276 (null? (call-with-warnings
279 (letrec ((x (lambda () (y)))
282 #:opts %opts-w-unused)))))
284 (pass-if "unused argument"
285 ;; Unused arguments should not be reported.
286 (null? (call-with-warnings
288 (compile '(lambda (x y z) #t)
289 #:opts %opts-w-unused)))))
291 (pass-if "special variable names"
292 (null? (call-with-warnings
295 (let ((_ 'underscore)
296 (#{gensym name}# 'ignore-me))
299 #:opts %opts-w-unused))))))
301 (with-test-prefix "unused-toplevel"
303 (pass-if "used after definition"
304 (null? (call-with-warnings
306 (let ((in (open-input-string
307 "(define foo 2) foo")))
310 #:opts %opts-w-unused-toplevel))))))
312 (pass-if "used before definition"
313 (null? (call-with-warnings
315 (let ((in (open-input-string
316 "(define (bar) foo) (define foo 2) (bar)")))
319 #:opts %opts-w-unused-toplevel))))))
321 (pass-if "unused but public"
322 (let ((in (open-input-string
323 "(define-module (test-suite tree-il x) #:export (bar))
324 (define (bar) #t)")))
325 (null? (call-with-warnings
329 #:opts %opts-w-unused-toplevel))))))
331 (pass-if "unused but public (more)"
332 (let ((in (open-input-string
333 "(define-module (test-suite tree-il x) #:export (bar))
336 (define (foo) #t)")))
337 (null? (call-with-warnings
341 #:opts %opts-w-unused-toplevel))))))
343 (pass-if "unused but define-public"
344 (null? (call-with-warnings
346 (compile '(define-public foo 2)
348 #:opts %opts-w-unused-toplevel)))))
350 (pass-if "used by macro"
351 ;; FIXME: See comment about macros at `unused-toplevel-analysis'.
354 (null? (call-with-warnings
356 (let ((in (open-input-string
359 (syntax-rules () ((_) (bar))))")))
362 #:opts %opts-w-unused-toplevel))))))
365 (let ((w (call-with-warnings
367 (compile '(define foo 2)
369 #:opts %opts-w-unused-toplevel)))))
370 (and (= (length w) 1)
371 (number? (string-contains (car w)
372 (format #f "top-level variable `~A'"
375 (pass-if "unused recursive"
376 (let ((w (call-with-warnings
378 (compile '(define (foo) (foo))
380 #:opts %opts-w-unused-toplevel)))))
381 (and (= (length w) 1)
382 (number? (string-contains (car w)
383 (format #f "top-level variable `~A'"
386 (pass-if "unused mutually recursive"
387 (let* ((in (open-input-string
388 "(define (foo) (bar)) (define (bar) (foo))"))
389 (w (call-with-warnings
393 #:opts %opts-w-unused-toplevel)))))
394 (and (= (length w) 2)
395 (number? (string-contains (car w)
396 (format #f "top-level variable `~A'"
398 (number? (string-contains (cadr w)
399 (format #f "top-level variable `~A'"
402 (pass-if "special variable names"
403 (null? (call-with-warnings
405 (compile '(define #{gensym name}# 'ignore-me)
407 #:opts %opts-w-unused-toplevel))))))
409 (with-test-prefix "unbound variable"
412 (null? (call-with-warnings
414 (compile '+ #:opts %opts-w-unbound)))))
418 (w (call-with-warnings
422 #:opts %opts-w-unbound)))))
423 (and (= (length w) 1)
424 (number? (string-contains (car w)
425 (format #f "unbound variable `~A'"
430 (w (call-with-warnings
432 (compile `(set! ,v 7)
434 #:opts %opts-w-unbound)))))
435 (and (= (length w) 1)
436 (number? (string-contains (car w)
437 (format #f "unbound variable `~A'"
440 (pass-if "module-local top-level is visible"
441 (let ((m (make-module))
443 (beautify-user-module! m)
444 (compile `(define ,v 123)
445 #:env m #:opts %opts-w-unbound)
446 (null? (call-with-warnings
451 #:opts %opts-w-unbound))))))
453 (pass-if "module-local top-level is visible after"
454 (let ((m (make-module))
456 (beautify-user-module! m)
457 (null? (call-with-warnings
459 (let ((in (open-input-string
462 (define chbouib 5)")))
465 #:opts %opts-w-unbound)))))))
467 (pass-if "optional arguments are visible"
468 (null? (call-with-warnings
470 (compile '(lambda* (x #:optional y z) (list x y z))
471 #:opts %opts-w-unbound
474 (pass-if "keyword arguments are visible"
475 (null? (call-with-warnings
477 (compile '(lambda* (x #:key y z) (list x y z))
478 #:opts %opts-w-unbound
481 (pass-if "GOOPS definitions are visible"
482 (let ((m (make-module))
484 (beautify-user-module! m)
485 (module-use! m (resolve-interface '(oop goops)))
486 (null? (call-with-warnings
488 (let ((in (open-input-string
489 "(define-class <foo> ()
490 (bar #:getter foo-bar))
491 (define z (foo-bar (make <foo>)))")))
494 #:opts %opts-w-unbound))))))))
496 (with-test-prefix "arity mismatch"
499 (null? (call-with-warnings
501 (compile '(cons 'a 'b) #:opts %opts-w-arity)))))
503 (pass-if "direct application"
504 (let ((w (call-with-warnings
506 (compile '((lambda (x y) (or x y)) 1 2 3 4 5)
509 (and (= (length w) 1)
510 (number? (string-contains (car w)
511 "wrong number of arguments to")))))
513 (let ((w (call-with-warnings
515 (compile '(let ((f (lambda (x y) (+ x y))))
519 (and (= (length w) 1)
520 (number? (string-contains (car w)
521 "wrong number of arguments to")))))
524 (let ((w (call-with-warnings
526 (compile '(cons 1 2 3 4)
529 (and (= (length w) 1)
530 (number? (string-contains (car w)
531 "wrong number of arguments to")))))
533 (pass-if "alias to global"
534 (let ((w (call-with-warnings
536 (compile '(let ((f cons)) (f 1 2 3 4))
539 (and (= (length w) 1)
540 (number? (string-contains (car w)
541 "wrong number of arguments to")))))
543 (pass-if "alias to lexical to global"
544 (let ((w (call-with-warnings
546 (compile '(let ((f number?))
551 (and (= (length w) 1)
552 (number? (string-contains (car w)
553 "wrong number of arguments to")))))
555 (pass-if "alias to lexical"
556 (let ((w (call-with-warnings
558 (compile '(let ((f (lambda (x y z) (+ x y z))))
563 (and (= (length w) 1)
564 (number? (string-contains (car w)
565 "wrong number of arguments to")))))
568 (let ((w (call-with-warnings
570 (compile '(letrec ((odd? (lambda (x) (even? (1- x))))
577 (and (= (length w) 1)
578 (number? (string-contains (car w)
579 "wrong number of arguments to")))))
581 (pass-if "case-lambda"
582 (null? (call-with-warnings
584 (compile '(let ((f (case-lambda
594 (pass-if "case-lambda with wrong number of arguments"
595 (let ((w (call-with-warnings
597 (compile '(let ((f (case-lambda
603 (and (= (length w) 1)
604 (number? (string-contains (car w)
605 "wrong number of arguments to")))))
607 (pass-if "case-lambda*"
608 (null? (call-with-warnings
610 (compile '(let ((f (case-lambda*
621 (pass-if "case-lambda* with wrong arguments"
622 (let ((w (call-with-warnings
624 (compile '(let ((f (case-lambda*
632 (and (= (length w) 2)
633 (null? (filter (lambda (w)
637 w "wrong number of arguments to"))))
640 (pass-if "top-level applicable struct"
641 (null? (call-with-warnings
643 (compile '(let ((p current-warning-port))
649 (pass-if "top-level applicable struct with wrong arguments"
650 (let ((w (call-with-warnings
652 (compile '(let ((p current-warning-port))
656 (and (= (length w) 1)
657 (number? (string-contains (car w)
658 "wrong number of arguments to")))))
660 (pass-if "local toplevel-defines"
661 (let ((w (call-with-warnings
663 (let ((in (open-input-string "
669 (and (= (length w) 1)
670 (number? (string-contains (car w)
671 "wrong number of arguments to")))))
673 (pass-if "global toplevel alias"
674 (let ((w (call-with-warnings
676 (let ((in (open-input-string "
682 (and (= (length w) 1)
683 (number? (string-contains (car w)
684 "wrong number of arguments to")))))
686 (pass-if "local toplevel overrides global"
687 (null? (call-with-warnings
689 (let ((in (open-input-string "
691 (define (foo x) (cons))")))
696 (pass-if "keyword not passed and quiet"
697 (null? (call-with-warnings
699 (compile '(let ((f (lambda* (x #:key y) y)))
704 (pass-if "keyword passed and quiet"
705 (null? (call-with-warnings
707 (compile '(let ((f (lambda* (x #:key y) y)))
712 (pass-if "keyword passed to global and quiet"
713 (null? (call-with-warnings
715 (let ((in (open-input-string "
716 (use-modules (system base compile))
717 (compile '(+ 2 3) #:env (current-module))")))
722 (pass-if "extra keyword"
723 (let ((w (call-with-warnings
725 (compile '(let ((f (lambda* (x #:key y) y)))
729 (and (= (length w) 1)
730 (number? (string-contains (car w)
731 "wrong number of arguments to")))))
733 (pass-if "extra keywords allowed"
734 (null? (call-with-warnings
736 (compile '(let ((f (lambda* (x #:key y #:allow-other-keys)
742 (with-test-prefix "format"
744 (pass-if "quiet (no args)"
745 (null? (call-with-warnings
747 (compile '(format #t "hey!")
748 #:opts %opts-w-format
751 (pass-if "quiet (1 arg)"
752 (null? (call-with-warnings
754 (compile '(format #t "hey ~A!" "you")
755 #:opts %opts-w-format
758 (pass-if "quiet (2 args)"
759 (null? (call-with-warnings
761 (compile '(format #t "~A ~A!" "hello" "world")
762 #:opts %opts-w-format
765 (pass-if "wrong port arg"
766 (let ((w (call-with-warnings
768 (compile '(format 10 "foo")
769 #:opts %opts-w-format
771 (and (= (length w) 1)
772 (number? (string-contains (car w)
773 "wrong port argument")))))
775 (pass-if "non-literal format string"
776 (let ((w (call-with-warnings
778 (compile '(format #f fmt)
779 #:opts %opts-w-format
781 (and (= (length w) 1)
782 (number? (string-contains (car w)
783 "non-literal format string")))))
785 (pass-if "non-literal format string using gettext"
786 (null? (call-with-warnings
788 (compile '(format #t (gettext "~A ~A!") "hello" "world")
789 #:opts %opts-w-format
792 (pass-if "non-literal format string using gettext as _"
793 (null? (call-with-warnings
795 (compile '(format #t (_ "~A ~A!") "hello" "world")
796 #:opts %opts-w-format
799 (pass-if "non-literal format string using gettext as top-level _"
800 (null? (call-with-warnings
803 (define (_ s) (gettext s "my-domain"))
804 (format #t (_ "~A ~A!") "hello" "world"))
805 #:opts %opts-w-format
808 (pass-if "non-literal format string using gettext as module-ref _"
809 (null? (call-with-warnings
811 (compile '(format #t ((@@ (foo) _) "~A ~A!") "hello" "world")
812 #:opts %opts-w-format
815 (pass-if "non-literal format string using gettext as lexical _"
816 (null? (call-with-warnings
818 (compile '(let ((_ (lambda (s)
819 (gettext s "my-domain"))))
820 (format #t (_ "~A ~A!") "hello" "world"))
821 #:opts %opts-w-format
824 (pass-if "non-literal format string using ngettext"
825 (null? (call-with-warnings
828 (ngettext "~a thing" "~a things" n "dom") n)
829 #:opts %opts-w-format
832 (pass-if "non-literal format string using ngettext as N_"
833 (null? (call-with-warnings
835 (compile '(format #t (N_ "~a thing" "~a things" n) n)
836 #:opts %opts-w-format
839 (pass-if "non-literal format string with (define _ gettext)"
840 (null? (call-with-warnings
845 (format #t (_ "~A ~A!") "hello" "world")))
846 #:opts %opts-w-format
849 (pass-if "wrong format string"
850 (let ((w (call-with-warnings
852 (compile '(format #f 'not-a-string)
853 #:opts %opts-w-format
855 (and (= (length w) 1)
856 (number? (string-contains (car w)
857 "wrong format string")))))
859 (pass-if "wrong number of args"
860 (let ((w (call-with-warnings
862 (compile '(format "shbweeb")
863 #:opts %opts-w-format
865 (and (= (length w) 1)
866 (number? (string-contains (car w)
867 "wrong number of arguments")))))
869 (pass-if "~%, ~~, ~&, ~t, ~_, ~!, ~|, ~/, ~q and ~\\n"
870 (null? (call-with-warnings
872 (compile '((@ (ice-9 format) format) some-port
873 "~&~3_~~ ~\n~12they~% ~!~|~/~q")
874 #:opts %opts-w-format
877 (pass-if "one missing argument"
878 (let ((w (call-with-warnings
880 (compile '(format some-port "foo ~A~%")
881 #:opts %opts-w-format
883 (and (= (length w) 1)
884 (number? (string-contains (car w)
885 "expected 1, got 0")))))
887 (pass-if "one missing argument, gettext"
888 (let ((w (call-with-warnings
890 (compile '(format some-port (gettext "foo ~A~%"))
891 #:opts %opts-w-format
893 (and (= (length w) 1)
894 (number? (string-contains (car w)
895 "expected 1, got 0")))))
897 (pass-if "two missing arguments"
898 (let ((w (call-with-warnings
900 (compile '((@ (ice-9 format) format) #f
901 "foo ~10,2f and bar ~S~%")
902 #:opts %opts-w-format
904 (and (= (length w) 1)
905 (number? (string-contains (car w)
906 "expected 2, got 0")))))
908 (pass-if "one given, one missing argument"
909 (let ((w (call-with-warnings
911 (compile '(format #t "foo ~A and ~S~%" hey)
912 #:opts %opts-w-format
914 (and (= (length w) 1)
915 (number? (string-contains (car w)
916 "expected 2, got 1")))))
918 (pass-if "too many arguments"
919 (let ((w (call-with-warnings
921 (compile '(format #t "foo ~A~%" 1 2)
922 #:opts %opts-w-format
924 (and (= (length w) 1)
925 (number? (string-contains (car w)
926 "expected 1, got 2")))))
929 (null? (call-with-warnings
931 (compile '((@ (ice-9 format) format) #t
932 "foo ~h ~a~%" 123.4 'bar)
933 #:opts %opts-w-format
936 (pass-if "~:h with locale object"
937 (null? (call-with-warnings
939 (compile '((@ (ice-9 format) format) #t
940 "foo ~:h~%" 123.4 %global-locale)
941 #:opts %opts-w-format
944 (pass-if "~:h without locale object"
945 (let ((w (call-with-warnings
947 (compile '((@ (ice-9 format) format) #t "foo ~,2:h" 123.4)
948 #:opts %opts-w-format
950 (and (= (length w) 1)
951 (number? (string-contains (car w)
952 "expected 2, got 1")))))
954 (with-test-prefix "conditionals"
956 (null? (call-with-warnings
958 (compile '((@ (ice-9 format) format) #f "~A ~[foo~;bar~;baz~;~] ~10,2f"
960 #:opts %opts-w-format
963 (pass-if "literals with selector"
964 (let ((w (call-with-warnings
966 (compile '((@ (ice-9 format) format) #f "~2[foo~;bar~;baz~;~] ~A"
968 #:opts %opts-w-format
970 (and (= (length w) 1)
971 (number? (string-contains (car w)
972 "expected 1, got 2")))))
974 (pass-if "escapes (exact count)"
975 (let ((w (call-with-warnings
977 (compile '((@ (ice-9 format) format) #f "~[~a~;~a~]")
978 #:opts %opts-w-format
980 (and (= (length w) 1)
981 (number? (string-contains (car w)
982 "expected 2, got 0")))))
984 (pass-if "escapes with selector"
985 (let ((w (call-with-warnings
987 (compile '((@ (ice-9 format) format) #f "~1[chbouib~;~a~]")
988 #:opts %opts-w-format
990 (and (= (length w) 1)
991 (number? (string-contains (car w)
992 "expected 1, got 0")))))
994 (pass-if "escapes, range"
995 (let ((w (call-with-warnings
997 (compile '((@ (ice-9 format) format) #f "~[chbouib~;~a~;~2*~a~]")
998 #:opts %opts-w-format
1000 (and (= (length w) 1)
1001 (number? (string-contains (car w)
1002 "expected 1 to 4, got 0")))))
1005 (let ((w (call-with-warnings
1007 (compile '((@ (ice-9 format) format) #f "~@[temperature=~d~]")
1008 #:opts %opts-w-format
1010 (and (= (length w) 1)
1011 (number? (string-contains (car w)
1012 "expected 1, got 0")))))
1015 (let ((w (call-with-warnings
1017 (compile '((@ (ice-9 format) format) #f "~:[~[hey~;~a~;~va~]~;~3*~]")
1018 #:opts %opts-w-format
1020 (and (= (length w) 1)
1021 (number? (string-contains (car w)
1022 "expected 2 to 4, got 0")))))
1024 (pass-if "unterminated"
1025 (let ((w (call-with-warnings
1027 (compile '((@ (ice-9 format) format) #f "~[unterminated")
1028 #:opts %opts-w-format
1030 (and (= (length w) 1)
1031 (number? (string-contains (car w)
1032 "unterminated conditional")))))
1034 (pass-if "unexpected ~;"
1035 (let ((w (call-with-warnings
1037 (compile '((@ (ice-9 format) format) #f "foo~;bar")
1038 #:opts %opts-w-format
1040 (and (= (length w) 1)
1041 (number? (string-contains (car w)
1044 (pass-if "unexpected ~]"
1045 (let ((w (call-with-warnings
1047 (compile '((@ (ice-9 format) format) #f "foo~]")
1048 #:opts %opts-w-format
1050 (and (= (length w) 1)
1051 (number? (string-contains (car w)
1055 (null? (call-with-warnings
1057 (compile '((@ (ice-9 format) format) #f "~A ~{~S~} ~A"
1058 'hello '("ladies" "and")
1060 #:opts %opts-w-format
1063 (pass-if "~{...~}, too many args"
1064 (let ((w (call-with-warnings
1066 (compile '((@ (ice-9 format) format) #f "~{~S~}" 1 2 3)
1067 #:opts %opts-w-format
1069 (and (= (length w) 1)
1070 (number? (string-contains (car w)
1071 "expected 1, got 3")))))
1074 (null? (call-with-warnings
1076 (compile '((@ (ice-9 format) format) #f "~@{~S~}" 1 2 3)
1077 #:opts %opts-w-format
1080 (pass-if "~@{...~}, too few args"
1081 (let ((w (call-with-warnings
1083 (compile '((@ (ice-9 format) format) #f "~A ~@{~S~}")
1084 #:opts %opts-w-format
1086 (and (= (length w) 1)
1087 (number? (string-contains (car w)
1088 "expected at least 1, got 0")))))
1090 (pass-if "unterminated ~{...~}"
1091 (let ((w (call-with-warnings
1093 (compile '((@ (ice-9 format) format) #f "~{")
1094 #:opts %opts-w-format
1096 (and (= (length w) 1)
1097 (number? (string-contains (car w)
1101 (null? (call-with-warnings
1103 (compile '((@ (ice-9 format) format) #f "~:@(~A ~A~)" 'foo 'bar)
1104 #:opts %opts-w-format
1108 (let ((w (call-with-warnings
1110 (compile '((@ (ice-9 format) format) #f "~v_foo")
1111 #:opts %opts-w-format
1113 (and (= (length w) 1)
1114 (number? (string-contains (car w)
1115 "expected 1, got 0")))))
1117 (null? (call-with-warnings
1119 (compile '((@ (ice-9 format) format) #f "~v:@y" 1 123)
1120 #:opts %opts-w-format
1125 (let ((w (call-with-warnings
1127 (compile '((@ (ice-9 format) format) #f "~2*~a" 'a 'b)
1128 #:opts %opts-w-format
1130 (and (= (length w) 1)
1131 (number? (string-contains (car w)
1132 "expected 3, got 2")))))
1135 (null? (call-with-warnings
1137 (compile '(((@ (ice-9 format) format) #f "thing~p" 2))
1138 #:opts %opts-w-format
1141 (pass-if "~p, too few arguments"
1142 (let ((w (call-with-warnings
1144 (compile '((@ (ice-9 format) format) #f "~p")
1145 #:opts %opts-w-format
1147 (and (= (length w) 1)
1148 (number? (string-contains (car w)
1149 "expected 1, got 0")))))
1152 (null? (call-with-warnings
1154 (compile '(((@ (ice-9 format) format) #f "~d thing~:p" 2))
1155 #:opts %opts-w-format
1158 (pass-if "~:@p, too many arguments"
1159 (let ((w (call-with-warnings
1161 (compile '((@ (ice-9 format) format) #f "~d pupp~:@p" 5 5)
1162 #:opts %opts-w-format
1164 (and (= (length w) 1)
1165 (number? (string-contains (car w)
1166 "expected 1, got 2")))))
1168 (pass-if "~:@p, too few arguments"
1169 (let ((w (call-with-warnings
1171 (compile '((@ (ice-9 format) format) #f "pupp~:@p")
1172 #:opts %opts-w-format
1174 (and (= (length w) 1)
1175 (number? (string-contains (car w)
1176 "expected 1, got 0")))))
1179 (null? (call-with-warnings
1181 (compile '((@ (ice-9 format) format) #f "~?" "~d ~d" '(1 2))
1182 #:opts %opts-w-format
1186 (null? (call-with-warnings
1188 (compile '((@ (ice-9 format) format) #f "~a ~^ ~a" 0 1)
1189 #:opts %opts-w-format
1192 (pass-if "~^, too few args"
1193 (let ((w (call-with-warnings
1195 (compile '((@ (ice-9 format) format) #f "~a ~^ ~a")
1196 #:opts %opts-w-format
1198 (and (= (length w) 1)
1199 (number? (string-contains (car w)
1200 "expected at least 1, got 0")))))
1202 (pass-if "parameters: +,-,#, and '"
1203 (null? (call-with-warnings
1205 (compile '((@ (ice-9 format) format) some-port
1206 "~#~ ~,,-2f ~,,+2f ~'A~" 1234 1234)
1207 #:opts %opts-w-format
1210 (pass-if "complex 1"
1211 (let ((w (call-with-warnings
1213 (compile '((@ (ice-9 format) format) #f
1214 "~4@S ~32S~@[;; ~1{~@?~}~]~@[~61t at ~a~]\n"
1216 #:opts %opts-w-format
1218 (and (= (length w) 1)
1219 (number? (string-contains (car w)
1220 "expected 4, got 6")))))
1222 (pass-if "complex 2"
1223 (let ((w (call-with-warnings
1225 (compile '((@ (ice-9 format) format) #f
1226 "~:(~A~) Commands~:[~; [abbrev]~]:~2%"
1228 #:opts %opts-w-format
1230 (and (= (length w) 1)
1231 (number? (string-contains (car w)
1232 "expected 2, got 4")))))
1234 (pass-if "complex 3"
1235 (let ((w (call-with-warnings
1237 (compile '((@ (ice-9 format) format) #f "~9@a~:[~*~3_~;~3d~] ~v:@y~%")
1238 #:opts %opts-w-format
1240 (and (= (length w) 1)
1241 (number? (string-contains (car w)
1242 "expected 5, got 0")))))
1244 (pass-if "ice-9 format"
1245 (let ((w (call-with-warnings
1247 (let ((in (open-input-string
1248 "(use-modules ((ice-9 format) #:prefix i9-))
1249 (i9-format #t \"yo! ~A\" 1 2)")))
1250 (read-and-compile in
1251 #:opts %opts-w-format
1253 (and (= (length w) 1)
1254 (number? (string-contains (car w)
1255 "expected 1, got 2")))))
1257 (pass-if "not format"
1258 (null? (call-with-warnings
1260 (compile '(let ((format chbouib))
1261 (format #t "not ~A a format string"))
1262 #:opts %opts-w-format
1265 (with-test-prefix "simple-format"
1268 (null? (call-with-warnings
1270 (compile '(simple-format #t "foo ~a bar ~s ~%~~" 1 2)
1271 #:opts %opts-w-format
1274 (pass-if "wrong number of args"
1275 (let ((w (call-with-warnings
1277 (compile '(simple-format #t "foo ~a ~s~%" 'one-missing)
1278 #:opts %opts-w-format
1280 (and (= (length w) 1)
1281 (number? (string-contains (car w) "wrong number")))))
1283 (pass-if "unsupported"
1284 (let ((w (call-with-warnings
1286 (compile '(simple-format #t "foo ~x~%" 16)
1287 #:opts %opts-w-format
1289 (and (= (length w) 1)
1290 (number? (string-contains (car w) "unsupported format option")))))
1292 (pass-if "unsupported, gettext"
1293 (let ((w (call-with-warnings
1295 (compile '(simple-format #t (gettext "foo ~2f~%") 3.14)
1296 #:opts %opts-w-format
1298 (and (= (length w) 1)
1299 (number? (string-contains (car w) "unsupported format option")))))
1301 (pass-if "unsupported, ngettext"
1302 (let ((w (call-with-warnings
1304 (compile '(simple-format #t (ngettext "s ~x" "p ~x" x) x)
1305 #:opts %opts-w-format
1307 (and (= (length w) 1)
1308 (number? (string-contains (car w) "unsupported format option")))))))
1310 (with-test-prefix "duplicate-case-datum"
1313 (null? (call-with-warnings
1315 (compile '(case x ((1) 'one) ((2) 'two))
1316 #:opts %opts-w-duplicate-case-datum
1319 (pass-if "one duplicate"
1320 (let ((w (call-with-warnings
1326 #:opts %opts-w-duplicate-case-datum
1328 (and (= (length w) 1)
1329 (number? (string-contains (car w) "duplicate")))))
1331 (pass-if "one duplicate"
1332 (let ((w (call-with-warnings
1337 #:opts %opts-w-duplicate-case-datum
1339 (and (= (length w) 1)
1340 (number? (string-contains (car w) "duplicate"))))))
1342 (with-test-prefix "bad-case-datum"
1345 (null? (call-with-warnings
1347 (compile '(case x ((1) 'one) ((2) 'two))
1348 #:opts %opts-w-bad-case-datum
1352 (let ((w (call-with-warnings
1357 #:opts %opts-w-bad-case-datum
1359 (and (= (length w) 1)
1360 (number? (string-contains (car w)
1361 "cannot be meaningfully compared")))))
1363 (pass-if "one clause element not eqv?"
1364 (let ((w (call-with-warnings
1368 #:opts %opts-w-duplicate-case-datum
1370 (and (= (length w) 1)
1371 (number? (string-contains (car w)
1372 "cannot be meaningfully compared")))))))
1375 ;; eval: (put 'pass-if-primitives-resolved 'scheme-indent-function 1)
1376 ;; eval: (put 'pass-if-tree-il->scheme 'scheme-indent-function 1)