1 ;;;; eval.test --- tests guile's evaluator -*- scheme -*-
2 ;;;; Copyright (C) 2000, 2001, 2006, 2007 Free Software Foundation, Inc.
4 ;;;; This library is free software; you can redistribute it and/or
5 ;;;; modify it under the terms of the GNU Lesser General Public
6 ;;;; License as published by the Free Software Foundation; either
7 ;;;; version 2.1 of the License, or (at your option) any later version.
9 ;;;; This library is distributed in the hope that it will be useful,
10 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ;;;; Lesser General Public License for more details.
14 ;;;; You should have received a copy of the GNU Lesser General Public
15 ;;;; License along with this library; if not, write to the Free Software
16 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 (define-module (test-suite test-eval)
19 :use-module (test-suite lib)
20 :use-module (ice-9 documentation))
23 (define exception:bad-expression
24 (cons 'syntax-error "Bad expression"))
31 (define (documented? object)
32 (not (not (object-documentation object))))
39 (with-test-prefix "memoization"
41 (with-test-prefix "copy-tree"
43 (pass-if "(#t . #(#t))"
44 (let* ((foo (cons #t (vector #t)))
45 (bar (copy-tree foo)))
46 (vector-set! (cdr foo) 0 #f)
47 (equal? bar '(#t . #(#t)))))
49 (pass-if-exception "circular lists in forms"
50 exception:bad-expression
51 (let ((foo (list #f)))
55 (pass-if "transparency"
57 (eval x (current-module))
58 (equal? '(begin 1) x))))
65 (with-test-prefix "evaluator"
67 (with-test-prefix "symbol lookup"
69 (with-test-prefix "top level"
71 (with-test-prefix "unbound"
73 (pass-if-exception "variable reference"
77 (pass-if-exception "procedure"
81 (with-test-prefix "parameter error"
83 ;; This is currently a bug in guile:
84 ;; Macros are accepted as function parameters.
85 ;; Functions that 'apply' macros are rewritten!!!
87 (expect-fail-exception "macro as argument"
88 exception:wrong-type-arg
89 (let ((f (lambda (p a b) (p a b))))
92 (expect-fail-exception "passing macro as parameter"
93 exception:wrong-type-arg
94 (let* ((f (lambda (p a b) (p a b)))
95 (foo (procedure-source f)))
97 (equal? (procedure-source f) foo)))
105 (with-test-prefix "call"
107 (with-test-prefix "wrong number of arguments"
109 (pass-if-exception "((lambda () #f) 1)"
110 exception:wrong-num-args
113 (pass-if-exception "((lambda (x) #f))"
114 exception:wrong-num-args
117 (pass-if-exception "((lambda (x) #f) 1 2)"
118 exception:wrong-num-args
119 ((lambda (x) #f) 1 2))
121 (pass-if-exception "((lambda (x y) #f))"
122 exception:wrong-num-args
125 (pass-if-exception "((lambda (x y) #f) 1)"
126 exception:wrong-num-args
127 ((lambda (x y) #f) 1))
129 (pass-if-exception "((lambda (x y) #f) 1 2 3)"
130 exception:wrong-num-args
131 ((lambda (x y) #f) 1 2 3))
133 (pass-if-exception "((lambda (x . rest) #f))"
134 exception:wrong-num-args
135 ((lambda (x . rest) #f)))
137 (pass-if-exception "((lambda (x y . rest) #f))"
138 exception:wrong-num-args
139 ((lambda (x y . rest) #f)))
141 (pass-if-exception "((lambda (x y . rest) #f) 1)"
142 exception:wrong-num-args
143 ((lambda (x y . rest) #f) 1))))
149 (with-test-prefix "apply"
151 (with-test-prefix "scm_tc7_subr_2o"
153 ;; prior to guile 1.6.9 and 1.8.1 this called the function with
154 ;; SCM_UNDEFIEND, which in the case of make-vector resulted in
155 ;; wrong-type-arg, instead of the intended wrong-num-args
156 (pass-if-exception "0 args" exception:wrong-num-args
157 (apply make-vector '()))
160 (vector? (apply make-vector '(1))))
163 (vector? (apply make-vector '(1 2))))
165 ;; prior to guile 1.6.9 and 1.8.1 this error wasn't detected
166 (pass-if-exception "3 args" exception:wrong-num-args
167 (apply make-vector '(1 2 3)))))
173 (with-test-prefix "map"
175 ;; Is documentation available?
177 (expect-fail "documented?"
180 (with-test-prefix "argument error"
182 (with-test-prefix "non list argument"
185 (with-test-prefix "different length lists"
187 (pass-if-exception "first list empty"
188 exception:out-of-range
191 (pass-if-exception "second list empty"
192 exception:out-of-range
195 (pass-if-exception "first list shorter"
196 exception:out-of-range
199 (pass-if-exception "second list shorter"
200 exception:out-of-range
205 ;;; define with procedure-name
208 (define old-procnames-flag (memq 'procnames (debug-options)))
209 (debug-enable 'procnames)
211 ;; names are only set on top-level procedures (currently), so these can't be
214 (define foo-closure (lambda () "hello"))
215 (define bar-closure foo-closure)
216 ;; make sure that make-procedure-with-setter returns an anonymous
217 ;; procedure-with-setter by passing it an anonymous getter.
218 (define foo-pws (make-procedure-with-setter
220 (lambda (x y) (set-car! x y))))
221 (define bar-pws foo-pws)
223 (with-test-prefix "define set procedure-name"
226 (eq? 'foo-closure (procedure-name bar-closure)))
228 (pass-if "procedure-with-setter"
229 (eq? 'foo-pws (procedure-name bar-pws))))
231 (if old-procnames-flag
232 (debug-enable 'procnames)
233 (debug-disable 'procnames))
239 (with-test-prefix "promises"
241 (with-test-prefix "basic promise behaviour"
243 (pass-if "delay gives a promise"
244 (promise? (delay 1)))
246 (pass-if "force evaluates a promise"
247 (eqv? (force (delay (+ 1 2))) 3))
249 (pass-if "a forced promise is a promise"
250 (let ((p (delay (+ 1 2))))
254 (pass-if "forcing a forced promise works"
255 (let ((p (delay (+ 1 2))))
259 (pass-if "a promise is evaluated once"
266 (pass-if "a promise may call itself"
272 (if (> x 1) x (force p))))))
275 (pass-if "a promise carries its environment"
278 (set! p (delay (+ x 1))))
281 (pass-if "a forced promise does not reference its environment"
282 (let* ((g (make-guardian))
284 (let* ((x (cons #f #f)))
286 (set! p (delay (car x))))
289 (if (not (equal? (g) (cons #f #f)))
293 (with-test-prefix "extended promise behaviour"
295 (pass-if-exception "forcing a non-promise object is not supported"
296 exception:wrong-type-arg
299 (pass-if-exception "implicit forcing is not supported"
300 exception:wrong-type-arg
301 (+ (delay (* 3 7)) 13))
303 ;; Tests that require the debugging evaluator...
304 (with-debugging-evaluator
306 (pass-if "unmemoizing a promise"
309 (false-if-exception (lazy-catch #t
311 (let ((f (lambda (g) (delay (g)))))
314 (set! stack (make-stack #t)))))
316 (%make-void-port "w"))
320 ;;; letrec init evaluation
323 (with-test-prefix "letrec init evaluation"
325 (pass-if "lots of inits calculated in correct order"
326 (equal? (letrec ((a 'a) (b 'b) (c 'c) (d 'd)
327 (e 'e) (f 'f) (g 'g) (h 'h)
328 (i 'i) (j 'j) (k 'k) (l 'l)
329 (m 'm) (n 'n) (o 'o) (p 'p)
330 (q 'q) (r 'r) (s 's) (t 't)
331 (u 'u) (v 'v) (w 'w) (x 'x)
333 (list a b c d e f g h i j k l m
334 n o p q r s t u v w x y z))
335 '(a b c d e f g h i j k l m
336 n o p q r s t u v w x y z))))
342 (with-test-prefix "values"
344 (pass-if "single value"
345 (equal? 1 (values 1)))
347 (pass-if "call-with-values"
348 (equal? (call-with-values (lambda () (values 1 2 3 4)) list)
352 (equal? (values 1 2 3 4) (values 1 2 3 4))))
354 ;;; eval.test ends here