Fix typos leading to wrong argument counts.
[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;;;;
4;;;; Copyright (C) 2009 Free Software Foundation, Inc.
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))
8a4ca0ea
AW
72 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (const 1) (call goto/args 1)))
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
AW
76 (call drop 1) (branch br ,l2)
77 (label ,l3) (mv-bind () #f) (unbind)
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)
ce09ee19
AW
84 (call goto/args 1))))
85
86(with-test-prefix "conditional"
8a4ca0ea 87 (assert-tree-il->glil
ce09ee19 88 (if (const #t) (const 1) (const 2))
8a4ca0ea 89 (program () (std-prelude 0 0 #f) (label _) (const #t) (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
ce09ee19 95 (begin (if (const #t) (const 1) (const 2)) (const #f))
8a4ca0ea 96 (program () (std-prelude 0 0 #f) (label _) (const #t) (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
ce09ee19 101 (apply (primitive null?) (if (const #t) (const 1) (const 2)))
8a4ca0ea 102 (program () (std-prelude 0 0 #f) (label _) (const #t) (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
322(with-test-prefix "lambda"
323 (assert-tree-il->glil
8a4ca0ea 324 (lambda ()
b0c8c187 325 (lambda-case (((x) #f #f #f () (y) #f) (const 2)) #f))
8a4ca0ea 326 (program () (std-prelude 0 0 #f) (label _)
258344b4 327 (program () (std-prelude 1 1 #f)
8a4ca0ea
AW
328 (bind (x #f 0)) (label _)
329 (const 2) (call return 1) (unbind))
ce09ee19
AW
330 (call return 1)))
331
332 (assert-tree-il->glil
8a4ca0ea 333 (lambda ()
b0c8c187 334 (lambda-case (((x y) #f #f #f () (x1 y1) #f)
8a4ca0ea
AW
335 (const 2))
336 #f))
337 (program () (std-prelude 0 0 #f) (label _)
258344b4 338 (program () (std-prelude 2 2 #f)
8a4ca0ea
AW
339 (bind (x #f 0) (y #f 1)) (label _)
340 (const 2) (call return 1)
341 (unbind))
ce09ee19
AW
342 (call return 1)))
343
344 (assert-tree-il->glil
8a4ca0ea 345 (lambda ()
b0c8c187 346 (lambda-case ((() #f x #f () (y) #f) (const 2))
8a4ca0ea
AW
347 #f))
348 (program () (std-prelude 0 0 #f) (label _)
899d37a6 349 (program () (opt-prelude 0 0 0 1 #f)
8a4ca0ea
AW
350 (bind (x #f 0)) (label _)
351 (const 2) (call return 1)
352 (unbind))
ce09ee19
AW
353 (call return 1)))
354
355 (assert-tree-il->glil
8a4ca0ea 356 (lambda ()
b0c8c187 357 (lambda-case (((x) #f x1 #f () (y y1) #f) (const 2))
8a4ca0ea
AW
358 #f))
359 (program () (std-prelude 0 0 #f) (label _)
899d37a6 360 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
361 (bind (x #f 0) (x1 #f 1)) (label _)
362 (const 2) (call return 1)
363 (unbind))
ce09ee19
AW
364 (call return 1)))
365
366 (assert-tree-il->glil
8a4ca0ea 367 (lambda ()
b0c8c187 368 (lambda-case (((x) #f x1 #f () (y y1) #f) (lexical x y))
8a4ca0ea
AW
369 #f))
370 (program () (std-prelude 0 0 #f) (label _)
899d37a6 371 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
372 (bind (x #f 0) (x1 #f 1)) (label _)
373 (lexical #t #f ref 0) (call return 1)
374 (unbind))
ce09ee19
AW
375 (call return 1)))
376
377 (assert-tree-il->glil
8a4ca0ea 378 (lambda ()
b0c8c187 379 (lambda-case (((x) #f x1 #f () (y y1) #f) (lexical x1 y1))
8a4ca0ea
AW
380 #f))
381 (program () (std-prelude 0 0 #f) (label _)
899d37a6 382 (program () (opt-prelude 1 0 1 2 #f)
8a4ca0ea
AW
383 (bind (x #f 0) (x1 #f 1)) (label _)
384 (lexical #t #f ref 1) (call return 1)
385 (unbind))
a1a482e0
AW
386 (call return 1)))
387
388 (assert-tree-il->glil
8a4ca0ea 389 (lambda ()
b0c8c187 390 (lambda-case (((x) #f #f #f () (x1) #f)
8a4ca0ea 391 (lambda ()
b0c8c187 392 (lambda-case (((y) #f #f #f () (y1) #f)
8a4ca0ea
AW
393 (lexical x x1))
394 #f)))
395 #f))
396 (program () (std-prelude 0 0 #f) (label _)
397 (program () (std-prelude 1 1 #f)
398 (bind (x #f 0)) (label _)
258344b4 399 (program () (std-prelude 1 1 #f)
8a4ca0ea
AW
400 (bind (y #f 0)) (label _)
401 (lexical #f #f ref 0) (call return 1)
402 (unbind))
66d3e9a3
AW
403 (lexical #t #f ref 0)
404 (call vector 1)
57ab0671 405 (call make-closure 2)
8a4ca0ea
AW
406 (call return 1)
407 (unbind))
ce09ee19
AW
408 (call return 1))))
409
410(with-test-prefix "sequence"
411 (assert-tree-il->glil
412 (begin (begin (const 2) (const #f)) (const #t))
8a4ca0ea 413 (program () (std-prelude 0 0 #f) (label _)
ce09ee19
AW
414 (const #t) (call return 1)))
415
416 (assert-tree-il->glil
417 (apply (primitive null?) (begin (const #f) (const 2)))
8a4ca0ea 418 (program () (std-prelude 0 0 #f) (label _)
ce09ee19 419 (const 2) (call null? 1) (call return 1))))
5af166bd
AW
420
421;; FIXME: binding info for or-hacked locals might bork the disassembler,
422;; and could be tightened in any case
423(with-test-prefix "the or hack"
8a4ca0ea 424 (assert-tree-il->glil
5af166bd
AW
425 (let (x) (y) ((const 1))
426 (if (lexical x y)
427 (lexical x y)
428 (let (a) (b) ((const 2))
429 (lexical a b))))
8a4ca0ea 430 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
431 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
432 (lexical #t #f ref 0) (branch br-if-not ,l1)
433 (lexical #t #f ref 0) (call return 1)
5af166bd 434 (label ,l2)
66d3e9a3
AW
435 (const 2) (bind (a #f 0)) (lexical #t #f set 0)
436 (lexical #t #f ref 0) (call return 1)
5af166bd
AW
437 (unbind)
438 (unbind))
439 (eq? l1 l2))
440
aaae0d5a 441 ;; second bound var is unreferenced
8a4ca0ea 442 (assert-tree-il->glil
5af166bd
AW
443 (let (x) (y) ((const 1))
444 (if (lexical x y)
445 (lexical x y)
446 (let (a) (b) ((const 2))
447 (lexical x y))))
8a4ca0ea 448 (program () (std-prelude 0 1 #f) (label _)
66d3e9a3
AW
449 (const 1) (bind (x #f 0)) (lexical #t #f set 0)
450 (lexical #t #f ref 0) (branch br-if-not ,l1)
451 (lexical #t #f ref 0) (call return 1)
5af166bd 452 (label ,l2)
66d3e9a3 453 (lexical #t #f ref 0) (call return 1)
5af166bd
AW
454 (unbind))
455 (eq? l1 l2)))
0f423f20
AW
456
457(with-test-prefix "apply"
458 (assert-tree-il->glil
459 (apply (primitive @apply) (toplevel foo) (toplevel bar))
8a4ca0ea
AW
460 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (toplevel ref bar) (call goto/apply 2)))
461 (assert-tree-il->glil
0f423f20 462 (begin (apply (primitive @apply) (toplevel foo) (toplevel bar)) (void))
8a4ca0ea 463 (program () (std-prelude 0 0 #f) (label _)
b7946e9e 464 (call new-frame 0) (toplevel ref apply) (toplevel ref foo) (toplevel ref bar) (mv-call 2 ,l1)
0f423f20
AW
465 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind () #f) (unbind)
466 (label ,l4)
467 (void) (call return 1))
468 (and (eq? l1 l3) (eq? l2 l4)))
469 (assert-tree-il->glil
470 (apply (toplevel foo) (apply (toplevel @apply) (toplevel bar) (toplevel baz)))
8a4ca0ea 471 (program () (std-prelude 0 0 #f) (label _)
0f423f20 472 (toplevel ref foo)
b7946e9e 473 (call new-frame 0) (toplevel ref bar) (toplevel ref baz) (call apply 2)
0f423f20
AW
474 (call goto/args 1))))
475
476(with-test-prefix "call/cc"
477 (assert-tree-il->glil
478 (apply (primitive @call-with-current-continuation) (toplevel foo))
8a4ca0ea
AW
479 (program () (std-prelude 0 0 #f) (label _) (toplevel ref foo) (call goto/cc 1)))
480 (assert-tree-il->glil
0f423f20 481 (begin (apply (primitive @call-with-current-continuation) (toplevel foo)) (void))
8a4ca0ea 482 (program () (std-prelude 0 0 #f) (label _)
b7946e9e 483 (call new-frame 0) (toplevel ref call-with-current-continuation) (toplevel ref foo) (mv-call 1 ,l1)
0f423f20
AW
484 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind () #f) (unbind)
485 (label ,l4)
486 (void) (call return 1))
487 (and (eq? l1 l3) (eq? l2 l4)))
488 (assert-tree-il->glil
489 (apply (toplevel foo)
490 (apply (toplevel @call-with-current-continuation) (toplevel bar)))
8a4ca0ea 491 (program () (std-prelude 0 0 #f) (label _)
0f423f20
AW
492 (toplevel ref foo)
493 (toplevel ref bar) (call call/cc 1)
494 (call goto/args 1))))
495
f4aa0f10
LC
496\f
497(with-test-prefix "tree-il-fold"
498
499 (pass-if "empty tree"
500 (let ((leaf? #f) (up? #f) (down? #f) (mark (list 'mark)))
501 (and (eq? mark
502 (tree-il-fold (lambda (x y) (set! leaf? #t) y)
503 (lambda (x y) (set! down? #t) y)
504 (lambda (x y) (set! up? #t) y)
505 mark
506 '()))
507 (not leaf?)
508 (not up?)
509 (not down?))))
510
511 (pass-if "lambda and application"
512 (let* ((leaves '()) (ups '()) (downs '())
513 (result (tree-il-fold (lambda (x y)
514 (set! leaves (cons x leaves))
515 (1+ y))
516 (lambda (x y)
517 (set! downs (cons x downs))
518 (1+ y))
519 (lambda (x y)
520 (set! ups (cons x ups))
521 (1+ y))
522 0
523 (parse-tree-il
8a4ca0ea
AW
524 '(lambda ()
525 (lambda-case
b0c8c187 526 (((x y) #f #f #f () (x1 y1) #f)
8a4ca0ea
AW
527 (apply (toplevel +)
528 (lexical x x1)
529 (lexical y y1)))
530 #f))))))
f4aa0f10
LC
531 (and (equal? (map strip-source leaves)
532 (list (make-lexical-ref #f 'y 'y1)
533 (make-lexical-ref #f 'x 'x1)
534 (make-toplevel-ref #f '+)))
8a4ca0ea 535 (= (length downs) 3)
f4aa0f10
LC
536 (equal? (reverse (map strip-source ups))
537 (map strip-source downs))))))
4b856371
LC
538
539\f
540;;;
541;;; Warnings.
542;;;
543
544;; Make sure we get English messages.
545(setlocale LC_ALL "C")
546
547(define (call-with-warnings thunk)
548 (let ((port (open-output-string)))
549 (with-fluid* *current-warning-port* port
550 thunk)
551 (let ((warnings (get-output-string port)))
552 (string-tokenize warnings
553 (char-set-complement (char-set #\newline))))))
554
555(define %opts-w-unused
556 '(#:warnings (unused-variable)))
557
f67ddf9d
LC
558(define %opts-w-unbound
559 '(#:warnings (unbound-variable)))
4b856371 560
ae03cf1f
LC
561(define %opts-w-arity
562 '(#:warnings (arity-mismatch)))
563
564
4b856371
LC
565(with-test-prefix "warnings"
566
567 (pass-if "unknown warning type"
568 (let ((w (call-with-warnings
569 (lambda ()
570 (compile #t #:opts '(#:warnings (does-not-exist)))))))
571 (and (= (length w) 1)
572 (number? (string-contains (car w) "unknown warning")))))
573
574 (with-test-prefix "unused-variable"
575
576 (pass-if "quiet"
577 (null? (call-with-warnings
578 (lambda ()
579 (compile '(lambda (x y) (+ x y))
580 #:opts %opts-w-unused)))))
581
582 (pass-if "let/unused"
583 (let ((w (call-with-warnings
584 (lambda ()
585 (compile '(lambda (x)
586 (let ((y (+ x 2)))
587 x))
588 #:opts %opts-w-unused)))))
589 (and (= (length w) 1)
590 (number? (string-contains (car w) "unused variable `y'")))))
591
592 (pass-if "shadowed variable"
593 (let ((w (call-with-warnings
594 (lambda ()
595 (compile '(lambda (x)
596 (let ((y x))
597 (let ((y (+ x 2)))
598 (+ x y))))
599 #:opts %opts-w-unused)))))
600 (and (= (length w) 1)
601 (number? (string-contains (car w) "unused variable `y'")))))
602
603 (pass-if "letrec"
604 (null? (call-with-warnings
605 (lambda ()
606 (compile '(lambda ()
607 (letrec ((x (lambda () (y)))
608 (y (lambda () (x))))
609 y))
610 #:opts %opts-w-unused)))))
611
612 (pass-if "unused argument"
613 ;; Unused arguments should not be reported.
614 (null? (call-with-warnings
615 (lambda ()
616 (compile '(lambda (x y z) #t)
f67ddf9d
LC
617 #:opts %opts-w-unused))))))
618
619 (with-test-prefix "unbound variable"
620
621 (pass-if "quiet"
622 (null? (call-with-warnings
623 (lambda ()
624 (compile '+ #:opts %opts-w-unbound)))))
625
626 (pass-if "ref"
627 (let* ((v (gensym))
628 (w (call-with-warnings
629 (lambda ()
630 (compile v
631 #:to 'assembly
632 #:opts %opts-w-unbound)))))
633 (and (= (length w) 1)
634 (number? (string-contains (car w)
635 (format #f "unbound variable `~A'"
636 v))))))
637
638 (pass-if "set!"
639 (let* ((v (gensym))
640 (w (call-with-warnings
641 (lambda ()
642 (compile `(set! ,v 7)
643 #:to 'assembly
644 #:opts %opts-w-unbound)))))
645 (and (= (length w) 1)
646 (number? (string-contains (car w)
647 (format #f "unbound variable `~A'"
648 v))))))
649
650 (pass-if "module-local top-level is visible"
651 (let ((m (make-module))
652 (v (gensym)))
653 (beautify-user-module! m)
654 (compile `(define ,v 123)
655 #:env m #:opts %opts-w-unbound)
656 (null? (call-with-warnings
657 (lambda ()
658 (compile v
659 #:env m
660 #:to 'assembly
661 #:opts %opts-w-unbound))))))
662
663 (pass-if "module-local top-level is visible after"
664 (let ((m (make-module))
665 (v (gensym)))
666 (beautify-user-module! m)
667 (null? (call-with-warnings
668 (lambda ()
669 (let ((in (open-input-string
670 "(define (f)
671 (set! chbouib 3))
672 (define chbouib 5)")))
b6d2306d
LC
673 (read-and-compile in
674 #:env m
675 #:opts %opts-w-unbound)))))))
676
677 (pass-if "GOOPS definitions are visible"
678 (let ((m (make-module))
679 (v (gensym)))
680 (beautify-user-module! m)
681 (module-use! m (resolve-interface '(oop goops)))
682 (null? (call-with-warnings
683 (lambda ()
684 (let ((in (open-input-string
685 "(define-class <foo> ()
686 (bar #:getter foo-bar))
687 (define z (foo-bar (make <foo>)))")))
f67ddf9d
LC
688 (read-and-compile in
689 #:env m
ae03cf1f
LC
690 #:opts %opts-w-unbound))))))))
691
692 (with-test-prefix "arity mismatch"
693
694 (pass-if "quiet"
695 (null? (call-with-warnings
696 (lambda ()
697 (compile '(cons 'a 'b) #:opts %opts-w-arity)))))
698
699 (pass-if "direct application"
700 (let ((w (call-with-warnings
701 (lambda ()
702 (compile '((lambda (x y) (or x y)) 1 2 3 4 5)
703 #:opts %opts-w-arity
704 #:to 'assembly)))))
705 (and (= (length w) 1)
706 (number? (string-contains (car w)
707 "wrong number of arguments to")))))
708 (pass-if "local"
709 (let ((w (call-with-warnings
710 (lambda ()
711 (compile '(let ((f (lambda (x y) (+ x y))))
712 (f 2))
713 #:opts %opts-w-arity
714 #:to 'assembly)))))
715 (and (= (length w) 1)
716 (number? (string-contains (car w)
717 "wrong number of arguments to")))))
718
719 (pass-if "global"
720 (let ((w (call-with-warnings
721 (lambda ()
722 (compile '(cons 1 2 3 4)
723 #:opts %opts-w-arity
724 #:to 'assembly)))))
725 (and (= (length w) 1)
726 (number? (string-contains (car w)
727 "wrong number of arguments to")))))
728
729 (pass-if "alias to global"
730 (let ((w (call-with-warnings
731 (lambda ()
732 (compile '(let ((f cons)) (f 1 2 3 4))
733 #:opts %opts-w-arity
734 #:to 'assembly)))))
735 (and (= (length w) 1)
736 (number? (string-contains (car w)
737 "wrong number of arguments to")))))
738
739 (pass-if "alias to lexical to global"
740 (let ((w (call-with-warnings
741 (lambda ()
742 (compile '(let ((f number?))
743 (let ((g f))
744 (f 1 2 3 4)))
745 #:opts %opts-w-arity
746 #:to 'assembly)))))
747 (and (= (length w) 1)
748 (number? (string-contains (car w)
749 "wrong number of arguments to")))))
750
751 (pass-if "alias to lexical"
752 (let ((w (call-with-warnings
753 (lambda ()
754 (compile '(let ((f (lambda (x y z) (+ x y z))))
755 (let ((g f))
756 (g 1)))
757 #:opts %opts-w-arity
758 #:to 'assembly)))))
759 (and (= (length w) 1)
760 (number? (string-contains (car w)
761 "wrong number of arguments to")))))
762
763 (pass-if "letrec"
764 (let ((w (call-with-warnings
765 (lambda ()
766 (compile '(letrec ((odd? (lambda (x) (even? (1- x))))
767 (even? (lambda (x)
768 (or (= 0 x)
769 (odd?)))))
770 (odd? 1))
771 #:opts %opts-w-arity
772 #:to 'assembly)))))
773 (and (= (length w) 1)
774 (number? (string-contains (car w)
775 "wrong number of arguments to")))))
776
777 (pass-if "local toplevel-defines"
778 (let ((w (call-with-warnings
779 (lambda ()
780 (let ((in (open-input-string "
781 (define (g x) (f x))
782 (define (f) 1)")))
783 (read-and-compile in
784 #:opts %opts-w-arity
785 #:to 'assembly))))))
786 (and (= (length w) 1)
787 (number? (string-contains (car w)
788 "wrong number of arguments to")))))
789
790 (pass-if "global toplevel alias"
791 (let ((w (call-with-warnings
792 (lambda ()
793 (let ((in (open-input-string "
794 (define f cons)
795 (define (g) (f))")))
796 (read-and-compile in
797 #:opts %opts-w-arity
798 #:to 'assembly))))))
799 (and (= (length w) 1)
800 (number? (string-contains (car w)
801 "wrong number of arguments to")))))
802
803 (pass-if "local toplevel overrides global"
804 (null? (call-with-warnings
805 (lambda ()
806 (let ((in (open-input-string "
807 (define (cons) 0)
808 (define (foo x) (cons))")))
809 (read-and-compile in
810 #:opts %opts-w-arity
811 #:to 'assembly))))))))