1
;;;; r5rs_pitfall.test --- tests some pitfalls in R5RS -*- scheme -*-
2
;;;; Copyright (C) 2003, 2004, 2006 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
;; These tests have been copied from
19
;; http://sisc.sourceforge.net/r5rs_pitfall.scm and the 'should-be'
20
;; macro has been modified to fit into our test suite machinery.
22
(define-module (test-suite test-r5rs-pitfall)
23
:use-syntax (ice-9 syncase)
24
:use-module (test-suite lib))
26
(define-syntax should-be
28
((_ test-id value expression)
29
(run-test test-id #t (lambda ()
31
(equal? expression value)))))))
33
(define-syntax should-be-but-isnt
35
((_ test-id value expression)
36
(run-test test-id #f (lambda ()
38
(equal? expression value)))))))
40
(define call/cc call-with-current-continuation)
42
;; Section 1: Proper letrec implementation
44
;;Credits to Al Petrofsky
46
;; defines in letrec body
47
;; http://groups.google.com/groups?selm=87bsoq0wfk.fsf%40app.dial.idiom.com
51
(letrec ((x (call-with-current-continuation (lambda (c) (set! cont c) 0)))
52
(y (call-with-current-continuation (lambda (c) (set! cont c) 0))))
61
;;Credits to Al Petrofsky
63
;; Widespread bug (arguably) in letrec when an initializer returns twice
64
;; http://groups.google.com/groups?selm=87d793aacz.fsf_-_%40app.dial.idiom.com
66
(letrec ((x (call/cc list)) (y (call/cc list)))
67
(cond ((procedure? x) (x (pair? y)))
68
((procedure? y) (y (pair? x))))
69
(let ((x (car x)) (y (car y)))
70
(and (call/cc x) (call/cc y) (call/cc x)))))
72
;;Credits to Alan Bawden
74
;; LETREC + CALL/CC = SET! even in a limited setting
75
;; http://groups.google.com/groups?selm=19890302162742.4.ALAN%40PIGPEN.AI.MIT.EDU
77
(letrec ((x (call-with-current-continuation
81
((cadr x) (list #F (lambda () x)))
84
;; Section 2: Proper call/cc and procedure application
86
;;Credits to Al Petrofsky, (and a wink to Matthias Blume)
88
;; Widespread bug in handling (call/cc (lambda (c) (0 (c 1)))) => 1
89
;; http://groups.google.com/groups?selm=87g00y4b6l.fsf%40radish.petrofsky.org
91
(call/cc (lambda (c) (0 (c 1)))))
93
;; Section 3: Hygienic macros
98
;; http://groups.google.com/groups?selm=skitsdqjq3.fsf%40tulare.cs.cornell.edu
102
((_ expr) (+ expr 1)))))
107
;; Al Petrofsky again
109
;; Buggy use of begin in r5rs cond and case macros.
110
;; http://groups.google.com/groups?selm=87bse3bznr.fsf%40radish.petrofsky.org
112
(let-syntax ((foo (syntax-rules ()
113
((_ var) (define var 1)))))
115
(begin (define foo +))
116
(cond (else (foo x)))
121
;; An Advanced syntax-rules Primer for the Mildly Insane
122
;; http://groups.google.com/groups?selm=87it8db0um.fsf@radish.petrofsky.org
127
((foo (syntax-rules ()
129
((bar (syntax-rules ()
130
((_) (let ((x 2)) y)))))
135
;; Contributed directly
137
(let-syntax ((x (syntax-rules ()))) 1))
139
;; Setion 4: No identifiers are reserved
143
;; shadowing syntatic keywords, bug in MIT Scheme?
144
;; http://groups.google.com/groups?selm=6e6n88%248qf%241%40news.cc.ukans.edu
146
((lambda lambda lambda) 'x))
148
(should-be 4.2 '(1 2 3)
149
((lambda (begin) (begin 1 2 3)) (lambda lambda lambda)))
152
(let ((quote -)) (eqv? '1 1)))
153
;; Section 5: #f/() distinctness
163
;; Section 6: string->symbol case sensitivity
167
;; Symbols in DrScheme - bug?
168
;; http://groups.google.com/groups?selm=3be55b4f%240%24358%24edfadb0f%40dspool01.news.tele.dk
170
(eq? (string->symbol "f") (string->symbol "F")))
172
;; Section 7: First class continuations
175
;; No newsgroup posting associated. The jist of this test and 7.2
176
;; is that once captured, a continuation should be unmodified by the
177
;; invocation of other continuations. This test determines that this is
178
;; the case by capturing a continuation and setting it aside in a temporary
179
;; variable while it invokes that and another continuation, trying to
180
;; side effect the first continuation. This test case was developed when
181
;; testing SISC 1.7's lazy CallFrame unzipping code.
189
(set! r (+ 1 (+ 2 (+ 3 (call/cc (lambda (k) (set! a k) 4))))
190
(+ 5 (+ 6 (call/cc (lambda (k) (set! b k) 7))))))
201
;; Same test, but in reverse order
209
(set! r (+ 1 (+ 2 (+ 3 (call/cc (lambda (k) (set! a k) 4))))
210
(+ 5 (+ 6 (call/cc (lambda (k) (set! b k) 7))))))
221
;; Credits to Matthias Radestock
222
;; Another test case used to test SISC's lazy CallFrame routines.
223
(should-be 7.3 '((-1 4 5 3)
233
(define (identity x) x)
235
((identity (if (= state 0)
236
(call/cc (lambda (k) (set! k1 k) +))
238
(identity (if (= state 0)
239
(call/cc (lambda (k) (set! k2 k) 1))
241
(identity (if (= state 0)
242
(call/cc (lambda (k) (set! k3 k) 2))
244
(define (check states)
248
(set! res (cons r res))
251
(begin (set! state (car states))
252
(set! states (cdr states))
257
(map check '((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)))))
259
;; Modification of the yin-yang puzzle so that it terminates and produces
260
;; a value as a result. (Scott G. Miller)
261
(should-be 7.4 '(10 9 8 7 6 5 4 3 2 1 0)
266
(let* ((yin ((lambda (foo)
273
(call/cc (lambda (bar) bar))))
277
(call/cc (lambda (baz) baz)))))
284
;; R5RS Implementors Pitfalls
285
;; http://groups.google.com/groups?selm=871zemtmd4.fsf@app.dial.idiom.com
287
(let - ((n (- 1))) n))
289
(should-be 8.2 '(1 2 3 4 1 2 3 4 5)
290
(let ((ls (list 1 2 3 4)))
291
(append ls ls '(5))))
293
;;Not really an error to fail this (Matthias Radestock)
294
;;If this returns (0 1 0), your map isn't call/cc safe, but is probably
295
;;tail-recursive. If its (0 0 0), the opposite is true.
296
(should-be 8.3 '(0 1 0)
298
(define executed-k #f)
302
(set! res1 (map (lambda (x)
304
(call/cc (lambda (k) (set! cont k) 0))
308
(begin (set! executed-k #t)