fix analyze.scm literal string warnings
[bpt/guile.git] / test-suite / tests / tree-il.test
CommitLineData
ce09ee19
AW
1;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*-
2;;;; Andy Wingo <wingo@pobox.com> --- May 2009
3;;;;
a4060f67
LC
4;;;; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
5;;;;
ce09ee19
AW
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
53befeb7 9;;;; version 3 of the License, or (at your option) any later version.
a4060f67 10;;;;
ce09ee19
AW
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.
a4060f67 15;;;;
ce09ee19
AW
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
19
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)
4b856371 24 #:use-module (system base message)
ce09ee19 25 #:use-module (language tree-il)
4b856371
LC
26 #:use-module (language glil)
27 #:use-module (srfi srfi-13))
ce09ee19 28
e0c90f90
AW
29;; Of course, the GLIL that is emitted depends on the source info of the
30;; input. Here we're not concerned about that, so we strip source
31;; information from the incoming tree-il.
32
33(define (strip-source x)
34 (post-order! (lambda (x) (set! (tree-il-src x) #f))
35 x))
36
ce09ee19
AW
37(define-syntax assert-scheme->glil
38 (syntax-rules ()
39 ((_ in out)
e0c90f90
AW
40 (let ((tree-il (strip-source
41 (compile 'in #:from 'scheme #:to 'tree-il))))
ce09ee19
AW
42 (pass-if 'in
43 (equal? (unparse-glil (compile tree-il #:from 'tree-il #:to 'glil))
44 'out))))))
45
46(define-syntax assert-tree-il->glil
ce09ee19
AW
47 (syntax-rules ()
48 ((_ in pat test ...)
49 (let ((exp 'in))
50 (pass-if 'in
51 (let ((glil (unparse-glil
e0c90f90 52 (compile (strip-source (parse-tree-il exp))
ce09ee19
AW
53 #:from 'tree-il #:to 'glil))))
54 (pmatch glil
55 (pat (guard test ...) #t)
56 (else #f))))))))
57
ce09ee19
AW
58(with-test-prefix "void"
59 (assert-tree-il->glil
60 (void)
8a4ca0ea 61 (program () (std-prelude 0 0 #f) (label _) (void) (call return 1)))
ce09ee19
AW
62 (assert-tree-il->glil
63 (begin (void) (const 1))
8a4ca0ea 64 (program () (std-prelude 0 0 #f) (label _) (const 1) (call return 1)))
ce09ee19
AW
65 (assert-tree-il->glil
66 (apply (primitive +) (void) (const 1))
8a4ca0ea 67 (program () (std-prelude 0 0 #f) (label _) (void) (call add1 1) (call return 1))))
ce09ee19
AW
68
69(with-test-prefix "application"
70 (assert-tree-il->glil
71 (apply (toplevel foo) (const 1))
a5bbb22e 72 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (const 1) (call tail-call 1)))
8a4ca0ea 73 (assert-tree-il->glil
ce09ee19 74 (begin (apply (toplevel foo) (const 1)) (void))
8a4ca0ea 75 (program () (std-prelude 0 0 #f) (label _) (call new-frame 0) (toplevel ref foo) (const 1) (mv-call 1 ,l1)
0f423f20 76 (call drop 1) (branch br ,l2)
05c51bcf 77 (label ,l3) (mv-bind 0 #f)
0f423f20 78 (label ,l4)
30a5e062 79 (void) (call return 1))
0f423f20 80 (and (eq? l1 l3) (eq? l2 l4)))
ce09ee19
AW
81 (assert-tree-il->glil
82 (apply (toplevel foo) (apply (toplevel bar)))
8a4ca0ea 83 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (call new-frame 0) (toplevel ref bar) (call call 0)
a5bbb22e 84 (call tail-call 1))))
ce09ee19
AW
85
86(with-test-prefix "conditional"
8a4ca0ea 87 (assert-tree-il->glil
0e4b7818
AW
88 (if (toplevel foo) (const 1) (const 2))
89 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (branch br-if-not ,l1)
ce09ee19
AW
90 (const 1) (call return 1)
91 (label ,l2) (const 2) (call return 1))
92 (eq? l1 l2))
93
8a4ca0ea 94 (assert-tree-il->glil
0e4b7818
AW
95 (begin (if (toplevel foo) (const 1) (const 2)) (const #f))
96 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (branch br-if-not ,l1) (branch br ,l2)
ce09ee19
AW
97 (label ,l3) (label ,l4) (const #f) (call return 1))
98 (eq? l1 l3) (eq? l2 l4))
99
8a4ca0ea 100 (assert-tree-il->glil
0e4b7818
AW
101 (apply (primitive null?) (if (toplevel foo) (const 1) (const 2)))
102 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (branch br-if-not ,l1)
ce09ee19
AW
103 (const 1) (branch br ,l2)
104 (label ,l3) (const 2) (label ,l4)
105 (call null? 1) (call return 1))
106 (eq? l1 l3) (eq? l2 l4)))
107
108(with-test-prefix "primitive-ref"
109 (assert-tree-il->glil
110 (primitive +)
8a4ca0ea 111 (program () (std-prelude 0 0 #f) (label _) (toplevel ref +) (call return 1)))
ce09ee19
AW
112
113 (assert-tree-il->glil
114 (begin (primitive +) (const #f))
8a4ca0ea 115 (program () (std-prelude 0 0 #f) (label _) (const #f) (call return 1)))
ce09ee19
AW
116
117 (assert-tree-il->glil
118 (apply (primitive null?) (primitive +))
8a4ca0ea 119 (program () (std-prelude 0 0 #f) (label _) (toplevel ref +) (call null? 1)
ce09ee19
AW
120 (call return 1))))
121
122(with-test-prefix "lexical refs"
123 (assert-tree-il->glil
124 (let (x) (y) ((const 1)) (lexical x y))
8a4ca0ea 125 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
126 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
127 (lexical #t #f ref 0) (call return 1)
ce09ee19
AW
128 (unbind)))
129
130 (assert-tree-il->glil
131 (let (x) (y) ((const 1)) (begin (lexical x y) (const #f)))
8a4ca0ea 132 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3 133 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
ce09ee19
AW
134 (const #f) (call return 1)
135 (unbind)))
136
137 (assert-tree-il->glil
138 (let (x) (y) ((const 1)) (apply (primitive null?) (lexical x y)))
8a4ca0ea 139 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
140 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
141 (lexical #t #f ref 0) (call null? 1) (call return 1)
ce09ee19
AW
142 (unbind))))
143
144(with-test-prefix "lexical sets"
145 (assert-tree-il->glil
aaae0d5a
AW
146 ;; unreferenced sets may be optimized away -- make sure they are ref'd
147 (let (x) (y) ((const 1))
148 (set! (lexical x y) (apply (primitive 1+) (lexical x y))))
8a4ca0ea 149 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3 150 (const 1) (bind (x #t 0)) (lexical #t #t box 0)
aaae0d5a
AW
151 (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0)
152 (void) (call return 1)
ce09ee19
AW
153 (unbind)))
154
155 (assert-tree-il->glil
aaae0d5a
AW
156 (let (x) (y) ((const 1))
157 (begin (set! (lexical x y) (apply (primitive 1+) (lexical x y)))
158 (lexical x y)))
8a4ca0ea 159 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3 160 (const 1) (bind (x #t 0)) (lexical #t #t box 0)
aaae0d5a
AW
161 (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0)
162 (lexical #t #t ref 0) (call return 1)
ce09ee19
AW
163 (unbind)))
164
165 (assert-tree-il->glil
166 (let (x) (y) ((const 1))
aaae0d5a
AW
167 (apply (primitive null?)
168 (set! (lexical x y) (apply (primitive 1+) (lexical x y)))))
8a4ca0ea 169 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3 170 (const 1) (bind (x #t 0)) (lexical #t #t box 0)
aaae0d5a
AW
171 (lexical #t #t ref 0) (call add1 1) (lexical #t #t set 0) (void)
172 (call null? 1) (call return 1)
ce09ee19
AW
173 (unbind))))
174
175(with-test-prefix "module refs"
176 (assert-tree-il->glil
177 (@ (foo) bar)
8a4ca0ea 178 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
179 (module public ref (foo) bar)
180 (call return 1)))
181
182 (assert-tree-il->glil
183 (begin (@ (foo) bar) (const #f))
8a4ca0ea 184 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
185 (module public ref (foo) bar) (call drop 1)
186 (const #f) (call return 1)))
187
188 (assert-tree-il->glil
189 (apply (primitive null?) (@ (foo) bar))
8a4ca0ea 190 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
191 (module public ref (foo) bar)
192 (call null? 1) (call return 1)))
193
194 (assert-tree-il->glil
195 (@@ (foo) bar)
8a4ca0ea 196 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
197 (module private ref (foo) bar)
198 (call return 1)))
199
200 (assert-tree-il->glil
201 (begin (@@ (foo) bar) (const #f))
8a4ca0ea 202 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
203 (module private ref (foo) bar) (call drop 1)
204 (const #f) (call return 1)))
205
206 (assert-tree-il->glil
207 (apply (primitive null?) (@@ (foo) bar))
8a4ca0ea 208 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
209 (module private ref (foo) bar)
210 (call null? 1) (call return 1))))
211
212(with-test-prefix "module sets"
213 (assert-tree-il->glil
214 (set! (@ (foo) bar) (const 2))
8a4ca0ea 215 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
216 (const 2) (module public set (foo) bar)
217 (void) (call return 1)))
218
219 (assert-tree-il->glil
220 (begin (set! (@ (foo) bar) (const 2)) (const #f))
8a4ca0ea 221 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
222 (const 2) (module public set (foo) bar)
223 (const #f) (call return 1)))
224
225 (assert-tree-il->glil
226 (apply (primitive null?) (set! (@ (foo) bar) (const 2)))
8a4ca0ea 227 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
228 (const 2) (module public set (foo) bar)
229 (void) (call null? 1) (call return 1)))
230
231 (assert-tree-il->glil
232 (set! (@@ (foo) bar) (const 2))
8a4ca0ea 233 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
234 (const 2) (module private set (foo) bar)
235 (void) (call return 1)))
236
237 (assert-tree-il->glil
238 (begin (set! (@@ (foo) bar) (const 2)) (const #f))
8a4ca0ea 239 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
240 (const 2) (module private set (foo) bar)
241 (const #f) (call return 1)))
242
243 (assert-tree-il->glil
244 (apply (primitive null?) (set! (@@ (foo) bar) (const 2)))
8a4ca0ea 245 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
246 (const 2) (module private set (foo) bar)
247 (void) (call null? 1) (call return 1))))
248
249(with-test-prefix "toplevel refs"
250 (assert-tree-il->glil
251 (toplevel bar)
8a4ca0ea 252 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
253 (toplevel ref bar)
254 (call return 1)))
255
256 (assert-tree-il->glil
257 (begin (toplevel bar) (const #f))
8a4ca0ea 258 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
259 (toplevel ref bar) (call drop 1)
260 (const #f) (call return 1)))
261
262 (assert-tree-il->glil
263 (apply (primitive null?) (toplevel bar))
8a4ca0ea 264 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
265 (toplevel ref bar)
266 (call null? 1) (call return 1))))
267
268(with-test-prefix "toplevel sets"
269 (assert-tree-il->glil
270 (set! (toplevel bar) (const 2))
8a4ca0ea 271 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
272 (const 2) (toplevel set bar)
273 (void) (call return 1)))
274
275 (assert-tree-il->glil
276 (begin (set! (toplevel bar) (const 2)) (const #f))
8a4ca0ea 277 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
278 (const 2) (toplevel set bar)
279 (const #f) (call return 1)))
280
281 (assert-tree-il->glil
282 (apply (primitive null?) (set! (toplevel bar) (const 2)))
8a4ca0ea 283 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
284 (const 2) (toplevel set bar)
285 (void) (call null? 1) (call return 1))))
286
287(with-test-prefix "toplevel defines"
288 (assert-tree-il->glil
289 (define bar (const 2))
8a4ca0ea 290 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
291 (const 2) (toplevel define bar)
292 (void) (call return 1)))
293
294 (assert-tree-il->glil
295 (begin (define bar (const 2)) (const #f))
8a4ca0ea 296 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
297 (const 2) (toplevel define bar)
298 (const #f) (call return 1)))
299
300 (assert-tree-il->glil
301 (apply (primitive null?) (define bar (const 2)))
8a4ca0ea 302 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
303 (const 2) (toplevel define bar)
304 (void) (call null? 1) (call return 1))))
305
306(with-test-prefix "constants"
307 (assert-tree-il->glil
308 (const 2)
8a4ca0ea 309 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
310 (const 2) (call return 1)))
311
312 (assert-tree-il->glil
313 (begin (const 2) (const #f))
8a4ca0ea 314 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
315 (const #f) (call return 1)))
316
317 (assert-tree-il->glil
318 (apply (primitive null?) (const 2))
8a4ca0ea 319 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
320 (const 2) (call null? 1) (call return 1))))
321
60d4b224
AW
322(with-test-prefix "letrec"
323 ;; simple bindings -> let
324 (assert-tree-il->glil
325 (letrec (x y) (x1 y1) ((const 10) (const 20))
326 (apply (toplevel foo) (lexical x x1) (lexical y y1)))
327 (program () (std-prelude 0 2 #f) (label _)
328 (const 10) (const 20)
329 (bind (x #f 0) (y #f 1))
330 (lexical #t #f set 1) (lexical #t #f set 0)
331 (toplevel ref foo)
332 (lexical #t #f ref 0) (lexical #t #f ref 1)
333 (call tail-call 2)
334 (unbind)))
335
336 ;; complex bindings -> box and set! within let
337 (assert-tree-il->glil
338 (letrec (x y) (x1 y1) ((apply (toplevel foo)) (apply (toplevel bar)))
339 (apply (primitive +) (lexical x x1) (lexical y y1)))
340 (program () (std-prelude 0 4 #f) (label _)
341 (void) (void) ;; what are these?
342 (bind (x #t 0) (y #t 1))
343 (lexical #t #t box 1) (lexical #t #t box 0)
344 (call new-frame 0) (toplevel ref foo) (call call 0)
345 (call new-frame 0) (toplevel ref bar) (call call 0)
346 (bind (x #f 2) (y #f 3)) (lexical #t #f set 3) (lexical #t #f set 2)
347 (lexical #t #f ref 2) (lexical #t #t set 0)
348 (lexical #t #f ref 3) (lexical #t #t set 1) (unbind)
349 (lexical #t #t ref 0) (lexical #t #t ref 1)
350 (call add 2) (call return 1) (unbind)))
351
352 ;; complex bindings in letrec* -> box and set! in order
353 (assert-tree-il->glil
354 (letrec* (x y) (x1 y1) ((apply (toplevel foo)) (apply (toplevel bar)))
355 (apply (primitive +) (lexical x x1) (lexical y y1)))
356 (program () (std-prelude 0 2 #f) (label _)
357 (void) (void) ;; what are these?
358 (bind (x #t 0) (y #t 1))
359 (lexical #t #t box 1) (lexical #t #t box 0)
360 (call new-frame 0) (toplevel ref foo) (call call 0)
361 (lexical #t #t set 0)
362 (call new-frame 0) (toplevel ref bar) (call call 0)
363 (lexical #t #t set 1)
364 (lexical #t #t ref 0)
365 (lexical #t #t ref 1)
65ea26c5
LC
366 (call add 2) (call return 1) (unbind)))
367
368 ;; simple bindings in letrec* -> equivalent to letrec
369 (assert-tree-il->glil
370 (letrec* (x y) (xx yy) ((const 1) (const 2))
371 (lexical y yy))
372 (program () (std-prelude 0 1 #f) (label _)
373 (const 2)
374 (bind (y #f 0)) ;; X is removed, and Y is unboxed
375 (lexical #t #f set 0)
376 (lexical #t #f ref 0)
377 (call return 1) (unbind))))
60d4b224 378
ce09ee19
AW
379(with-test-prefix "lambda"
380 (assert-tree-il->glil
8a4ca0ea 381 (lambda ()
1e2a8edb 382 (lambda-case (((x) #f #f #f () (y)) (const 2)) #f))
8a4ca0ea 383 (program () (std-prelude 0 0 #f) (label _)
258344b4 384 (program () (std-prelude 1 1 #f)
8a4ca0ea
AW
385 (bind (x #f 0)) (label _)
386 (const 2) (call return 1) (unbind))
ce09ee19
AW
387 (call return 1)))
388
389 (assert-tree-il->glil
8a4ca0ea 390 (lambda ()
1e2a8edb 391 (lambda-case (((x y) #f #f #f () (x1 y1))
8a4ca0ea
AW
392 (const 2))
393 #f))
394 (program () (std-prelude 0 0 #f) (label _)
258344b4 395 (program () (std-prelude 2 2 #f)
8a4ca0ea
AW
396 (bind (x #f 0) (y #f 1)) (label _)
397 (const 2) (call return 1)
398 (unbind))
ce09ee19
AW
399 (call return 1)))
400
401 (assert-tree-il->glil
8a4ca0ea 402 (lambda ()
1e2a8edb 403 (lambda-case ((() #f x #f () (y)) (const 2))
8a4ca0ea
AW
404 #f))
405 (program () (std-prelude 0 0 #f) (label _)
899d37a6 406 (program () (opt-prelude 0 0 0 1 #f)
8a4ca0ea
AW
407 (bind (x #f 0)) (label _)
408 (const 2) (call return 1)
409 (unbind))
ce09ee19
AW
410 (call return 1)))
411
412 (assert-tree-il->glil
8a4ca0ea 413 (lambda ()
1e2a8edb 414 (lambda-case (((x) #f x1 #f () (y y1)) (const 2))
8a4ca0ea
AW
415 #f))
416 (program () (std-prelude 0 0 #f) (label _)
899d37a6 417 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
418 (bind (x #f 0) (x1 #f 1)) (label _)
419 (const 2) (call return 1)
420 (unbind))
ce09ee19
AW
421 (call return 1)))
422
423 (assert-tree-il->glil
8a4ca0ea 424 (lambda ()
1e2a8edb 425 (lambda-case (((x) #f x1 #f () (y y1)) (lexical x y))
8a4ca0ea
AW
426 #f))
427 (program () (std-prelude 0 0 #f) (label _)
899d37a6 428 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
429 (bind (x #f 0) (x1 #f 1)) (label _)
430 (lexical #t #f ref 0) (call return 1)
431 (unbind))
ce09ee19
AW
432 (call return 1)))
433
434 (assert-tree-il->glil
8a4ca0ea 435 (lambda ()
1e2a8edb 436 (lambda-case (((x) #f x1 #f () (y y1)) (lexical x1 y1))
8a4ca0ea
AW
437 #f))
438 (program () (std-prelude 0 0 #f) (label _)
899d37a6 439 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
440 (bind (x #f 0) (x1 #f 1)) (label _)
441 (lexical #t #f ref 1) (call return 1)
442 (unbind))
a1a482e0
AW
443 (call return 1)))
444
445 (assert-tree-il->glil
8a4ca0ea 446 (lambda ()
1e2a8edb 447 (lambda-case (((x) #f #f #f () (x1))
8a4ca0ea 448 (lambda ()
1e2a8edb 449 (lambda-case (((y) #f #f #f () (y1))
8a4ca0ea
AW
450 (lexical x x1))
451 #f)))
452 #f))
453 (program () (std-prelude 0 0 #f) (label _)
454 (program () (std-prelude 1 1 #f)
455 (bind (x #f 0)) (label _)
258344b4 456 (program () (std-prelude 1 1 #f)
8a4ca0ea
AW
457 (bind (y #f 0)) (label _)
458 (lexical #f #f ref 0) (call return 1)
459 (unbind))
66d3e9a3 460 (lexical #t #f ref 0)
6f16379e 461 (call make-closure 1)
8a4ca0ea
AW
462 (call return 1)
463 (unbind))
ce09ee19
AW
464 (call return 1))))
465
466(with-test-prefix "sequence"
467 (assert-tree-il->glil
468 (begin (begin (const 2) (const #f)) (const #t))
8a4ca0ea 469 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
470 (const #t) (call return 1)))
471
472 (assert-tree-il->glil
473 (apply (primitive null?) (begin (const #f) (const 2)))
8a4ca0ea 474 (program () (std-prelude 0 0 #f) (label _)
ce09ee19 475 (const 2) (call null? 1) (call return 1))))
5af166bd
AW
476
477;; FIXME: binding info for or-hacked locals might bork the disassembler,
478;; and could be tightened in any case
479(with-test-prefix "the or hack"
8a4ca0ea 480 (assert-tree-il->glil
5af166bd
AW
481 (let (x) (y) ((const 1))
482 (if (lexical x y)
483 (lexical x y)
484 (let (a) (b) ((const 2))
485 (lexical a b))))
8a4ca0ea 486 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
487 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
488 (lexical #t #f ref 0) (branch br-if-not ,l1)
489 (lexical #t #f ref 0) (call return 1)
5af166bd 490 (label ,l2)
66d3e9a3
AW
491 (const 2) (bind (a #f 0)) (lexical #t #f set 0)
492 (lexical #t #f ref 0) (call return 1)
5af166bd
AW
493 (unbind)
494 (unbind))
495 (eq? l1 l2))
496
aaae0d5a 497 ;; second bound var is unreferenced
8a4ca0ea 498 (assert-tree-il->glil
5af166bd
AW
499 (let (x) (y) ((const 1))
500 (if (lexical x y)
501 (lexical x y)
502 (let (a) (b) ((const 2))
503 (lexical x y))))
8a4ca0ea 504 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
505 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
506 (lexical #t #f ref 0) (branch br-if-not ,l1)
507 (lexical #t #f ref 0) (call return 1)
5af166bd 508 (label ,l2)
66d3e9a3 509 (lexical #t #f ref 0) (call return 1)
5af166bd
AW
510 (unbind))
511 (eq? l1 l2)))
0f423f20
AW
512
513(with-test-prefix "apply"
514 (assert-tree-il->glil
515 (apply (primitive @apply) (toplevel foo) (toplevel bar))
a5bbb22e 516 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (toplevel ref bar) (call tail-apply 2)))
8a4ca0ea 517 (assert-tree-il->glil
0f423f20 518 (begin (apply (primitive @apply) (toplevel foo) (toplevel bar)) (void))
8a4ca0ea 519 (program () (std-prelude 0 0 #f) (label _)
b7946e9e 520 (call new-frame 0) (toplevel ref apply) (toplevel ref foo) (toplevel ref bar) (mv-call 2 ,l1)
05c51bcf 521 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind 0 #f)
0f423f20
AW
522 (label ,l4)
523 (void) (call return 1))
524 (and (eq? l1 l3) (eq? l2 l4)))
525 (assert-tree-il->glil
526 (apply (toplevel foo) (apply (toplevel @apply) (toplevel bar) (toplevel baz)))
8a4ca0ea 527 (program () (std-prelude 0 0 #f) (label _)
0f423f20 528 (toplevel ref foo)
b7946e9e 529 (call new-frame 0) (toplevel ref bar) (toplevel ref baz) (call apply 2)
a5bbb22e 530 (call tail-call 1))))
0f423f20
AW
531
532(with-test-prefix "call/cc"
533 (assert-tree-il->glil
534 (apply (primitive @call-with-current-continuation) (toplevel foo))
a5bbb22e 535 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (call tail-call/cc 1)))
8a4ca0ea 536 (assert-tree-il->glil
0f423f20 537 (begin (apply (primitive @call-with-current-continuation) (toplevel foo)) (void))
8a4ca0ea 538 (program () (std-prelude 0 0 #f) (label _)
b7946e9e 539 (call new-frame 0) (toplevel ref call-with-current-continuation) (toplevel ref foo) (mv-call 1 ,l1)
05c51bcf 540 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind 0 #f)
0f423f20
AW
541 (label ,l4)
542 (void) (call return 1))
543 (and (eq? l1 l3) (eq? l2 l4)))
544 (assert-tree-il->glil
545 (apply (toplevel foo)
546 (apply (toplevel @call-with-current-continuation) (toplevel bar)))
8a4ca0ea 547 (program () (std-prelude 0 0 #f) (label _)
0f423f20
AW
548 (toplevel ref foo)
549 (toplevel ref bar) (call call/cc 1)
a5bbb22e 550 (call tail-call 1))))
0f423f20 551
f4aa0f10
LC
552\f
553(with-test-prefix "tree-il-fold"
554
555 (pass-if "empty tree"
556 (let ((leaf? #f) (up? #f) (down? #f) (mark (list 'mark)))
557 (and (eq? mark
558 (tree-il-fold (lambda (x y) (set! leaf? #t) y)
559 (lambda (x y) (set! down? #t) y)
560 (lambda (x y) (set! up? #t) y)
561 mark
562 '()))
563 (not leaf?)
564 (not up?)
565 (not down?))))
566
567 (pass-if "lambda and application"
568 (let* ((leaves '()) (ups '()) (downs '())
569 (result (tree-il-fold (lambda (x y)
570 (set! leaves (cons x leaves))
571 (1+ y))
572 (lambda (x y)
573 (set! downs (cons x downs))
574 (1+ y))
575 (lambda (x y)
576 (set! ups (cons x ups))
577 (1+ y))
578 0
579 (parse-tree-il
8a4ca0ea
AW
580 '(lambda ()
581 (lambda-case
1e2a8edb 582 (((x y) #f #f #f () (x1 y1))
8a4ca0ea
AW
583 (apply (toplevel +)
584 (lexical x x1)
585 (lexical y y1)))
586 #f))))))
f4aa0f10
LC
587 (and (equal? (map strip-source leaves)
588 (list (make-lexical-ref #f 'y 'y1)
589 (make-lexical-ref #f 'x 'x1)
590 (make-toplevel-ref #f '+)))
8a4ca0ea 591 (= (length downs) 3)
f4aa0f10
LC
592 (equal? (reverse (map strip-source ups))
593 (map strip-source downs))))))
4b856371
LC
594
595\f
596;;;
597;;; Warnings.
598;;;
599
600;; Make sure we get English messages.
601(setlocale LC_ALL "C")
602
603(define (call-with-warnings thunk)
604 (let ((port (open-output-string)))
a4060f67
LC
605 (with-fluids ((*current-warning-port* port)
606 (*current-warning-prefix* ""))
607 (thunk))
4b856371
LC
608 (let ((warnings (get-output-string port)))
609 (string-tokenize warnings
610 (char-set-complement (char-set #\newline))))))
611
612(define %opts-w-unused
613 '(#:warnings (unused-variable)))
614
bcae9a98
LC
615(define %opts-w-unused-toplevel
616 '(#:warnings (unused-toplevel)))
617
f67ddf9d
LC
618(define %opts-w-unbound
619 '(#:warnings (unbound-variable)))
4b856371 620
ae03cf1f
LC
621(define %opts-w-arity
622 '(#:warnings (arity-mismatch)))
623
75365375
LC
624(define %opts-w-format
625 '(#:warnings (format)))
626
ae03cf1f 627
4b856371
LC
628(with-test-prefix "warnings"
629
630 (pass-if "unknown warning type"
631 (let ((w (call-with-warnings
632 (lambda ()
633 (compile #t #:opts '(#:warnings (does-not-exist)))))))
634 (and (= (length w) 1)
635 (number? (string-contains (car w) "unknown warning")))))
636
637 (with-test-prefix "unused-variable"
638
639 (pass-if "quiet"
640 (null? (call-with-warnings
641 (lambda ()
642 (compile '(lambda (x y) (+ x y))
643 #:opts %opts-w-unused)))))
644
645 (pass-if "let/unused"
646 (let ((w (call-with-warnings
647 (lambda ()
648 (compile '(lambda (x)
649 (let ((y (+ x 2)))
650 x))
651 #:opts %opts-w-unused)))))
652 (and (= (length w) 1)
653 (number? (string-contains (car w) "unused variable `y'")))))
654
655 (pass-if "shadowed variable"
656 (let ((w (call-with-warnings
657 (lambda ()
658 (compile '(lambda (x)
659 (let ((y x))
660 (let ((y (+ x 2)))
661 (+ x y))))
662 #:opts %opts-w-unused)))))
663 (and (= (length w) 1)
664 (number? (string-contains (car w) "unused variable `y'")))))
665
666 (pass-if "letrec"
667 (null? (call-with-warnings
668 (lambda ()
669 (compile '(lambda ()
670 (letrec ((x (lambda () (y)))
671 (y (lambda () (x))))
672 y))
673 #:opts %opts-w-unused)))))
674
675 (pass-if "unused argument"
676 ;; Unused arguments should not be reported.
677 (null? (call-with-warnings
678 (lambda ()
679 (compile '(lambda (x y z) #t)
3a1a883b
LC
680 #:opts %opts-w-unused)))))
681
682 (pass-if "special variable names"
683 (null? (call-with-warnings
684 (lambda ()
685 (compile '(lambda ()
686 (let ((_ 'underscore)
687 (#{gensym name}# 'ignore-me))
688 #t))
689 #:to 'assembly
f67ddf9d
LC
690 #:opts %opts-w-unused))))))
691
bcae9a98
LC
692 (with-test-prefix "unused-toplevel"
693
694 (pass-if "used after definition"
695 (null? (call-with-warnings
696 (lambda ()
697 (let ((in (open-input-string
698 "(define foo 2) foo")))
699 (read-and-compile in
700 #:to 'assembly
701 #:opts %opts-w-unused-toplevel))))))
702
703 (pass-if "used before definition"
704 (null? (call-with-warnings
705 (lambda ()
706 (let ((in (open-input-string
707 "(define (bar) foo) (define foo 2) (bar)")))
708 (read-and-compile in
709 #:to 'assembly
710 #:opts %opts-w-unused-toplevel))))))
711
712 (pass-if "unused but public"
713 (let ((in (open-input-string
714 "(define-module (test-suite tree-il x) #:export (bar))
715 (define (bar) #t)")))
716 (null? (call-with-warnings
717 (lambda ()
718 (read-and-compile in
719 #:to 'assembly
720 #:opts %opts-w-unused-toplevel))))))
721
722 (pass-if "unused but public (more)"
723 (let ((in (open-input-string
724 "(define-module (test-suite tree-il x) #:export (bar))
725 (define (bar) (baz))
726 (define (baz) (foo))
727 (define (foo) #t)")))
728 (null? (call-with-warnings
729 (lambda ()
730 (read-and-compile in
731 #:to 'assembly
732 #:opts %opts-w-unused-toplevel))))))
733
734 (pass-if "unused but define-public"
bcae9a98
LC
735 (null? (call-with-warnings
736 (lambda ()
737 (compile '(define-public foo 2)
738 #:to 'assembly
739 #:opts %opts-w-unused-toplevel)))))
740
741 (pass-if "used by macro"
742 ;; FIXME: See comment about macros at `unused-toplevel-analysis'.
743 (throw 'unresolved)
744
745 (null? (call-with-warnings
746 (lambda ()
747 (let ((in (open-input-string
748 "(define (bar) 'foo)
749 (define-syntax baz
750 (syntax-rules () ((_) (bar))))")))
751 (read-and-compile in
752 #:to 'assembly
753 #:opts %opts-w-unused-toplevel))))))
754
755 (pass-if "unused"
756 (let ((w (call-with-warnings
757 (lambda ()
758 (compile '(define foo 2)
759 #:to 'assembly
760 #:opts %opts-w-unused-toplevel)))))
761 (and (= (length w) 1)
762 (number? (string-contains (car w)
763 (format #f "top-level variable `~A'"
764 'foo))))))
765
766 (pass-if "unused recursive"
767 (let ((w (call-with-warnings
768 (lambda ()
769 (compile '(define (foo) (foo))
770 #:to 'assembly
771 #:opts %opts-w-unused-toplevel)))))
772 (and (= (length w) 1)
773 (number? (string-contains (car w)
774 (format #f "top-level variable `~A'"
775 'foo))))))
776
777 (pass-if "unused mutually recursive"
778 (let* ((in (open-input-string
779 "(define (foo) (bar)) (define (bar) (foo))"))
780 (w (call-with-warnings
781 (lambda ()
782 (read-and-compile in
783 #:to 'assembly
784 #:opts %opts-w-unused-toplevel)))))
785 (and (= (length w) 2)
786 (number? (string-contains (car w)
787 (format #f "top-level variable `~A'"
788 'foo)))
789 (number? (string-contains (cadr w)
790 (format #f "top-level variable `~A'"
3a1a883b
LC
791 'bar))))))
792
793 (pass-if "special variable names"
794 (null? (call-with-warnings
795 (lambda ()
796 (compile '(define #{gensym name}# 'ignore-me)
797 #:to 'assembly
798 #:opts %opts-w-unused-toplevel))))))
bcae9a98 799
f67ddf9d
LC
800 (with-test-prefix "unbound variable"
801
802 (pass-if "quiet"
803 (null? (call-with-warnings
804 (lambda ()
805 (compile '+ #:opts %opts-w-unbound)))))
806
807 (pass-if "ref"
808 (let* ((v (gensym))
809 (w (call-with-warnings
810 (lambda ()
811 (compile v
812 #:to 'assembly
813 #:opts %opts-w-unbound)))))
814 (and (= (length w) 1)
815 (number? (string-contains (car w)
816 (format #f "unbound variable `~A'"
817 v))))))
818
819 (pass-if "set!"
820 (let* ((v (gensym))
821 (w (call-with-warnings
822 (lambda ()
823 (compile `(set! ,v 7)
824 #:to 'assembly
825 #:opts %opts-w-unbound)))))
826 (and (= (length w) 1)
827 (number? (string-contains (car w)
828 (format #f "unbound variable `~A'"
829 v))))))
830
831 (pass-if "module-local top-level is visible"
832 (let ((m (make-module))
833 (v (gensym)))
834 (beautify-user-module! m)
835 (compile `(define ,v 123)
836 #:env m #:opts %opts-w-unbound)
837 (null? (call-with-warnings
838 (lambda ()
839 (compile v
840 #:env m
841 #:to 'assembly
842 #:opts %opts-w-unbound))))))
843
844 (pass-if "module-local top-level is visible after"
845 (let ((m (make-module))
846 (v (gensym)))
847 (beautify-user-module! m)
848 (null? (call-with-warnings
849 (lambda ()
850 (let ((in (open-input-string
851 "(define (f)
852 (set! chbouib 3))
853 (define chbouib 5)")))
b6d2306d
LC
854 (read-and-compile in
855 #:env m
856 #:opts %opts-w-unbound)))))))
857
bd36e901
LC
858 (pass-if "optional arguments are visible"
859 (null? (call-with-warnings
860 (lambda ()
861 (compile '(lambda* (x #:optional y z) (list x y z))
862 #:opts %opts-w-unbound
863 #:to 'assembly)))))
864
865 (pass-if "keyword arguments are visible"
866 (null? (call-with-warnings
867 (lambda ()
868 (compile '(lambda* (x #:key y z) (list x y z))
869 #:opts %opts-w-unbound
870 #:to 'assembly)))))
871
b6d2306d
LC
872 (pass-if "GOOPS definitions are visible"
873 (let ((m (make-module))
874 (v (gensym)))
875 (beautify-user-module! m)
876 (module-use! m (resolve-interface '(oop goops)))
877 (null? (call-with-warnings
878 (lambda ()
879 (let ((in (open-input-string
880 "(define-class <foo> ()
881 (bar #:getter foo-bar))
882 (define z (foo-bar (make <foo>)))")))
f67ddf9d
LC
883 (read-and-compile in
884 #:env m
ae03cf1f
LC
885 #:opts %opts-w-unbound))))))))
886
887 (with-test-prefix "arity mismatch"
888
889 (pass-if "quiet"
890 (null? (call-with-warnings
891 (lambda ()
892 (compile '(cons 'a 'b) #:opts %opts-w-arity)))))
893
894 (pass-if "direct application"
895 (let ((w (call-with-warnings
896 (lambda ()
897 (compile '((lambda (x y) (or x y)) 1 2 3 4 5)
898 #:opts %opts-w-arity
899 #:to 'assembly)))))
900 (and (= (length w) 1)
901 (number? (string-contains (car w)
902 "wrong number of arguments to")))))
903 (pass-if "local"
904 (let ((w (call-with-warnings
905 (lambda ()
906 (compile '(let ((f (lambda (x y) (+ x y))))
907 (f 2))
908 #:opts %opts-w-arity
909 #:to 'assembly)))))
910 (and (= (length w) 1)
911 (number? (string-contains (car w)
912 "wrong number of arguments to")))))
913
914 (pass-if "global"
915 (let ((w (call-with-warnings
916 (lambda ()
917 (compile '(cons 1 2 3 4)
918 #:opts %opts-w-arity
919 #:to 'assembly)))))
920 (and (= (length w) 1)
921 (number? (string-contains (car w)
922 "wrong number of arguments to")))))
923
924 (pass-if "alias to global"
925 (let ((w (call-with-warnings
926 (lambda ()
927 (compile '(let ((f cons)) (f 1 2 3 4))
928 #:opts %opts-w-arity
929 #:to 'assembly)))))
930 (and (= (length w) 1)
931 (number? (string-contains (car w)
932 "wrong number of arguments to")))))
933
934 (pass-if "alias to lexical to global"
935 (let ((w (call-with-warnings
936 (lambda ()
937 (compile '(let ((f number?))
938 (let ((g f))
939 (f 1 2 3 4)))
940 #:opts %opts-w-arity
941 #:to 'assembly)))))
942 (and (= (length w) 1)
943 (number? (string-contains (car w)
944 "wrong number of arguments to")))))
945
946 (pass-if "alias to lexical"
947 (let ((w (call-with-warnings
948 (lambda ()
949 (compile '(let ((f (lambda (x y z) (+ x y z))))
950 (let ((g f))
951 (g 1)))
952 #:opts %opts-w-arity
953 #:to 'assembly)))))
954 (and (= (length w) 1)
955 (number? (string-contains (car w)
956 "wrong number of arguments to")))))
957
958 (pass-if "letrec"
959 (let ((w (call-with-warnings
960 (lambda ()
961 (compile '(letrec ((odd? (lambda (x) (even? (1- x))))
962 (even? (lambda (x)
963 (or (= 0 x)
964 (odd?)))))
965 (odd? 1))
966 #:opts %opts-w-arity
967 #:to 'assembly)))))
968 (and (= (length w) 1)
969 (number? (string-contains (car w)
970 "wrong number of arguments to")))))
971
99480e11
LC
972 (pass-if "case-lambda"
973 (null? (call-with-warnings
974 (lambda ()
975 (compile '(let ((f (case-lambda
976 ((x) 1)
977 ((x y) 2)
978 ((x y z) 3))))
979 (list (f 1)
980 (f 1 2)
981 (f 1 2 3)))
982 #:opts %opts-w-arity
983 #:to 'assembly)))))
984
985 (pass-if "case-lambda with wrong number of arguments"
986 (let ((w (call-with-warnings
987 (lambda ()
988 (compile '(let ((f (case-lambda
989 ((x) 1)
990 ((x y) 2))))
991 (f 1 2 3))
992 #:opts %opts-w-arity
993 #:to 'assembly)))))
994 (and (= (length w) 1)
995 (number? (string-contains (car w)
996 "wrong number of arguments to")))))
997
998 (pass-if "case-lambda*"
999 (null? (call-with-warnings
1000 (lambda ()
1001 (compile '(let ((f (case-lambda*
1002 ((x #:optional y) 1)
1003 ((x #:key y) 2)
1004 ((x y #:key z) 3))))
1005 (list (f 1)
1006 (f 1 2)
1007 (f #:y 2)
1008 (f 1 2 #:z 3)))
1009 #:opts %opts-w-arity
1010 #:to 'assembly)))))
1011
1012 (pass-if "case-lambda* with wrong arguments"
1013 (let ((w (call-with-warnings
1014 (lambda ()
1015 (compile '(let ((f (case-lambda*
1016 ((x #:optional y) 1)
1017 ((x #:key y) 2)
1018 ((x y #:key z) 3))))
1019 (list (f)
1020 (f 1 #:z 3)))
1021 #:opts %opts-w-arity
1022 #:to 'assembly)))))
1023 (and (= (length w) 2)
1024 (null? (filter (lambda (w)
1025 (not
1026 (number?
1027 (string-contains
1028 w "wrong number of arguments to"))))
1029 w)))))
1030
ae03cf1f
LC
1031 (pass-if "local toplevel-defines"
1032 (let ((w (call-with-warnings
1033 (lambda ()
1034 (let ((in (open-input-string "
1035 (define (g x) (f x))
1036 (define (f) 1)")))
1037 (read-and-compile in
1038 #:opts %opts-w-arity
1039 #:to 'assembly))))))
1040 (and (= (length w) 1)
1041 (number? (string-contains (car w)
1042 "wrong number of arguments to")))))
1043
1044 (pass-if "global toplevel alias"
1045 (let ((w (call-with-warnings
1046 (lambda ()
1047 (let ((in (open-input-string "
1048 (define f cons)
1049 (define (g) (f))")))
1050 (read-and-compile in
1051 #:opts %opts-w-arity
1052 #:to 'assembly))))))
1053 (and (= (length w) 1)
1054 (number? (string-contains (car w)
1055 "wrong number of arguments to")))))
1056
1057 (pass-if "local toplevel overrides global"
1058 (null? (call-with-warnings
1059 (lambda ()
1060 (let ((in (open-input-string "
1061 (define (cons) 0)
1062 (define (foo x) (cons))")))
1063 (read-and-compile in
1064 #:opts %opts-w-arity
af5ed549
LC
1065 #:to 'assembly))))))
1066
1067 (pass-if "keyword not passed and quiet"
1068 (null? (call-with-warnings
1069 (lambda ()
1070 (compile '(let ((f (lambda* (x #:key y) y)))
1071 (f 2))
1072 #:opts %opts-w-arity
1073 #:to 'assembly)))))
1074
1075 (pass-if "keyword passed and quiet"
1076 (null? (call-with-warnings
1077 (lambda ()
1078 (compile '(let ((f (lambda* (x #:key y) y)))
1079 (f 2 #:y 3))
1080 #:opts %opts-w-arity
1081 #:to 'assembly)))))
1082
1083 (pass-if "keyword passed to global and quiet"
1084 (null? (call-with-warnings
1085 (lambda ()
1086 (let ((in (open-input-string "
1087 (use-modules (system base compile))
1088 (compile '(+ 2 3) #:env (current-module))")))
1089 (read-and-compile in
1090 #:opts %opts-w-arity
1091 #:to 'assembly))))))
1092
1093 (pass-if "extra keyword"
1094 (let ((w (call-with-warnings
1095 (lambda ()
1096 (compile '(let ((f (lambda* (x #:key y) y)))
1097 (f 2 #:Z 3))
1098 #:opts %opts-w-arity
1099 #:to 'assembly)))))
1100 (and (= (length w) 1)
1101 (number? (string-contains (car w)
1102 "wrong number of arguments to")))))
1103
1104 (pass-if "extra keywords allowed"
1105 (null? (call-with-warnings
1106 (lambda ()
1107 (compile '(let ((f (lambda* (x #:key y #:allow-other-keys)
1108 y)))
1109 (f 2 #:Z 3))
1110 #:opts %opts-w-arity
75365375
LC
1111 #:to 'assembly))))))
1112
1113 (with-test-prefix "format"
1114
1115 (pass-if "quiet (no args)"
1116 (null? (call-with-warnings
1117 (lambda ()
1118 (compile '(format #t "hey!")
1119 #:opts %opts-w-format
1120 #:to 'assembly)))))
1121
1122 (pass-if "quiet (1 arg)"
1123 (null? (call-with-warnings
1124 (lambda ()
1125 (compile '(format #t "hey ~A!" "you")
1126 #:opts %opts-w-format
1127 #:to 'assembly)))))
1128
1129 (pass-if "quiet (2 args)"
1130 (null? (call-with-warnings
1131 (lambda ()
1132 (compile '(format #t "~A ~A!" "hello" "world")
1133 #:opts %opts-w-format
1134 #:to 'assembly)))))
1135
60f01304
LC
1136 (pass-if "wrong port arg"
1137 (let ((w (call-with-warnings
1138 (lambda ()
1139 (compile '(format 10 "foo")
1140 #:opts %opts-w-format
1141 #:to 'assembly)))))
1142 (and (= (length w) 1)
1143 (number? (string-contains (car w)
1144 "wrong port argument")))))
1145
1146 (pass-if "non-literal format string"
1147 (let ((w (call-with-warnings
1148 (lambda ()
1149 (compile '(format #f fmt)
1150 #:opts %opts-w-format
1151 #:to 'assembly)))))
1152 (and (= (length w) 1)
1153 (number? (string-contains (car w)
1154 "non-literal format string")))))
1155
1156 (pass-if "wrong format string"
1157 (let ((w (call-with-warnings
1158 (lambda ()
1159 (compile '(format #f 'not-a-string)
1160 #:opts %opts-w-format
1161 #:to 'assembly)))))
1162 (and (= (length w) 1)
1163 (number? (string-contains (car w)
1164 "wrong format string")))))
1165
1166 (pass-if "wrong number of args"
1167 (let ((w (call-with-warnings
1168 (lambda ()
1169 (compile '(format "shbweeb")
1170 #:opts %opts-w-format
1171 #:to 'assembly)))))
1172 (and (= (length w) 1)
1173 (number? (string-contains (car w)
1174 "wrong number of arguments")))))
1175
e0697241 1176 (pass-if "~%, ~~, ~&, ~t, ~_, and ~\\n"
75365375
LC
1177 (null? (call-with-warnings
1178 (lambda ()
e0697241 1179 (compile '(format some-port "~&~3_~~ ~\n~12they~%")
75365375
LC
1180 #:opts %opts-w-format
1181 #:to 'assembly)))))
1182
1183 (pass-if "one missing argument"
1184 (let ((w (call-with-warnings
1185 (lambda ()
1186 (compile '(format some-port "foo ~A~%")
1187 #:opts %opts-w-format
1188 #:to 'assembly)))))
1189 (and (= (length w) 1)
1190 (number? (string-contains (car w)
1191 "expected 1, got 0")))))
1192
1193 (pass-if "two missing arguments"
1194 (let ((w (call-with-warnings
1195 (lambda ()
1196 (compile '(format #f "foo ~10,2f and bar ~S~%")
1197 #:opts %opts-w-format
1198 #:to 'assembly)))))
1199 (and (= (length w) 1)
1200 (number? (string-contains (car w)
1201 "expected 2, got 0")))))
1202
1203 (pass-if "one given, one missing argument"
1204 (let ((w (call-with-warnings
1205 (lambda ()
1206 (compile '(format #t "foo ~A and ~S~%" hey)
1207 #:opts %opts-w-format
1208 #:to 'assembly)))))
1209 (and (= (length w) 1)
1210 (number? (string-contains (car w)
1211 "expected 2, got 1")))))
1212
1213 (pass-if "too many arguments"
1214 (let ((w (call-with-warnings
1215 (lambda ()
1216 (compile '(format #t "foo ~A~%" 1 2)
1217 #:opts %opts-w-format
1218 #:to 'assembly)))))
1219 (and (= (length w) 1)
1220 (number? (string-contains (car w)
1221 "expected 1, got 2")))))
1222
e0697241
LC
1223 (with-test-prefix "conditionals"
1224 (pass-if "literals"
1225 (null? (call-with-warnings
1226 (lambda ()
1227 (compile '(format #f "~A ~[foo~;bar~;baz~;~] ~10,2f"
1228 'a 1 3.14)
1229 #:opts %opts-w-format
1230 #:to 'assembly)))))
1231
1232 (pass-if "literals with selector"
1233 (let ((w (call-with-warnings
1234 (lambda ()
1235 (compile '(format #f "~2[foo~;bar~;baz~;~] ~A"
1236 1 'dont-ignore-me)
1237 #:opts %opts-w-format
1238 #:to 'assembly)))))
1239 (and (= (length w) 1)
1240 (number? (string-contains (car w)
1241 "expected 1, got 2")))))
1242
1243 (pass-if "escapes (exact count)"
1244 (let ((w (call-with-warnings
1245 (lambda ()
1246 (compile '(format #f "~[~a~;~a~]")
1247 #:opts %opts-w-format
1248 #:to 'assembly)))))
1249 (and (= (length w) 1)
1250 (number? (string-contains (car w)
1251 "expected 2, got 0")))))
1252
1253 (pass-if "escapes with selector"
1254 (let ((w (call-with-warnings
1255 (lambda ()
1256 (compile '(format #f "~1[chbouib~;~a~]")
1257 #:opts %opts-w-format
1258 #:to 'assembly)))))
1259 (and (= (length w) 1)
1260 (number? (string-contains (car w)
1261 "expected 1, got 0")))))
1262
1263 (pass-if "escapes, range"
1264 (let ((w (call-with-warnings
1265 (lambda ()
1266 (compile '(format #f "~[chbouib~;~a~;~2*~a~]")
1267 #:opts %opts-w-format
1268 #:to 'assembly)))))
1269 (and (= (length w) 1)
1270 (number? (string-contains (car w)
1271 "expected 1 to 4, got 0")))))
1272
1273 (pass-if "@"
1274 (let ((w (call-with-warnings
1275 (lambda ()
1276 (compile '(format #f "~@[temperature=~d~]")
1277 #:opts %opts-w-format
1278 #:to 'assembly)))))
1279 (and (= (length w) 1)
1280 (number? (string-contains (car w)
1281 "expected 1, got 0")))))
1282
1283 (pass-if "nested"
1284 (let ((w (call-with-warnings
1285 (lambda ()
1286 (compile '(format #f "~:[~[hey~;~a~;~va~]~;~3*~]")
1287 #:opts %opts-w-format
1288 #:to 'assembly)))))
1289 (and (= (length w) 1)
1290 (number? (string-contains (car w)
1291 "expected 2 to 4, got 0")))))
1292
8e6c15a6
LC
1293 (pass-if "unterminated"
1294 (let ((w (call-with-warnings
1295 (lambda ()
1296 (compile '(format #f "~[unterminated")
1297 #:opts %opts-w-format
1298 #:to 'assembly)))))
1299 (and (= (length w) 1)
1300 (number? (string-contains (car w)
1301 "unterminated conditional")))))
1302
1303 (pass-if "unexpected ~;"
1304 (let ((w (call-with-warnings
1305 (lambda ()
1306 (compile '(format #f "foo~;bar")
1307 #:opts %opts-w-format
1308 #:to 'assembly)))))
1309 (and (= (length w) 1)
1310 (number? (string-contains (car w)
1311 "unexpected")))))
1312
1313 (pass-if "unexpected ~]"
1314 (let ((w (call-with-warnings
1315 (lambda ()
1316 (compile '(format #f "foo~]")
1317 #:opts %opts-w-format
1318 #:to 'assembly)))))
1319 (and (= (length w) 1)
1320 (number? (string-contains (car w)
1321 "unexpected"))))))
e0697241
LC
1322
1323 (pass-if "~{...~}"
1324 (null? (call-with-warnings
1325 (lambda ()
1326 (compile '(format #f "~A ~{~S~} ~A"
1327 'hello '("ladies" "and")
1328 'gentlemen)
1329 #:opts %opts-w-format
1330 #:to 'assembly)))))
1331
1332 (pass-if "~{...~}, too many args"
1333 (let ((w (call-with-warnings
1334 (lambda ()
1335 (compile '(format #f "~{~S~}" 1 2 3)
1336 #:opts %opts-w-format
1337 #:to 'assembly)))))
1338 (and (= (length w) 1)
1339 (number? (string-contains (car w)
1340 "expected 1, got 3")))))
1341
1342 (pass-if "~@{...~}"
1343 (null? (call-with-warnings
1344 (lambda ()
1345 (compile '(format #f "~@{~S~}" 1 2 3)
1346 #:opts %opts-w-format
1347 #:to 'assembly)))))
1348
1349 (pass-if "~@{...~}, too few args"
1350 (let ((w (call-with-warnings
1351 (lambda ()
1352 (compile '(format #f "~A ~@{~S~}")
1353 #:opts %opts-w-format
1354 #:to 'assembly)))))
1355 (and (= (length w) 1)
1356 (number? (string-contains (car w)
1357 "expected at least 1, got 0")))))
1358
8e6c15a6
LC
1359 (pass-if "unterminated ~{...~}"
1360 (let ((w (call-with-warnings
1361 (lambda ()
1362 (compile '(format #f "~{")
1363 #:opts %opts-w-format
1364 #:to 'assembly)))))
1365 (and (= (length w) 1)
1366 (number? (string-contains (car w)
1367 "unterminated")))))
1368
e0697241
LC
1369 (pass-if "~(...~)"
1370 (null? (call-with-warnings
1371 (lambda ()
1372 (compile '(format #f "~:@(~A ~A~)" 'foo 'bar)
1373 #:opts %opts-w-format
1374 #:to 'assembly)))))
1375
1376 (pass-if "~v"
1377 (let ((w (call-with-warnings
1378 (lambda ()
1379 (compile '(format #f "~v_foo")
1380 #:opts %opts-w-format
1381 #:to 'assembly)))))
1382 (and (= (length w) 1)
1383 (number? (string-contains (car w)
1384 "expected 1, got 0")))))
1385 (pass-if "~v:@y"
1386 (null? (call-with-warnings
1387 (lambda ()
1388 (compile '(format #f "~v:@y" 1 123)
1389 #:opts %opts-w-format
1390 #:to 'assembly)))))
1391
1392
1393 (pass-if "~*"
1394 (let ((w (call-with-warnings
1395 (lambda ()
1396 (compile '(format #f "~2*~a" 'a 'b)
1397 #:opts %opts-w-format
1398 #:to 'assembly)))))
1399 (and (= (length w) 1)
1400 (number? (string-contains (car w)
1401 "expected 3, got 2")))))
1402
1403 (pass-if "~?"
1404 (null? (call-with-warnings
1405 (lambda ()
1406 (compile '(format #f "~?" "~d ~d" '(1 2))
1407 #:opts %opts-w-format
1408 #:to 'assembly)))))
1409
1410 (pass-if "complex 1"
1411 (let ((w (call-with-warnings
1412 (lambda ()
1413 (compile '(format #f
1414 "~4@S ~32S~@[;; ~1{~@?~}~]~@[~61t at ~a~]\n"
1415 1 2 3 4 5 6)
1416 #:opts %opts-w-format
1417 #:to 'assembly)))))
1418 (and (= (length w) 1)
1419 (number? (string-contains (car w)
1420 "expected 4, got 6")))))
1421
1422 (pass-if "complex 2"
1423 (let ((w (call-with-warnings
1424 (lambda ()
1425 (compile '(format #f
1426 "~:(~A~) Commands~:[~; [abbrev]~]:~2%"
1427 1 2 3 4)
1428 #:opts %opts-w-format
1429 #:to 'assembly)))))
1430 (and (= (length w) 1)
1431 (number? (string-contains (car w)
1432 "expected 2, got 4")))))
1433
1434 (pass-if "complex 3"
1435 (let ((w (call-with-warnings
1436 (lambda ()
1437 (compile '(format #f "~9@a~:[~*~3_~;~3d~] ~v:@y~%")
1438 #:opts %opts-w-format
1439 #:to 'assembly)))))
1440 (and (= (length w) 1)
1441 (number? (string-contains (car w)
1442 "expected 5, got 0")))))
1443
75365375
LC
1444 (pass-if "ice-9 format"
1445 (let ((w (call-with-warnings
1446 (lambda ()
1447 (let ((in (open-input-string
1448 "(use-modules ((ice-9 format)
1449 #:renamer (symbol-prefix-proc 'i9-)))
1450 (i9-format #t \"yo! ~A\" 1 2)")))
1451 (read-and-compile in
1452 #:opts %opts-w-format
1453 #:to 'assembly))))))
1454 (and (= (length w) 1)
1455 (number? (string-contains (car w)
1456 "expected 1, got 2")))))
1457
1458 (pass-if "not format"
1459 (null? (call-with-warnings
1460 (lambda ()
1461 (compile '(let ((format chbouib))
1462 (format #t "not ~A a format string"))
1463 #:opts %opts-w-format
1464 #:to 'assembly)))))))