mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-23 22:20:24 -08:00
414 lines
11 KiB
Scheme
414 lines
11 KiB
Scheme
;;; test-r5rs.scm -- tests from R5RS
|
|
;;;
|
|
;;; This file contains test code derived directly from R5RS. It
|
|
;;; ensures that all the functions correctly evaluate the examples in
|
|
;;; R5RS.
|
|
;;;
|
|
;;; Tests that rely on features that are unimplemented in the toy
|
|
;;; Scheme interpreter distributed with the MPS are marked "UNIMPL".
|
|
;;;
|
|
;;; DOCUMENT HISTORY
|
|
;;;
|
|
;;; 2004-07-27 RB Added document history and Perforce Id keyword.
|
|
;;; 2011-06-11 RB Updated for Ruse/SC.
|
|
;;; 2012-11-01 GDR Updated for toy Scheme in MPS kit.
|
|
|
|
(load "test-common.scm")
|
|
|
|
;;; let, let*, letrec
|
|
|
|
(check '(let ((x 2) (y 3)) (* x y)) '6)
|
|
(check '(let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) (* z x))) '35)
|
|
(check '(let ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) (* z x))) '70)
|
|
(check '(letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (odd? (lambda (n) (if (zero? n) #f (even? (- n 1)))))) (even? 88)) '#t)
|
|
|
|
;;; eqv?
|
|
|
|
(check '(eqv? 'a 'a) '#t)
|
|
(check '(eqv? 'a 'b) '#f)
|
|
(check '(eqv? 2 2) '#t)
|
|
(check '(eqv? '() '()) '#t)
|
|
(check '(eqv? 100000000 100000000) '#t)
|
|
(check '(eqv? (cons 1 2) (cons 1 2)) '#f)
|
|
(check '(eqv? (lambda () 1) (lambda () 2)) '#f)
|
|
(check '(eqv? #f 'nil) '#f)
|
|
(check '(let ((p (lambda (x) x))) (eqv? p p)) '#t)
|
|
|
|
(check '(boolean? (eqv? "" "")) #t)
|
|
(check '(boolean? (eqv? '#() '#())) #t)
|
|
(check '(boolean? (eqv? (lambda (x) x) (lambda (x) x))) #t)
|
|
(check '(boolean? (eqv? (lambda (x) x) (lambda (y) y))) #t)
|
|
|
|
(define gen-counter
|
|
(lambda ()
|
|
(let ((n 0))
|
|
(lambda () (set! n (+ n 1)) n))))
|
|
(check '(let ((g (gen-counter))) (eqv? g g)) '#t)
|
|
(check '(eqv? (gen-counter) (gen-counter)) '#f)
|
|
(define gen-loser
|
|
(lambda ()
|
|
(let ((n 0))
|
|
(lambda () (set! n (+ n 1)) 27))))
|
|
(check '(let ((g (gen-loser))) (eqv? g g)) '#t)
|
|
|
|
(check '(letrec ((f (lambda () (if (eqv? f g) 'f 'both))) (g (lambda () (if (eqv? f g) 'g 'both)))) (eqv? f g)) '#f)
|
|
|
|
(check '(boolean? (eqv? '(a) '(a))) #t)
|
|
(check '(boolean? (eqv? "a" "a")) #t)
|
|
(check '(boolean? (eqv? '(b) (cdr '(a b)))) #t)
|
|
(check '(let ((x '(a))) (eqv? x x)) '#t)
|
|
|
|
;;; eq?
|
|
|
|
(check '(eq? 'a 'a) '#t)
|
|
(check '(boolean? (eq? '(a) '(a))) #t)
|
|
(check '(eq? (list 'a) (list 'a)) '#f)
|
|
(check '(boolean? (eq? "a" "a")) #t)
|
|
(check '(boolean? (eq? "" "")) #t)
|
|
(check '(eq? '() '()) '#t)
|
|
(check '(boolean? (eq? 2 2)) #t)
|
|
(check '(boolean? (eq? #\A #\A)) #t)
|
|
(check '(eq? car car) '#t)
|
|
(check '(boolean? (let ((n (+ 2 3))) (eq? n n))) #t)
|
|
(check '(let ((x '(a))) (eq? x x)) '#t)
|
|
(check '(let ((x '#())) (eq? x x)) '#t)
|
|
(check '(let ((p (lambda (x) x))) (eq? p p)) '#t)
|
|
|
|
;;; equal?
|
|
|
|
(check '(equal? 'a 'a) '#t)
|
|
(check '(equal? '(a) '(a)) '#t)
|
|
(check '(equal? '(a (b) c) '(a (b) c)) '#t)
|
|
(check '(equal? "abc" "abc") '#t)
|
|
(check '(equal? 2 2) '#t)
|
|
(check '(equal? (make-vector 5 'a) (make-vector 5 'a)) '#t)
|
|
(check '(boolean? (equal? (lambda (x) x) (lambda (y) y))) #t)
|
|
|
|
;;; Numerical operations
|
|
|
|
;; UNIMPL: (check '(complex? 3+4i) #t)
|
|
;; UNIMPL: (check '(complex? 3) #t)
|
|
;; UNIMPL: (check '(real? 3) #t)
|
|
;; UNIMPL: (check '(real? -2.5+0.0i) #t)
|
|
;; UNIMPL: (check '(real? #e1e10) #t)
|
|
;; UNIMPL: (check '(rational? 6/10) #t)
|
|
;; UNIMPL: (check '(rational? 6/3) #t)
|
|
;; UNIMPL: (check '(integer? 3+0i) #t)
|
|
;; UNIMPL: (check '(integer? 3.0) #t)
|
|
;; UNIMPL: (check '(integer? 8/4) #t)
|
|
|
|
(check '(max 3 4) 4)
|
|
;; UNIMPL: (check '(max 3.9 4) 4.0)
|
|
|
|
(check '(+ 3 4) 7)
|
|
(check '(+ 3) 3)
|
|
(check '(+) 0)
|
|
(check '(* 4) 4)
|
|
(check '(*) 1)
|
|
|
|
(check '(- 3 4) -1)
|
|
(check '(- 3 4 5) -6)
|
|
(check '(- 3) -3)
|
|
;; UNIMPL: (check '(/ 3 4 5) 3/20)
|
|
;; UNIMPL: (check '(/ 3) 1/3)
|
|
|
|
(check '(abs -7) 7)
|
|
|
|
;; UNIMPL: (check '(modulo 13 4) 1)
|
|
(check '(remainder 13 4) 1)
|
|
;; UNIMPL: (check '(modulo -13 4) 3)
|
|
(check '(remainder -13 4) -1)
|
|
;; UNIMPL: (check '(modulo 13 -4) -3)
|
|
(check '(remainder 13 -4) 1)
|
|
;; UNIMPL: (check '(modulo -13 -4) -1)
|
|
(check '(remainder -13 -4) -1)
|
|
;; UNIMPL: (check '(remainder -13 -4.0) -1.0)
|
|
|
|
;; UNIMPL: (check '(gcd 32 -36) 4)
|
|
;; UNIMPL: (check '(gcd) 0)
|
|
;; UNIMPL: (check '(lcm 32 -36) 288)
|
|
;; UNIMPL: (check '(lcm 32.0 -36) 288.0)
|
|
;; UNIMPL: (check '(lcm) 1)
|
|
|
|
;; UNIMPL: (check '(numerator (/ 6 4)) 3)
|
|
;; UNIMPL: (check '(denominator (/ 6 4)) 2)
|
|
;; UNIMPL: (check '(denominator (exact->inexact (/ 6 4))) 2.0)
|
|
|
|
;; UNIMPL: (check '(floor -4.3) -5.0)
|
|
;; UNIMPL: (check '(ceiling -4.3) -4.0)
|
|
;; UNIMPL: (check '(truncate -4.3) -4.0)
|
|
;; UNIMPL: (check '(round -4.3) -4.0)
|
|
|
|
;; UNIMPL: (check '(floor 3.5) 3.0)
|
|
;; UNIMPL: (check '(ceiling 3.5) 4.0)
|
|
;; UNIMPL: (check '(truncate 3.5) 3.0)
|
|
;; UNIMPL: (check '(round 3.5) 4.0)
|
|
|
|
;; UNIMPL: (check '(round 7/2) 4)
|
|
;; UNIMPL: (check '(round 7) 7)
|
|
|
|
;; UNIMPL: (check '(rationalize (inexact->exact .3) 1/10) 1/3)
|
|
;; UNIMPL: (check '(rationalize .3 1/10) #i1/3)
|
|
|
|
(check '(string->number "100") 100)
|
|
(check '(string->number "100" 16) 256)
|
|
;; UNIMPL: (check '(string->number "1e2") 100.0)
|
|
;; UNIMPL: (check '(string->number "15##") 1500.0)
|
|
|
|
;;; Booleans
|
|
|
|
(check '#t #t)
|
|
(check '#f #f)
|
|
(check ''#f #f)
|
|
|
|
;;; not?
|
|
|
|
(check '(not #t) '#f)
|
|
(check '(not 3) '#f)
|
|
(check '(not (list 3)) '#f)
|
|
(check '(not #f) '#t)
|
|
(check '(not '()) '#f)
|
|
(check '(not (list)) '#f)
|
|
(check '(not 'nil) '#f)
|
|
|
|
;;; boolean?
|
|
|
|
(check '(boolean? #f) '#t)
|
|
(check '(boolean? 0) '#f)
|
|
(check '(boolean? '()) '#f)
|
|
|
|
;;; Lists
|
|
|
|
(check ''(a b c . d) '(a . (b . (c . d))))
|
|
(define x (list 'a 'b 'c))
|
|
(define y x)
|
|
(check 'y '(a b c))
|
|
(check '(list? y) '#t)
|
|
(set-cdr! x 4)
|
|
(check 'x '(a . 4))
|
|
(check '(eqv? x y) '#t)
|
|
(check 'y '(a . 4))
|
|
(check '(list? y) '#f)
|
|
(set-cdr! x x)
|
|
;; UNIMPL: (check '(list? x) '#f)
|
|
|
|
;;; pair?
|
|
|
|
(check '(pair? '(a . b)) '#t)
|
|
(check '(pair? '(a b c)) '#t)
|
|
(check '(pair? '()) '#f)
|
|
(check '(pair? '#(a b)) '#f)
|
|
|
|
;;; cons
|
|
|
|
(check '(cons 'a '()) '(a))
|
|
(check '(cons '(a) '(b c d)) '((a) b c d))
|
|
(check '(cons "a" '(b c)) '("a" b c))
|
|
(check '(cons 'a 3) '(a . 3))
|
|
(check '(cons '(a b) 'c) '((a b) . c))
|
|
|
|
;;; car
|
|
|
|
(check '(car '(a b c)) 'a)
|
|
(check '(car '((a) b c d)) '(a))
|
|
(check '(car '(1 . 2)) '1)
|
|
|
|
;;; cdr
|
|
|
|
(check '(cdr '((a) b c d)) '(b c d))
|
|
(check '(cdr '(1 . 2)) '2)
|
|
|
|
;;; list?
|
|
|
|
(check '(list? '(a b c)) '#t)
|
|
(check '(list? '()) '#t)
|
|
(check '(list? '(a . b)) '#f)
|
|
;; UNIMPL: (check '(let ((x (list 'a))) (set-cdr! x x) (list? x)) '#f)
|
|
|
|
;;; list
|
|
|
|
(check '(list 'a (+ 3 4) 'c) '(a 7 c))
|
|
(check '(list) '())
|
|
|
|
;;; length
|
|
|
|
(check '(length '(a b c)) '3)
|
|
(check '(length '(a (b) (c d e))) '3)
|
|
(check '(length '()) '0)
|
|
|
|
;;; append
|
|
|
|
(check '(append '(x) '(y)) '(x y))
|
|
(check '(append '(a) '(b c d)) '(a b c d))
|
|
(check '(append '(a (b)) '((c))) '(a (b) (c)))
|
|
(check '(append '(a b) '(c . d)) '(a b c . d))
|
|
(check '(append '() 'a) 'a)
|
|
|
|
;;; reverse
|
|
|
|
(check '(reverse '(a b c)) '(c b a))
|
|
(check '(reverse '(a (b c) d (e (f)))) '((e (f)) d (b c) a))
|
|
|
|
;;; list-tail
|
|
|
|
(check '(list-tail '(a b c d) 2) '(c d))
|
|
|
|
;;; list-ref
|
|
|
|
(check '(list-ref '(a b c d) 2) 'c)
|
|
;; UNIMPL: (check '(list-ref '(a b c d) (inexact->exact (round 1.8))) 'c)
|
|
|
|
;;; memq, memv, member
|
|
|
|
(check '(memq 'a '(a b c)) '(a b c))
|
|
(check '(memq 'b '(a b c)) '(b c))
|
|
(check '(memq 'a '(b c d)) #f)
|
|
(check '(memq (list 'a) '(b (a) c)) #f)
|
|
(check '(member (list 'a) '(b (a) c)) '((a) c))
|
|
(check '(memv 101 '(100 101 102)) '(101 102))
|
|
|
|
;;; assq, assv, assoc
|
|
|
|
(define e '((a 1) (b 2) (c 3)))
|
|
(check '(assq 'a e) '(a 1))
|
|
(check '(assq 'b e) '(b 2))
|
|
(check '(assq 'd e) #f)
|
|
(check '(assq (list 'a) '(((a)) ((b)) ((c)))) #f)
|
|
(check '(assoc (list 'a) '(((a)) ((b)) ((c)))) '((a)))
|
|
(check '(assv 5 '((2 3) (5 7) (11 13))) '(5 7))
|
|
|
|
;;; symbol?
|
|
|
|
(check '(symbol? 'foo) '#t)
|
|
(check '(symbol? (car '(a b))) '#t)
|
|
(check '(symbol? "bar") '#f)
|
|
(check '(symbol? 'nil) '#t)
|
|
(check '(symbol? '()) '#f)
|
|
(check '(symbol? #f) '#f)
|
|
|
|
;;; symbol->string
|
|
|
|
(check '(symbol->string 'flying-fish) '"flying-fish")
|
|
(check '(symbol->string 'Martin) '"martin")
|
|
(check '(symbol->string (string->symbol "Malvina")) '"Malvina")
|
|
|
|
;;; string->symbol
|
|
|
|
(check '(eq? 'mISSISSIppi 'mississippi) '#t)
|
|
(check '(eq? 'bitBlt (string->symbol "bitBlt")) '#f)
|
|
(check '(eq? 'JollyWog (string->symbol (symbol->string 'JollyWog))) '#t)
|
|
(check '(string=? "K. Harper, M.D." (symbol->string (string->symbol "K. Harper, M.D."))) '#t)
|
|
|
|
;;; Vectors
|
|
|
|
(check ''#(0 (2 2 2 2) "Anna") '#(0 (2 2 2 2) "Anna"))
|
|
|
|
;;; vector
|
|
|
|
(check '(vector 'a 'b 'c) '#(a b c))
|
|
|
|
;;; vector-ref
|
|
|
|
(check '(vector-ref '#(1 1 2 3 5 8 13 21) 5) '8)
|
|
|
|
;(check '(vector-ref '#(1 1 2 3 5 8 13 21) (let ((i (round (* 2 (acos -1))))) (if (inexact? i) (inexact->exact i) i))) '13)
|
|
|
|
;;; vector-set!
|
|
|
|
(check '(let ((vec (vector 0 '(2 2 2 2) "Anna"))) (vector-set! vec 1 '("Sue" "Sue")) vec) '#(0 ("Sue" "Sue") "Anna"))
|
|
|
|
;;; vector->list, list->vector
|
|
|
|
(check '(vector->list '#(dah dah didah)) '(dah dah didah))
|
|
(check '(list->vector '(dididit dah)) '#(dididit dah))
|
|
|
|
;;; procedure?
|
|
|
|
(check '(procedure? car) '#t)
|
|
(check '(procedure? 'car) '#f)
|
|
(check '(procedure? (lambda (x) (* x x))) '#t)
|
|
(check '(procedure? '(lambda (x) (* x x))) '#f)
|
|
;; UNIMPL: (check '(call-with-current-continuation procedure?) '#t)
|
|
|
|
;;; apply
|
|
|
|
(check '(apply + (list 3 4)) '7)
|
|
(define compose
|
|
(lambda (f g)
|
|
(lambda args
|
|
(f (apply g args)))))
|
|
;; UNIMPL: (check '((compose sqrt *) 12 75) '30)
|
|
|
|
;;; map
|
|
|
|
(check '(map cadr '((a b) (d e) (g h))) '(b e h))
|
|
;; UNIMPL: (check '(map (lambda (n) (expt n n)) '(1 2 3 4 5)) '(1 4 27 256 3125))
|
|
(check '(map + '(1 2 3) '(4 5 6)) '(5 7 9))
|
|
|
|
;;; for-each
|
|
|
|
(check '(let ((v (make-vector 5))) (for-each (lambda (i) (vector-set! v i (* i i))) '(0 1 2 3 4)) v) '#(0 1 4 9 16))
|
|
|
|
;;; delay, force
|
|
|
|
(define (stream-from n) (delay (cons n (stream-from (+ n 1)))))
|
|
(define s0 (stream-from 0))
|
|
(define (head stream) (car (force stream)))
|
|
(define (tail stream) (cdr (force stream)))
|
|
(check '(head (tail (tail s0))) '2)
|
|
|
|
(define count 0)
|
|
(define p
|
|
(delay (begin (set! count (+ count 1))
|
|
(if (> count x)
|
|
count
|
|
(force p)))))
|
|
(define x 5)
|
|
(check '(force p) '6)
|
|
;; UNIMPL: (check '(begin (set! x 10) (force p)) '6)
|
|
|
|
;;; call/cc
|
|
|
|
;; UNIMPL: (check '(call-with-current-continuation (lambda (exit) (for-each (lambda (x) (if (negative? x) (exit x))) '(54 0 37 -3 245 19)) #t)) '-3)
|
|
|
|
(define list-length
|
|
(lambda (obj)
|
|
(call-with-current-continuation
|
|
(lambda (return)
|
|
(define (r obj)
|
|
(cond ((null? obj) 0)
|
|
((pair? obj)
|
|
(+ (r (cdr obj)) 1))
|
|
(else (return #f))))
|
|
(r obj)))))
|
|
|
|
;; UNIMPL: (check '(list-length '(1 2 3 4)) '4)
|
|
|
|
;; UNIMPL: (check '(list-length '(a b . c)) '#f)
|
|
|
|
;;; values, call-with-values
|
|
|
|
;; UNIMPL: (check '(call-with-values (lambda () (values 4 5)) (lambda (a b) b)) 5)
|
|
;; UNIMPL: (check '(call-with-values * -) -1)
|
|
|
|
;;; quasiquote
|
|
|
|
(check '`(list ,(+ 1 2) 4) '(list 3 4))
|
|
(check '(let ((name 'a)) `(list ,name ',name)) '(list a (quote a)))
|
|
(check '`(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b) '(a 3 4 5 6 b))
|
|
;; UNIMPL: (check '`((foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons))) '((foo 7) . cons))
|
|
;; UNIMPL: (check '`#(10 5 ,(abs -4) ,@(map abs '(16 -9)) 8) '#(10 5 4 16 9 8))
|
|
;; UNIMPL: (check '`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f) '(a `(b ,(+ 1 2) ,(foo 4 d) e) f))
|
|
;; UNIMPL: (check '(let ((name1 'x) (name2 'y)) `(a `(b ,,name1 ,',name2 d) e)) '(a `(b ,x ,'y d) e))
|
|
|
|
;;; do
|
|
|
|
(check '(do ((vec (make-vector 5)) (i 0 (+ i 1))) ((= i 5) vec) (vector-set! vec i i)) '#(0 1 2 3 4))
|
|
(check '(let ((x '(1 3 5 7 9))) (do ((x x (cdr x)) (sum 0 (+ sum (car x)))) ((null? x) sum))) '25)
|
|
|
|
;;; named let
|
|
|
|
;; UNIMPL: (check '(let loop ((numbers '(3 -2 1 6 -5)) (nonneg '()) (neg '())) (cond ((null? numbers) (list nonneg neg)) ((>= (car numbers) 0) (loop (cdr numbers) (cons (car numbers) nonneg) neg)) ((< (car numbers) 0) (loop (cdr numbers) nonneg (cons (car numbers) neg))))) '((6 1 3) (-5 -2)))
|
|
|
|
(write-string "All tests pass.")
|
|
(newline)
|