primitive-load defaults to utf-8, not latin-1
[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;;;;
a5bbb22e 4;;;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
ce09ee19
AW
5;;;;
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
NJ
9;;;; version 3 of the License, or (at your option) any later version.
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.
53befeb7 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)
366 (call add 2) (call return 1) (unbind))))
367
ce09ee19
AW
368(with-test-prefix "lambda"
369 (assert-tree-il->glil
8a4ca0ea 370 (lambda ()
1e2a8edb 371 (lambda-case (((x) #f #f #f () (y)) (const 2)) #f))
8a4ca0ea 372 (program () (std-prelude 0 0 #f) (label _)
258344b4 373 (program () (std-prelude 1 1 #f)
8a4ca0ea
AW
374 (bind (x #f 0)) (label _)
375 (const 2) (call return 1) (unbind))
ce09ee19
AW
376 (call return 1)))
377
378 (assert-tree-il->glil
8a4ca0ea 379 (lambda ()
1e2a8edb 380 (lambda-case (((x y) #f #f #f () (x1 y1))
8a4ca0ea
AW
381 (const 2))
382 #f))
383 (program () (std-prelude 0 0 #f) (label _)
258344b4 384 (program () (std-prelude 2 2 #f)
8a4ca0ea
AW
385 (bind (x #f 0) (y #f 1)) (label _)
386 (const 2) (call return 1)
387 (unbind))
ce09ee19
AW
388 (call return 1)))
389
390 (assert-tree-il->glil
8a4ca0ea 391 (lambda ()
1e2a8edb 392 (lambda-case ((() #f x #f () (y)) (const 2))
8a4ca0ea
AW
393 #f))
394 (program () (std-prelude 0 0 #f) (label _)
899d37a6 395 (program () (opt-prelude 0 0 0 1 #f)
8a4ca0ea
AW
396 (bind (x #f 0)) (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 (((x) #f x1 #f () (y y1)) (const 2))
8a4ca0ea
AW
404 #f))
405 (program () (std-prelude 0 0 #f) (label _)
899d37a6 406 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
407 (bind (x #f 0) (x1 #f 1)) (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)) (lexical x y))
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 (lexical #t #f ref 0) (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 x1 y1))
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 1) (call return 1)
431 (unbind))
a1a482e0
AW
432 (call return 1)))
433
434 (assert-tree-il->glil
8a4ca0ea 435 (lambda ()
1e2a8edb 436 (lambda-case (((x) #f #f #f () (x1))
8a4ca0ea 437 (lambda ()
1e2a8edb 438 (lambda-case (((y) #f #f #f () (y1))
8a4ca0ea
AW
439 (lexical x x1))
440 #f)))
441 #f))
442 (program () (std-prelude 0 0 #f) (label _)
443 (program () (std-prelude 1 1 #f)
444 (bind (x #f 0)) (label _)
258344b4 445 (program () (std-prelude 1 1 #f)
8a4ca0ea
AW
446 (bind (y #f 0)) (label _)
447 (lexical #f #f ref 0) (call return 1)
448 (unbind))
66d3e9a3 449 (lexical #t #f ref 0)
6f16379e 450 (call make-closure 1)
8a4ca0ea
AW
451 (call return 1)
452 (unbind))
ce09ee19
AW
453 (call return 1))))
454
455(with-test-prefix "sequence"
456 (assert-tree-il->glil
457 (begin (begin (const 2) (const #f)) (const #t))
8a4ca0ea 458 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
459 (const #t) (call return 1)))
460
461 (assert-tree-il->glil
462 (apply (primitive null?) (begin (const #f) (const 2)))
8a4ca0ea 463 (program () (std-prelude 0 0 #f) (label _)
ce09ee19 464 (const 2) (call null? 1) (call return 1))))
5af166bd
AW
465
466;; FIXME: binding info for or-hacked locals might bork the disassembler,
467;; and could be tightened in any case
468(with-test-prefix "the or hack"
8a4ca0ea 469 (assert-tree-il->glil
5af166bd
AW
470 (let (x) (y) ((const 1))
471 (if (lexical x y)
472 (lexical x y)
473 (let (a) (b) ((const 2))
474 (lexical a b))))
8a4ca0ea 475 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
476 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
477 (lexical #t #f ref 0) (branch br-if-not ,l1)
478 (lexical #t #f ref 0) (call return 1)
5af166bd 479 (label ,l2)
66d3e9a3
AW
480 (const 2) (bind (a #f 0)) (lexical #t #f set 0)
481 (lexical #t #f ref 0) (call return 1)
5af166bd
AW
482 (unbind)
483 (unbind))
484 (eq? l1 l2))
485
aaae0d5a 486 ;; second bound var is unreferenced
8a4ca0ea 487 (assert-tree-il->glil
5af166bd
AW
488 (let (x) (y) ((const 1))
489 (if (lexical x y)
490 (lexical x y)
491 (let (a) (b) ((const 2))
492 (lexical x y))))
8a4ca0ea 493 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
494 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
495 (lexical #t #f ref 0) (branch br-if-not ,l1)
496 (lexical #t #f ref 0) (call return 1)
5af166bd 497 (label ,l2)
66d3e9a3 498 (lexical #t #f ref 0) (call return 1)
5af166bd
AW
499 (unbind))
500 (eq? l1 l2)))
0f423f20
AW
501
502(with-test-prefix "apply"
503 (assert-tree-il->glil
504 (apply (primitive @apply) (toplevel foo) (toplevel bar))
a5bbb22e 505 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (toplevel ref bar) (call tail-apply 2)))
8a4ca0ea 506 (assert-tree-il->glil
0f423f20 507 (begin (apply (primitive @apply) (toplevel foo) (toplevel bar)) (void))
8a4ca0ea 508 (program () (std-prelude 0 0 #f) (label _)
b7946e9e 509 (call new-frame 0) (toplevel ref apply) (toplevel ref foo) (toplevel ref bar) (mv-call 2 ,l1)
05c51bcf 510 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind 0 #f)
0f423f20
AW
511 (label ,l4)
512 (void) (call return 1))
513 (and (eq? l1 l3) (eq? l2 l4)))
514 (assert-tree-il->glil
515 (apply (toplevel foo) (apply (toplevel @apply) (toplevel bar) (toplevel baz)))
8a4ca0ea 516 (program () (std-prelude 0 0 #f) (label _)
0f423f20 517 (toplevel ref foo)
b7946e9e 518 (call new-frame 0) (toplevel ref bar) (toplevel ref baz) (call apply 2)
a5bbb22e 519 (call tail-call 1))))
0f423f20
AW
520
521(with-test-prefix "call/cc"
522 (assert-tree-il->glil
523 (apply (primitive @call-with-current-continuation) (toplevel foo))
a5bbb22e 524 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (call tail-call/cc 1)))
8a4ca0ea 525 (assert-tree-il->glil
0f423f20 526 (begin (apply (primitive @call-with-current-continuation) (toplevel foo)) (void))
8a4ca0ea 527 (program () (std-prelude 0 0 #f) (label _)
b7946e9e 528 (call new-frame 0) (toplevel ref call-with-current-continuation) (toplevel ref foo) (mv-call 1 ,l1)
05c51bcf 529 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind 0 #f)
0f423f20
AW
530 (label ,l4)
531 (void) (call return 1))
532 (and (eq? l1 l3) (eq? l2 l4)))
533 (assert-tree-il->glil
534 (apply (toplevel foo)
535 (apply (toplevel @call-with-current-continuation) (toplevel bar)))
8a4ca0ea 536 (program () (std-prelude 0 0 #f) (label _)
0f423f20
AW
537 (toplevel ref foo)
538 (toplevel ref bar) (call call/cc 1)
a5bbb22e 539 (call tail-call 1))))
0f423f20 540
f4aa0f10
LC
541\f
542(with-test-prefix "tree-il-fold"
543
544 (pass-if "empty tree"
545 (let ((leaf? #f) (up? #f) (down? #f) (mark (list 'mark)))
546 (and (eq? mark
547 (tree-il-fold (lambda (x y) (set! leaf? #t) y)
548 (lambda (x y) (set! down? #t) y)
549 (lambda (x y) (set! up? #t) y)
550 mark
551 '()))
552 (not leaf?)
553 (not up?)
554 (not down?))))
555
556 (pass-if "lambda and application"
557 (let* ((leaves '()) (ups '()) (downs '())
558 (result (tree-il-fold (lambda (x y)
559 (set! leaves (cons x leaves))
560 (1+ y))
561 (lambda (x y)
562 (set! downs (cons x downs))
563 (1+ y))
564 (lambda (x y)
565 (set! ups (cons x ups))
566 (1+ y))
567 0
568 (parse-tree-il
8a4ca0ea
AW
569 '(lambda ()
570 (lambda-case
1e2a8edb 571 (((x y) #f #f #f () (x1 y1))
8a4ca0ea
AW
572 (apply (toplevel +)
573 (lexical x x1)
574 (lexical y y1)))
575 #f))))))
f4aa0f10
LC
576 (and (equal? (map strip-source leaves)
577 (list (make-lexical-ref #f 'y 'y1)
578 (make-lexical-ref #f 'x 'x1)
579 (make-toplevel-ref #f '+)))
8a4ca0ea 580 (= (length downs) 3)
f4aa0f10
LC
581 (equal? (reverse (map strip-source ups))
582 (map strip-source downs))))))
4b856371
LC
583
584\f
585;;;
586;;; Warnings.
587;;;
588
589;; Make sure we get English messages.
590(setlocale LC_ALL "C")
591
592(define (call-with-warnings thunk)
593 (let ((port (open-output-string)))
594 (with-fluid* *current-warning-port* port
595 thunk)
596 (let ((warnings (get-output-string port)))
597 (string-tokenize warnings
598 (char-set-complement (char-set #\newline))))))
599
600(define %opts-w-unused
601 '(#:warnings (unused-variable)))
602
bcae9a98
LC
603(define %opts-w-unused-toplevel
604 '(#:warnings (unused-toplevel)))
605
f67ddf9d
LC
606(define %opts-w-unbound
607 '(#:warnings (unbound-variable)))
4b856371 608
ae03cf1f
LC
609(define %opts-w-arity
610 '(#:warnings (arity-mismatch)))
611
75365375
LC
612(define %opts-w-format
613 '(#:warnings (format)))
614
ae03cf1f 615
4b856371
LC
616(with-test-prefix "warnings"
617
618 (pass-if "unknown warning type"
619 (let ((w (call-with-warnings
620 (lambda ()
621 (compile #t #:opts '(#:warnings (does-not-exist)))))))
622 (and (= (length w) 1)
623 (number? (string-contains (car w) "unknown warning")))))
624
625 (with-test-prefix "unused-variable"
626
627 (pass-if "quiet"
628 (null? (call-with-warnings
629 (lambda ()
630 (compile '(lambda (x y) (+ x y))
631 #:opts %opts-w-unused)))))
632
633 (pass-if "let/unused"
634 (let ((w (call-with-warnings
635 (lambda ()
636 (compile '(lambda (x)
637 (let ((y (+ x 2)))
638 x))
639 #:opts %opts-w-unused)))))
640 (and (= (length w) 1)
641 (number? (string-contains (car w) "unused variable `y'")))))
642
643 (pass-if "shadowed variable"
644 (let ((w (call-with-warnings
645 (lambda ()
646 (compile '(lambda (x)
647 (let ((y x))
648 (let ((y (+ x 2)))
649 (+ x y))))
650 #:opts %opts-w-unused)))))
651 (and (= (length w) 1)
652 (number? (string-contains (car w) "unused variable `y'")))))
653
654 (pass-if "letrec"
655 (null? (call-with-warnings
656 (lambda ()
657 (compile '(lambda ()
658 (letrec ((x (lambda () (y)))
659 (y (lambda () (x))))
660 y))
661 #:opts %opts-w-unused)))))
662
663 (pass-if "unused argument"
664 ;; Unused arguments should not be reported.
665 (null? (call-with-warnings
666 (lambda ()
667 (compile '(lambda (x y z) #t)
3a1a883b
LC
668 #:opts %opts-w-unused)))))
669
670 (pass-if "special variable names"
671 (null? (call-with-warnings
672 (lambda ()
673 (compile '(lambda ()
674 (let ((_ 'underscore)
675 (#{gensym name}# 'ignore-me))
676 #t))
677 #:to 'assembly
f67ddf9d
LC
678 #:opts %opts-w-unused))))))
679
bcae9a98
LC
680 (with-test-prefix "unused-toplevel"
681
682 (pass-if "used after definition"
683 (null? (call-with-warnings
684 (lambda ()
685 (let ((in (open-input-string
686 "(define foo 2) foo")))
687 (read-and-compile in
688 #:to 'assembly
689 #:opts %opts-w-unused-toplevel))))))
690
691 (pass-if "used before definition"
692 (null? (call-with-warnings
693 (lambda ()
694 (let ((in (open-input-string
695 "(define (bar) foo) (define foo 2) (bar)")))
696 (read-and-compile in
697 #:to 'assembly
698 #:opts %opts-w-unused-toplevel))))))
699
700 (pass-if "unused but public"
701 (let ((in (open-input-string
702 "(define-module (test-suite tree-il x) #:export (bar))
703 (define (bar) #t)")))
704 (null? (call-with-warnings
705 (lambda ()
706 (read-and-compile in
707 #:to 'assembly
708 #:opts %opts-w-unused-toplevel))))))
709
710 (pass-if "unused but public (more)"
711 (let ((in (open-input-string
712 "(define-module (test-suite tree-il x) #:export (bar))
713 (define (bar) (baz))
714 (define (baz) (foo))
715 (define (foo) #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 define-public"
bcae9a98
LC
723 (null? (call-with-warnings
724 (lambda ()
725 (compile '(define-public foo 2)
726 #:to 'assembly
727 #:opts %opts-w-unused-toplevel)))))
728
729 (pass-if "used by macro"
730 ;; FIXME: See comment about macros at `unused-toplevel-analysis'.
731 (throw 'unresolved)
732
733 (null? (call-with-warnings
734 (lambda ()
735 (let ((in (open-input-string
736 "(define (bar) 'foo)
737 (define-syntax baz
738 (syntax-rules () ((_) (bar))))")))
739 (read-and-compile in
740 #:to 'assembly
741 #:opts %opts-w-unused-toplevel))))))
742
743 (pass-if "unused"
744 (let ((w (call-with-warnings
745 (lambda ()
746 (compile '(define foo 2)
747 #:to 'assembly
748 #:opts %opts-w-unused-toplevel)))))
749 (and (= (length w) 1)
750 (number? (string-contains (car w)
751 (format #f "top-level variable `~A'"
752 'foo))))))
753
754 (pass-if "unused recursive"
755 (let ((w (call-with-warnings
756 (lambda ()
757 (compile '(define (foo) (foo))
758 #:to 'assembly
759 #:opts %opts-w-unused-toplevel)))))
760 (and (= (length w) 1)
761 (number? (string-contains (car w)
762 (format #f "top-level variable `~A'"
763 'foo))))))
764
765 (pass-if "unused mutually recursive"
766 (let* ((in (open-input-string
767 "(define (foo) (bar)) (define (bar) (foo))"))
768 (w (call-with-warnings
769 (lambda ()
770 (read-and-compile in
771 #:to 'assembly
772 #:opts %opts-w-unused-toplevel)))))
773 (and (= (length w) 2)
774 (number? (string-contains (car w)
775 (format #f "top-level variable `~A'"
776 'foo)))
777 (number? (string-contains (cadr w)
778 (format #f "top-level variable `~A'"
3a1a883b
LC
779 'bar))))))
780
781 (pass-if "special variable names"
782 (null? (call-with-warnings
783 (lambda ()
784 (compile '(define #{gensym name}# 'ignore-me)
785 #:to 'assembly
786 #:opts %opts-w-unused-toplevel))))))
bcae9a98 787
f67ddf9d
LC
788 (with-test-prefix "unbound variable"
789
790 (pass-if "quiet"
791 (null? (call-with-warnings
792 (lambda ()
793 (compile '+ #:opts %opts-w-unbound)))))
794
795 (pass-if "ref"
796 (let* ((v (gensym))
797 (w (call-with-warnings
798 (lambda ()
799 (compile v
800 #:to 'assembly
801 #:opts %opts-w-unbound)))))
802 (and (= (length w) 1)
803 (number? (string-contains (car w)
804 (format #f "unbound variable `~A'"
805 v))))))
806
807 (pass-if "set!"
808 (let* ((v (gensym))
809 (w (call-with-warnings
810 (lambda ()
811 (compile `(set! ,v 7)
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 "module-local top-level is visible"
820 (let ((m (make-module))
821 (v (gensym)))
822 (beautify-user-module! m)
823 (compile `(define ,v 123)
824 #:env m #:opts %opts-w-unbound)
825 (null? (call-with-warnings
826 (lambda ()
827 (compile v
828 #:env m
829 #:to 'assembly
830 #:opts %opts-w-unbound))))))
831
832 (pass-if "module-local top-level is visible after"
833 (let ((m (make-module))
834 (v (gensym)))
835 (beautify-user-module! m)
836 (null? (call-with-warnings
837 (lambda ()
838 (let ((in (open-input-string
839 "(define (f)
840 (set! chbouib 3))
841 (define chbouib 5)")))
b6d2306d
LC
842 (read-and-compile in
843 #:env m
844 #:opts %opts-w-unbound)))))))
845
bd36e901
LC
846 (pass-if "optional arguments are visible"
847 (null? (call-with-warnings
848 (lambda ()
849 (compile '(lambda* (x #:optional y z) (list x y z))
850 #:opts %opts-w-unbound
851 #:to 'assembly)))))
852
853 (pass-if "keyword arguments are visible"
854 (null? (call-with-warnings
855 (lambda ()
856 (compile '(lambda* (x #:key y z) (list x y z))
857 #:opts %opts-w-unbound
858 #:to 'assembly)))))
859
b6d2306d
LC
860 (pass-if "GOOPS definitions are visible"
861 (let ((m (make-module))
862 (v (gensym)))
863 (beautify-user-module! m)
864 (module-use! m (resolve-interface '(oop goops)))
865 (null? (call-with-warnings
866 (lambda ()
867 (let ((in (open-input-string
868 "(define-class <foo> ()
869 (bar #:getter foo-bar))
870 (define z (foo-bar (make <foo>)))")))
f67ddf9d
LC
871 (read-and-compile in
872 #:env m
ae03cf1f
LC
873 #:opts %opts-w-unbound))))))))
874
875 (with-test-prefix "arity mismatch"
876
877 (pass-if "quiet"
878 (null? (call-with-warnings
879 (lambda ()
880 (compile '(cons 'a 'b) #:opts %opts-w-arity)))))
881
882 (pass-if "direct application"
883 (let ((w (call-with-warnings
884 (lambda ()
885 (compile '((lambda (x y) (or x y)) 1 2 3 4 5)
886 #:opts %opts-w-arity
887 #:to 'assembly)))))
888 (and (= (length w) 1)
889 (number? (string-contains (car w)
890 "wrong number of arguments to")))))
891 (pass-if "local"
892 (let ((w (call-with-warnings
893 (lambda ()
894 (compile '(let ((f (lambda (x y) (+ x y))))
895 (f 2))
896 #:opts %opts-w-arity
897 #:to 'assembly)))))
898 (and (= (length w) 1)
899 (number? (string-contains (car w)
900 "wrong number of arguments to")))))
901
902 (pass-if "global"
903 (let ((w (call-with-warnings
904 (lambda ()
905 (compile '(cons 1 2 3 4)
906 #:opts %opts-w-arity
907 #:to 'assembly)))))
908 (and (= (length w) 1)
909 (number? (string-contains (car w)
910 "wrong number of arguments to")))))
911
912 (pass-if "alias to global"
913 (let ((w (call-with-warnings
914 (lambda ()
915 (compile '(let ((f cons)) (f 1 2 3 4))
916 #:opts %opts-w-arity
917 #:to 'assembly)))))
918 (and (= (length w) 1)
919 (number? (string-contains (car w)
920 "wrong number of arguments to")))))
921
922 (pass-if "alias to lexical to global"
923 (let ((w (call-with-warnings
924 (lambda ()
925 (compile '(let ((f number?))
926 (let ((g f))
927 (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"
935 (let ((w (call-with-warnings
936 (lambda ()
937 (compile '(let ((f (lambda (x y z) (+ x y z))))
938 (let ((g f))
939 (g 1)))
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 "letrec"
947 (let ((w (call-with-warnings
948 (lambda ()
949 (compile '(letrec ((odd? (lambda (x) (even? (1- x))))
950 (even? (lambda (x)
951 (or (= 0 x)
952 (odd?)))))
953 (odd? 1))
954 #:opts %opts-w-arity
955 #:to 'assembly)))))
956 (and (= (length w) 1)
957 (number? (string-contains (car w)
958 "wrong number of arguments to")))))
959
99480e11
LC
960 (pass-if "case-lambda"
961 (null? (call-with-warnings
962 (lambda ()
963 (compile '(let ((f (case-lambda
964 ((x) 1)
965 ((x y) 2)
966 ((x y z) 3))))
967 (list (f 1)
968 (f 1 2)
969 (f 1 2 3)))
970 #:opts %opts-w-arity
971 #:to 'assembly)))))
972
973 (pass-if "case-lambda with wrong number of arguments"
974 (let ((w (call-with-warnings
975 (lambda ()
976 (compile '(let ((f (case-lambda
977 ((x) 1)
978 ((x y) 2))))
979 (f 1 2 3))
980 #:opts %opts-w-arity
981 #:to 'assembly)))))
982 (and (= (length w) 1)
983 (number? (string-contains (car w)
984 "wrong number of arguments to")))))
985
986 (pass-if "case-lambda*"
987 (null? (call-with-warnings
988 (lambda ()
989 (compile '(let ((f (case-lambda*
990 ((x #:optional y) 1)
991 ((x #:key y) 2)
992 ((x y #:key z) 3))))
993 (list (f 1)
994 (f 1 2)
995 (f #:y 2)
996 (f 1 2 #:z 3)))
997 #:opts %opts-w-arity
998 #:to 'assembly)))))
999
1000 (pass-if "case-lambda* with wrong arguments"
1001 (let ((w (call-with-warnings
1002 (lambda ()
1003 (compile '(let ((f (case-lambda*
1004 ((x #:optional y) 1)
1005 ((x #:key y) 2)
1006 ((x y #:key z) 3))))
1007 (list (f)
1008 (f 1 #:z 3)))
1009 #:opts %opts-w-arity
1010 #:to 'assembly)))))
1011 (and (= (length w) 2)
1012 (null? (filter (lambda (w)
1013 (not
1014 (number?
1015 (string-contains
1016 w "wrong number of arguments to"))))
1017 w)))))
1018
ae03cf1f
LC
1019 (pass-if "local toplevel-defines"
1020 (let ((w (call-with-warnings
1021 (lambda ()
1022 (let ((in (open-input-string "
1023 (define (g x) (f x))
1024 (define (f) 1)")))
1025 (read-and-compile in
1026 #:opts %opts-w-arity
1027 #:to 'assembly))))))
1028 (and (= (length w) 1)
1029 (number? (string-contains (car w)
1030 "wrong number of arguments to")))))
1031
1032 (pass-if "global toplevel alias"
1033 (let ((w (call-with-warnings
1034 (lambda ()
1035 (let ((in (open-input-string "
1036 (define f cons)
1037 (define (g) (f))")))
1038 (read-and-compile in
1039 #:opts %opts-w-arity
1040 #:to 'assembly))))))
1041 (and (= (length w) 1)
1042 (number? (string-contains (car w)
1043 "wrong number of arguments to")))))
1044
1045 (pass-if "local toplevel overrides global"
1046 (null? (call-with-warnings
1047 (lambda ()
1048 (let ((in (open-input-string "
1049 (define (cons) 0)
1050 (define (foo x) (cons))")))
1051 (read-and-compile in
1052 #:opts %opts-w-arity
af5ed549
LC
1053 #:to 'assembly))))))
1054
1055 (pass-if "keyword not passed and quiet"
1056 (null? (call-with-warnings
1057 (lambda ()
1058 (compile '(let ((f (lambda* (x #:key y) y)))
1059 (f 2))
1060 #:opts %opts-w-arity
1061 #:to 'assembly)))))
1062
1063 (pass-if "keyword passed and quiet"
1064 (null? (call-with-warnings
1065 (lambda ()
1066 (compile '(let ((f (lambda* (x #:key y) y)))
1067 (f 2 #:y 3))
1068 #:opts %opts-w-arity
1069 #:to 'assembly)))))
1070
1071 (pass-if "keyword passed to global and quiet"
1072 (null? (call-with-warnings
1073 (lambda ()
1074 (let ((in (open-input-string "
1075 (use-modules (system base compile))
1076 (compile '(+ 2 3) #:env (current-module))")))
1077 (read-and-compile in
1078 #:opts %opts-w-arity
1079 #:to 'assembly))))))
1080
1081 (pass-if "extra keyword"
1082 (let ((w (call-with-warnings
1083 (lambda ()
1084 (compile '(let ((f (lambda* (x #:key y) y)))
1085 (f 2 #:Z 3))
1086 #:opts %opts-w-arity
1087 #:to 'assembly)))))
1088 (and (= (length w) 1)
1089 (number? (string-contains (car w)
1090 "wrong number of arguments to")))))
1091
1092 (pass-if "extra keywords allowed"
1093 (null? (call-with-warnings
1094 (lambda ()
1095 (compile '(let ((f (lambda* (x #:key y #:allow-other-keys)
1096 y)))
1097 (f 2 #:Z 3))
1098 #:opts %opts-w-arity
75365375
LC
1099 #:to 'assembly))))))
1100
1101 (with-test-prefix "format"
1102
1103 (pass-if "quiet (no args)"
1104 (null? (call-with-warnings
1105 (lambda ()
1106 (compile '(format #t "hey!")
1107 #:opts %opts-w-format
1108 #:to 'assembly)))))
1109
1110 (pass-if "quiet (1 arg)"
1111 (null? (call-with-warnings
1112 (lambda ()
1113 (compile '(format #t "hey ~A!" "you")
1114 #:opts %opts-w-format
1115 #:to 'assembly)))))
1116
1117 (pass-if "quiet (2 args)"
1118 (null? (call-with-warnings
1119 (lambda ()
1120 (compile '(format #t "~A ~A!" "hello" "world")
1121 #:opts %opts-w-format
1122 #:to 'assembly)))))
1123
60f01304
LC
1124 (pass-if "wrong port arg"
1125 (let ((w (call-with-warnings
1126 (lambda ()
1127 (compile '(format 10 "foo")
1128 #:opts %opts-w-format
1129 #:to 'assembly)))))
1130 (and (= (length w) 1)
1131 (number? (string-contains (car w)
1132 "wrong port argument")))))
1133
1134 (pass-if "non-literal format string"
1135 (let ((w (call-with-warnings
1136 (lambda ()
1137 (compile '(format #f fmt)
1138 #:opts %opts-w-format
1139 #:to 'assembly)))))
1140 (and (= (length w) 1)
1141 (number? (string-contains (car w)
1142 "non-literal format string")))))
1143
1144 (pass-if "wrong format string"
1145 (let ((w (call-with-warnings
1146 (lambda ()
1147 (compile '(format #f 'not-a-string)
1148 #:opts %opts-w-format
1149 #:to 'assembly)))))
1150 (and (= (length w) 1)
1151 (number? (string-contains (car w)
1152 "wrong format string")))))
1153
1154 (pass-if "wrong number of args"
1155 (let ((w (call-with-warnings
1156 (lambda ()
1157 (compile '(format "shbweeb")
1158 #:opts %opts-w-format
1159 #:to 'assembly)))))
1160 (and (= (length w) 1)
1161 (number? (string-contains (car w)
1162 "wrong number of arguments")))))
1163
e0697241 1164 (pass-if "~%, ~~, ~&, ~t, ~_, and ~\\n"
75365375
LC
1165 (null? (call-with-warnings
1166 (lambda ()
e0697241 1167 (compile '(format some-port "~&~3_~~ ~\n~12they~%")
75365375
LC
1168 #:opts %opts-w-format
1169 #:to 'assembly)))))
1170
1171 (pass-if "one missing argument"
1172 (let ((w (call-with-warnings
1173 (lambda ()
1174 (compile '(format some-port "foo ~A~%")
1175 #:opts %opts-w-format
1176 #:to 'assembly)))))
1177 (and (= (length w) 1)
1178 (number? (string-contains (car w)
1179 "expected 1, got 0")))))
1180
1181 (pass-if "two missing arguments"
1182 (let ((w (call-with-warnings
1183 (lambda ()
1184 (compile '(format #f "foo ~10,2f and bar ~S~%")
1185 #:opts %opts-w-format
1186 #:to 'assembly)))))
1187 (and (= (length w) 1)
1188 (number? (string-contains (car w)
1189 "expected 2, got 0")))))
1190
1191 (pass-if "one given, one missing argument"
1192 (let ((w (call-with-warnings
1193 (lambda ()
1194 (compile '(format #t "foo ~A and ~S~%" hey)
1195 #:opts %opts-w-format
1196 #:to 'assembly)))))
1197 (and (= (length w) 1)
1198 (number? (string-contains (car w)
1199 "expected 2, got 1")))))
1200
1201 (pass-if "too many arguments"
1202 (let ((w (call-with-warnings
1203 (lambda ()
1204 (compile '(format #t "foo ~A~%" 1 2)
1205 #:opts %opts-w-format
1206 #:to 'assembly)))))
1207 (and (= (length w) 1)
1208 (number? (string-contains (car w)
1209 "expected 1, got 2")))))
1210
e0697241
LC
1211 (with-test-prefix "conditionals"
1212 (pass-if "literals"
1213 (null? (call-with-warnings
1214 (lambda ()
1215 (compile '(format #f "~A ~[foo~;bar~;baz~;~] ~10,2f"
1216 'a 1 3.14)
1217 #:opts %opts-w-format
1218 #:to 'assembly)))))
1219
1220 (pass-if "literals with selector"
1221 (let ((w (call-with-warnings
1222 (lambda ()
1223 (compile '(format #f "~2[foo~;bar~;baz~;~] ~A"
1224 1 'dont-ignore-me)
1225 #:opts %opts-w-format
1226 #:to 'assembly)))))
1227 (and (= (length w) 1)
1228 (number? (string-contains (car w)
1229 "expected 1, got 2")))))
1230
1231 (pass-if "escapes (exact count)"
1232 (let ((w (call-with-warnings
1233 (lambda ()
1234 (compile '(format #f "~[~a~;~a~]")
1235 #:opts %opts-w-format
1236 #:to 'assembly)))))
1237 (and (= (length w) 1)
1238 (number? (string-contains (car w)
1239 "expected 2, got 0")))))
1240
1241 (pass-if "escapes with selector"
1242 (let ((w (call-with-warnings
1243 (lambda ()
1244 (compile '(format #f "~1[chbouib~;~a~]")
1245 #:opts %opts-w-format
1246 #:to 'assembly)))))
1247 (and (= (length w) 1)
1248 (number? (string-contains (car w)
1249 "expected 1, got 0")))))
1250
1251 (pass-if "escapes, range"
1252 (let ((w (call-with-warnings
1253 (lambda ()
1254 (compile '(format #f "~[chbouib~;~a~;~2*~a~]")
1255 #:opts %opts-w-format
1256 #:to 'assembly)))))
1257 (and (= (length w) 1)
1258 (number? (string-contains (car w)
1259 "expected 1 to 4, got 0")))))
1260
1261 (pass-if "@"
1262 (let ((w (call-with-warnings
1263 (lambda ()
1264 (compile '(format #f "~@[temperature=~d~]")
1265 #:opts %opts-w-format
1266 #:to 'assembly)))))
1267 (and (= (length w) 1)
1268 (number? (string-contains (car w)
1269 "expected 1, got 0")))))
1270
1271 (pass-if "nested"
1272 (let ((w (call-with-warnings
1273 (lambda ()
1274 (compile '(format #f "~:[~[hey~;~a~;~va~]~;~3*~]")
1275 #:opts %opts-w-format
1276 #:to 'assembly)))))
1277 (and (= (length w) 1)
1278 (number? (string-contains (car w)
1279 "expected 2 to 4, got 0")))))
1280
8e6c15a6
LC
1281 (pass-if "unterminated"
1282 (let ((w (call-with-warnings
1283 (lambda ()
1284 (compile '(format #f "~[unterminated")
1285 #:opts %opts-w-format
1286 #:to 'assembly)))))
1287 (and (= (length w) 1)
1288 (number? (string-contains (car w)
1289 "unterminated conditional")))))
1290
1291 (pass-if "unexpected ~;"
1292 (let ((w (call-with-warnings
1293 (lambda ()
1294 (compile '(format #f "foo~;bar")
1295 #:opts %opts-w-format
1296 #:to 'assembly)))))
1297 (and (= (length w) 1)
1298 (number? (string-contains (car w)
1299 "unexpected")))))
1300
1301 (pass-if "unexpected ~]"
1302 (let ((w (call-with-warnings
1303 (lambda ()
1304 (compile '(format #f "foo~]")
1305 #:opts %opts-w-format
1306 #:to 'assembly)))))
1307 (and (= (length w) 1)
1308 (number? (string-contains (car w)
1309 "unexpected"))))))
e0697241
LC
1310
1311 (pass-if "~{...~}"
1312 (null? (call-with-warnings
1313 (lambda ()
1314 (compile '(format #f "~A ~{~S~} ~A"
1315 'hello '("ladies" "and")
1316 'gentlemen)
1317 #:opts %opts-w-format
1318 #:to 'assembly)))))
1319
1320 (pass-if "~{...~}, too many args"
1321 (let ((w (call-with-warnings
1322 (lambda ()
1323 (compile '(format #f "~{~S~}" 1 2 3)
1324 #:opts %opts-w-format
1325 #:to 'assembly)))))
1326 (and (= (length w) 1)
1327 (number? (string-contains (car w)
1328 "expected 1, got 3")))))
1329
1330 (pass-if "~@{...~}"
1331 (null? (call-with-warnings
1332 (lambda ()
1333 (compile '(format #f "~@{~S~}" 1 2 3)
1334 #:opts %opts-w-format
1335 #:to 'assembly)))))
1336
1337 (pass-if "~@{...~}, too few args"
1338 (let ((w (call-with-warnings
1339 (lambda ()
1340 (compile '(format #f "~A ~@{~S~}")
1341 #:opts %opts-w-format
1342 #:to 'assembly)))))
1343 (and (= (length w) 1)
1344 (number? (string-contains (car w)
1345 "expected at least 1, got 0")))))
1346
8e6c15a6
LC
1347 (pass-if "unterminated ~{...~}"
1348 (let ((w (call-with-warnings
1349 (lambda ()
1350 (compile '(format #f "~{")
1351 #:opts %opts-w-format
1352 #:to 'assembly)))))
1353 (and (= (length w) 1)
1354 (number? (string-contains (car w)
1355 "unterminated")))))
1356
e0697241
LC
1357 (pass-if "~(...~)"
1358 (null? (call-with-warnings
1359 (lambda ()
1360 (compile '(format #f "~:@(~A ~A~)" 'foo 'bar)
1361 #:opts %opts-w-format
1362 #:to 'assembly)))))
1363
1364 (pass-if "~v"
1365 (let ((w (call-with-warnings
1366 (lambda ()
1367 (compile '(format #f "~v_foo")
1368 #:opts %opts-w-format
1369 #:to 'assembly)))))
1370 (and (= (length w) 1)
1371 (number? (string-contains (car w)
1372 "expected 1, got 0")))))
1373 (pass-if "~v:@y"
1374 (null? (call-with-warnings
1375 (lambda ()
1376 (compile '(format #f "~v:@y" 1 123)
1377 #:opts %opts-w-format
1378 #:to 'assembly)))))
1379
1380
1381 (pass-if "~*"
1382 (let ((w (call-with-warnings
1383 (lambda ()
1384 (compile '(format #f "~2*~a" 'a 'b)
1385 #:opts %opts-w-format
1386 #:to 'assembly)))))
1387 (and (= (length w) 1)
1388 (number? (string-contains (car w)
1389 "expected 3, got 2")))))
1390
1391 (pass-if "~?"
1392 (null? (call-with-warnings
1393 (lambda ()
1394 (compile '(format #f "~?" "~d ~d" '(1 2))
1395 #:opts %opts-w-format
1396 #:to 'assembly)))))
1397
1398 (pass-if "complex 1"
1399 (let ((w (call-with-warnings
1400 (lambda ()
1401 (compile '(format #f
1402 "~4@S ~32S~@[;; ~1{~@?~}~]~@[~61t at ~a~]\n"
1403 1 2 3 4 5 6)
1404 #:opts %opts-w-format
1405 #:to 'assembly)))))
1406 (and (= (length w) 1)
1407 (number? (string-contains (car w)
1408 "expected 4, got 6")))))
1409
1410 (pass-if "complex 2"
1411 (let ((w (call-with-warnings
1412 (lambda ()
1413 (compile '(format #f
1414 "~:(~A~) Commands~:[~; [abbrev]~]:~2%"
1415 1 2 3 4)
1416 #:opts %opts-w-format
1417 #:to 'assembly)))))
1418 (and (= (length w) 1)
1419 (number? (string-contains (car w)
1420 "expected 2, got 4")))))
1421
1422 (pass-if "complex 3"
1423 (let ((w (call-with-warnings
1424 (lambda ()
1425 (compile '(format #f "~9@a~:[~*~3_~;~3d~] ~v:@y~%")
1426 #:opts %opts-w-format
1427 #:to 'assembly)))))
1428 (and (= (length w) 1)
1429 (number? (string-contains (car w)
1430 "expected 5, got 0")))))
1431
75365375
LC
1432 (pass-if "ice-9 format"
1433 (let ((w (call-with-warnings
1434 (lambda ()
1435 (let ((in (open-input-string
1436 "(use-modules ((ice-9 format)
1437 #:renamer (symbol-prefix-proc 'i9-)))
1438 (i9-format #t \"yo! ~A\" 1 2)")))
1439 (read-and-compile in
1440 #:opts %opts-w-format
1441 #:to 'assembly))))))
1442 (and (= (length w) 1)
1443 (number? (string-contains (car w)
1444 "expected 1, got 2")))))
1445
1446 (pass-if "not format"
1447 (null? (call-with-warnings
1448 (lambda ()
1449 (compile '(let ((format chbouib))
1450 (format #t "not ~A a format string"))
1451 #:opts %opts-w-format
1452 #:to 'assembly)))))))