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