1 ;;;; tree-il.test --- test suite for compiling tree-il -*- scheme -*-
2 ;;;; Andy Wingo <wingo@pobox.com> --- May 2009
4 ;;;; Copyright (C) 2009 Free Software Foundation, Inc.
6 ;;;; This library is free software; you can redistribute it and/or
7 ;;;; modify it under the terms of the GNU Lesser General Public
8 ;;;; License as published by the Free Software Foundation; either
9 ;;;; version 3 of the License, or (at your option) any later version.
11 ;;;; This library is distributed in the hope that it will be useful,
12 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ;;;; Lesser General Public License for more details.
16 ;;;; You should have received a copy of the GNU Lesser General Public
17 ;;;; License along with this library; if not, write to the Free Software
18 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 (define-module (test-suite tree-il)
21 #:use-module (test-suite lib)
22 #:use-module (system base compile)
23 #:use-module (system base pmatch)
24 #:use-module (language tree-il)
25 #:use-module (language glil))
27 ;; Of course, the GLIL that is emitted depends on the source info of the
28 ;; input. Here we're not concerned about that, so we strip source
29 ;; information from the incoming tree-il.
31 (define (strip-source x)
32 (post-order! (lambda (x) (set! (tree-il-src x) #f))
35 (define-syntax assert-scheme->glil
38 (let ((tree-il (strip-source
39 (compile 'in #:from 'scheme #:to 'tree-il))))
41 (equal? (unparse-glil (compile tree-il #:from 'tree-il #:to 'glil))
44 (define-syntax assert-tree-il->glil
48 (let ((tree-il (strip-source (parse-tree-il 'in))))
49 (equal? (unparse-glil (compile tree-il #:from 'tree-il #:to 'glil))
52 (define-syntax assert-tree-il->glil/pmatch
57 (let ((glil (unparse-glil
58 (compile (strip-source (parse-tree-il exp))
59 #:from 'tree-il #:to 'glil))))
61 (pat (guard test ...) #t)
64 (with-test-prefix "void"
67 (program 0 0 0 0 () (void) (call return 1)))
69 (begin (void) (const 1))
70 (program 0 0 0 0 () (const 1) (call return 1)))
72 (apply (primitive +) (void) (const 1))
73 (program 0 0 0 0 () (void) (const 1) (call add 2) (call return 1))))
75 (with-test-prefix "application"
77 (apply (toplevel foo) (const 1))
78 (program 0 0 0 0 () (toplevel ref foo) (const 1) (call goto/args 1)))
79 (assert-tree-il->glil/pmatch
80 (begin (apply (toplevel foo) (const 1)) (void))
81 (program 0 0 0 0 () (toplevel ref foo) (const 1) (mv-call 1 ,l1)
82 (call drop 1) (branch br ,l2)
83 (label ,l3) (mv-bind () #f) (unbind)
85 (void) (call return 1))
86 (and (eq? l1 l3) (eq? l2 l4)))
88 (apply (toplevel foo) (apply (toplevel bar)))
89 (program 0 0 0 0 () (toplevel ref foo) (toplevel ref bar) (call call 0)
92 (with-test-prefix "conditional"
93 (assert-tree-il->glil/pmatch
94 (if (const #t) (const 1) (const 2))
95 (program 0 0 0 0 () (const #t) (branch br-if-not ,l1)
96 (const 1) (call return 1)
97 (label ,l2) (const 2) (call return 1))
100 (assert-tree-il->glil/pmatch
101 (begin (if (const #t) (const 1) (const 2)) (const #f))
102 (program 0 0 0 0 () (const #t) (branch br-if-not ,l1) (branch br ,l2)
103 (label ,l3) (label ,l4) (const #f) (call return 1))
104 (eq? l1 l3) (eq? l2 l4))
106 (assert-tree-il->glil/pmatch
107 (apply (primitive null?) (if (const #t) (const 1) (const 2)))
108 (program 0 0 0 0 () (const #t) (branch br-if-not ,l1)
109 (const 1) (branch br ,l2)
110 (label ,l3) (const 2) (label ,l4)
111 (call null? 1) (call return 1))
112 (eq? l1 l3) (eq? l2 l4)))
114 (with-test-prefix "primitive-ref"
115 (assert-tree-il->glil
117 (program 0 0 0 0 () (toplevel ref +) (call return 1)))
119 (assert-tree-il->glil
120 (begin (primitive +) (const #f))
121 (program 0 0 0 0 () (const #f) (call return 1)))
123 (assert-tree-il->glil
124 (apply (primitive null?) (primitive +))
125 (program 0 0 0 0 () (toplevel ref +) (call null? 1)
128 (with-test-prefix "lexical refs"
129 (assert-tree-il->glil
130 (let (x) (y) ((const 1)) (lexical x y))
132 (const 1) (bind (x local 0)) (local set 0)
133 (local ref 0) (call return 1)
136 (assert-tree-il->glil
137 (let (x) (y) ((const 1)) (begin (lexical x y) (const #f)))
139 (const 1) (bind (x local 0)) (local set 0)
140 (const #f) (call return 1)
143 (assert-tree-il->glil
144 (let (x) (y) ((const 1)) (apply (primitive null?) (lexical x y)))
146 (const 1) (bind (x local 0)) (local set 0)
147 (local ref 0) (call null? 1) (call return 1)
150 (with-test-prefix "lexical sets"
151 (assert-tree-il->glil
152 (let (x) (y) ((const 1)) (set! (lexical x y) (const 2)))
154 (const 1) (bind (x external 0)) (external set 0 0)
155 (const 2) (external set 0 0) (void) (call return 1)
158 (assert-tree-il->glil
159 (let (x) (y) ((const 1)) (begin (set! (lexical x y) (const 2)) (const #f)))
161 (const 1) (bind (x external 0)) (external set 0 0)
162 (const 2) (external set 0 0) (const #f) (call return 1)
165 (assert-tree-il->glil
166 (let (x) (y) ((const 1))
167 (apply (primitive null?) (set! (lexical x y) (const 2))))
169 (const 1) (bind (x external 0)) (external set 0 0)
170 (const 2) (external set 0 0) (void) (call null? 1) (call return 1)
173 (with-test-prefix "module refs"
174 (assert-tree-il->glil
177 (module public ref (foo) bar)
180 (assert-tree-il->glil
181 (begin (@ (foo) bar) (const #f))
183 (module public ref (foo) bar) (call drop 1)
184 (const #f) (call return 1)))
186 (assert-tree-il->glil
187 (apply (primitive null?) (@ (foo) bar))
189 (module public ref (foo) bar)
190 (call null? 1) (call return 1)))
192 (assert-tree-il->glil
195 (module private ref (foo) bar)
198 (assert-tree-il->glil
199 (begin (@@ (foo) bar) (const #f))
201 (module private ref (foo) bar) (call drop 1)
202 (const #f) (call return 1)))
204 (assert-tree-il->glil
205 (apply (primitive null?) (@@ (foo) bar))
207 (module private ref (foo) bar)
208 (call null? 1) (call return 1))))
210 (with-test-prefix "module sets"
211 (assert-tree-il->glil
212 (set! (@ (foo) bar) (const 2))
214 (const 2) (module public set (foo) bar)
215 (void) (call return 1)))
217 (assert-tree-il->glil
218 (begin (set! (@ (foo) bar) (const 2)) (const #f))
220 (const 2) (module public set (foo) bar)
221 (const #f) (call return 1)))
223 (assert-tree-il->glil
224 (apply (primitive null?) (set! (@ (foo) bar) (const 2)))
226 (const 2) (module public set (foo) bar)
227 (void) (call null? 1) (call return 1)))
229 (assert-tree-il->glil
230 (set! (@@ (foo) bar) (const 2))
232 (const 2) (module private set (foo) bar)
233 (void) (call return 1)))
235 (assert-tree-il->glil
236 (begin (set! (@@ (foo) bar) (const 2)) (const #f))
238 (const 2) (module private set (foo) bar)
239 (const #f) (call return 1)))
241 (assert-tree-il->glil
242 (apply (primitive null?) (set! (@@ (foo) bar) (const 2)))
244 (const 2) (module private set (foo) bar)
245 (void) (call null? 1) (call return 1))))
247 (with-test-prefix "toplevel refs"
248 (assert-tree-il->glil
254 (assert-tree-il->glil
255 (begin (toplevel bar) (const #f))
257 (toplevel ref bar) (call drop 1)
258 (const #f) (call return 1)))
260 (assert-tree-il->glil
261 (apply (primitive null?) (toplevel bar))
264 (call null? 1) (call return 1))))
266 (with-test-prefix "toplevel sets"
267 (assert-tree-il->glil
268 (set! (toplevel bar) (const 2))
270 (const 2) (toplevel set bar)
271 (void) (call return 1)))
273 (assert-tree-il->glil
274 (begin (set! (toplevel bar) (const 2)) (const #f))
276 (const 2) (toplevel set bar)
277 (const #f) (call return 1)))
279 (assert-tree-il->glil
280 (apply (primitive null?) (set! (toplevel bar) (const 2)))
282 (const 2) (toplevel set bar)
283 (void) (call null? 1) (call return 1))))
285 (with-test-prefix "toplevel defines"
286 (assert-tree-il->glil
287 (define bar (const 2))
289 (const 2) (toplevel define bar)
290 (void) (call return 1)))
292 (assert-tree-il->glil
293 (begin (define bar (const 2)) (const #f))
295 (const 2) (toplevel define bar)
296 (const #f) (call return 1)))
298 (assert-tree-il->glil
299 (apply (primitive null?) (define bar (const 2)))
301 (const 2) (toplevel define bar)
302 (void) (call null? 1) (call return 1))))
304 (with-test-prefix "constants"
305 (assert-tree-il->glil
308 (const 2) (call return 1)))
310 (assert-tree-il->glil
311 (begin (const 2) (const #f))
313 (const #f) (call return 1)))
315 (assert-tree-il->glil
316 (apply (primitive null?) (const 2))
318 (const 2) (call null? 1) (call return 1))))
320 (with-test-prefix "lambda"
321 (assert-tree-il->glil
322 (lambda (x) (y) () (const 2))
326 (const 2) (call return 1))
329 (assert-tree-il->glil
330 (lambda (x x1) (y y1) () (const 2))
333 (bind (x local 0) (x1 local 1))
334 (const 2) (call return 1))
337 (assert-tree-il->glil
338 (lambda x y () (const 2))
342 (const 2) (call return 1))
345 (assert-tree-il->glil
346 (lambda (x . x1) (y . y1) () (const 2))
349 (bind (x local 0) (x1 local 1))
350 (const 2) (call return 1))
353 (assert-tree-il->glil
354 (lambda (x . x1) (y . y1) () (lexical x y))
357 (bind (x local 0) (x1 local 1))
358 (local ref 0) (call return 1))
361 (assert-tree-il->glil
362 (lambda (x . x1) (y . y1) () (lexical x1 y1))
365 (bind (x local 0) (x1 local 1))
366 (local ref 1) (call return 1))
369 (assert-tree-il->glil
370 (lambda (x) (x1) () (lambda (y) (y1) () (lexical x x1)))
373 (bind (x external 0))
374 (local ref 0) (external set 0 0)
377 (external ref 1 0) (call return 1))
381 (with-test-prefix "sequence"
382 (assert-tree-il->glil
383 (begin (begin (const 2) (const #f)) (const #t))
385 (const #t) (call return 1)))
387 (assert-tree-il->glil
388 (apply (primitive null?) (begin (const #f) (const 2)))
390 (const 2) (call null? 1) (call return 1))))
392 ;; FIXME: binding info for or-hacked locals might bork the disassembler,
393 ;; and could be tightened in any case
394 (with-test-prefix "the or hack"
395 (assert-tree-il->glil/pmatch
396 (let (x) (y) ((const 1))
399 (let (a) (b) ((const 2))
402 (const 1) (bind (x local 0)) (local set 0)
403 (local ref 0) (branch br-if-not ,l1)
404 (local ref 0) (call return 1)
406 (const 2) (bind (a local 0)) (local set 0)
407 (local ref 0) (call return 1)
412 (assert-tree-il->glil/pmatch
413 (let (x) (y) ((const 1))
416 (let (a) (b) ((const 2))
419 (const 1) (bind (x local 0)) (local set 0)
420 (local ref 0) (branch br-if-not ,l1)
421 (local ref 0) (call return 1)
423 (const 2) (bind (a local 1)) (local set 1)
424 (local ref 0) (call return 1)
429 (with-test-prefix "apply"
430 (assert-tree-il->glil
431 (apply (primitive @apply) (toplevel foo) (toplevel bar))
432 (program 0 0 0 0 () (toplevel ref foo) (toplevel ref bar) (call goto/apply 2)))
433 (assert-tree-il->glil/pmatch
434 (begin (apply (primitive @apply) (toplevel foo) (toplevel bar)) (void))
436 (toplevel ref apply) (toplevel ref foo) (toplevel ref bar) (mv-call 2 ,l1)
437 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind () #f) (unbind)
439 (void) (call return 1))
440 (and (eq? l1 l3) (eq? l2 l4)))
441 (assert-tree-il->glil
442 (apply (toplevel foo) (apply (toplevel @apply) (toplevel bar) (toplevel baz)))
445 (toplevel ref bar) (toplevel ref baz) (call apply 2)
446 (call goto/args 1))))
448 (with-test-prefix "call/cc"
449 (assert-tree-il->glil
450 (apply (primitive @call-with-current-continuation) (toplevel foo))
451 (program 0 0 0 0 () (toplevel ref foo) (call goto/cc 1)))
452 (assert-tree-il->glil/pmatch
453 (begin (apply (primitive @call-with-current-continuation) (toplevel foo)) (void))
455 (toplevel ref call-with-current-continuation) (toplevel ref foo) (mv-call 1 ,l1)
456 (call drop 1) (branch br ,l2) (label ,l3) (mv-bind () #f) (unbind)
458 (void) (call return 1))
459 (and (eq? l1 l3) (eq? l2 l4)))
460 (assert-tree-il->glil
461 (apply (toplevel foo)
462 (apply (toplevel @call-with-current-continuation) (toplevel bar)))
465 (toplevel ref bar) (call call/cc 1)
466 (call goto/args 1))))