mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-26 08:41:47 -07:00
More r4rs, r5rs.
Copied from Perforce Change: 180365 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
b6300a3af4
commit
f4d7511316
3 changed files with 319 additions and 39 deletions
190
mps/example/scheme/r4rs.scm
Normal file
190
mps/example/scheme/r4rs.scm
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
;;; r4rs.scm -- essential procedures from R4RS
|
||||
|
||||
;; (caar pair)
|
||||
;; (cadr pair)
|
||||
;; ...
|
||||
;; (cdddar pair)
|
||||
;; (cddddr pair)
|
||||
;; These procedures are compositions of car and cdr. Arbitrary
|
||||
;; compositions, up to four deep, are provided. There are twenty-eight
|
||||
;; of these procedures in all.
|
||||
;; See R4RS 6.3.
|
||||
|
||||
(define (caar x) (car (car x)))
|
||||
(define (cadr x) (car (cdr x)))
|
||||
(define (cdar x) (cdr (car x)))
|
||||
(define (cddr x) (cdr (cdr x)))
|
||||
|
||||
(define (caaar x) (car (car (car x))))
|
||||
(define (caadr x) (car (car (cdr x))))
|
||||
(define (cadar x) (car (cdr (car x))))
|
||||
(define (caddr x) (car (cdr (cdr x))))
|
||||
(define (cdaar x) (cdr (car (car x))))
|
||||
(define (cdadr x) (cdr (car (cdr x))))
|
||||
(define (cddar x) (cdr (cdr (car x))))
|
||||
(define (cdddr x) (cdr (cdr (cdr x))))
|
||||
|
||||
(define (caaaar x) (car (car (car (car x)))))
|
||||
(define (caaadr x) (car (car (car (cdr x)))))
|
||||
(define (caadar x) (car (car (cdr (car x)))))
|
||||
(define (caaddr x) (car (car (cdr (cdr x)))))
|
||||
(define (cadaar x) (car (cdr (car (car x)))))
|
||||
(define (cadadr x) (car (cdr (car (cdr x)))))
|
||||
(define (caddar x) (car (cdr (cdr (car x)))))
|
||||
(define (cadddr x) (car (cdr (cdr (cdr x)))))
|
||||
(define (cdaaar x) (cdr (car (car (car x)))))
|
||||
(define (cdaadr x) (cdr (car (car (cdr x)))))
|
||||
(define (cdadar x) (cdr (car (cdr (car x)))))
|
||||
(define (cdaddr x) (cdr (car (cdr (cdr x)))))
|
||||
(define (cddaar x) (cdr (cdr (car (car x)))))
|
||||
(define (cddadr x) (cdr (cdr (car (cdr x)))))
|
||||
(define (cdddar x) (cdr (cdr (cdr (car x)))))
|
||||
(define (cddddr x) (cdr (cdr (cdr (cdr x)))))
|
||||
|
||||
|
||||
;; (memq obj list)
|
||||
;; (memv obj list)
|
||||
;; (member obj list)
|
||||
;; These procedures return the first sublist of list whose car is obj,
|
||||
;; where the sublists of list are the non-empty lists returned by
|
||||
;; (list-tail list k) for k less than the length of list. If obj does
|
||||
;; not occur in list, then #f (not the empty list) is returned. Memq
|
||||
;; uses eq? to compare obj with the elements of list, while memv uses
|
||||
;; eqv? and member uses equal?.
|
||||
;; See R4RS 6.3.
|
||||
|
||||
(define (memq obj list)
|
||||
(cond ((null? list) #f)
|
||||
((eq? obj (car list)) list)
|
||||
(else (memq obj (cdr list)))))
|
||||
|
||||
(define (memv obj list)
|
||||
(cond ((null? list) #f)
|
||||
((eqv? obj (car list)) list)
|
||||
(else (memv obj (cdr list)))))
|
||||
|
||||
(define (member obj list)
|
||||
(cond ((null? list) #f)
|
||||
((equal? obj (car list)) list)
|
||||
(else (member obj (cdr list)))))
|
||||
|
||||
|
||||
;; (assq obj alist)
|
||||
;; (assv obj alist)
|
||||
;; (assoc obj alist)
|
||||
;; Alist (for "association list") must be a list of pairs. These
|
||||
;; procedures find the first pair in alist whose car field is obj, and
|
||||
;; returns that pair. If no pair in alist has obj as its car, then #f
|
||||
;; (not the empty list) is returned. Assq uses eq? to compare obj with
|
||||
;; the car fields of the pairs in alist, while assv uses eqv? and
|
||||
;; assoc uses equal?.
|
||||
;; See R4RS 6.3.
|
||||
|
||||
(define (assq obj list)
|
||||
(cond ((null? list) #f)
|
||||
((eq? obj (caar list)) (car list))
|
||||
(else (assq obj (cdr list)))))
|
||||
|
||||
(define (assv obj list)
|
||||
(cond ((null? list) #f)
|
||||
((eqv? obj (caar list)) (car list))
|
||||
(else (assv obj (cdr list)))))
|
||||
|
||||
(define (assoc obj list)
|
||||
(cond ((null? list) #f)
|
||||
((equal? obj (caar list)) (car list))
|
||||
(else (assoc obj (cdr list)))))
|
||||
|
||||
|
||||
;; (<= x1 x2 x3 ...)
|
||||
;; (>= x1 x2 x3 ...)
|
||||
;; These procedures return #t if their arguments are (respectively):
|
||||
;; monotonically nondecreasing, or monotonically nonincreasing.
|
||||
;; These predicates are required to be transitive.
|
||||
;; See R4RS 6.5.5.
|
||||
|
||||
(define (no-fold op list)
|
||||
(cond ((null? list) #t)
|
||||
((null? (cdr list)) #t)
|
||||
((op (car list) (cadr list)) #f)
|
||||
(else (no-fold op (cdr list)))))
|
||||
|
||||
(define (<= . rest) (no-fold > rest))
|
||||
(define (>= . rest) (no-fold < rest))
|
||||
|
||||
|
||||
;; (odd? n)
|
||||
;; (even? n)
|
||||
;; These numerical predicates test a number for a particular property,
|
||||
;; returning #t or #f.
|
||||
;; See R4RS 6.5.5.
|
||||
|
||||
(define (odd? n) (eqv? (remainder n 2) 1))
|
||||
(define (even? n) (eqv? (remainder n 2) 0))
|
||||
|
||||
|
||||
;; (max x1 x2 ...)
|
||||
;; (min x1 x2 ...)
|
||||
;; These procedures return the maximum or minimum of their arguments.
|
||||
;; See R4RS 6.5.5.
|
||||
|
||||
(define (extremum op x list)
|
||||
(if (null? list) x
|
||||
(extremum op (if (op x (car list)) x (car list)) (cdr list))))
|
||||
|
||||
(define (max x1 . rest) (extremum > x1 rest))
|
||||
(define (min x1 . rest) (extremum < x1 rest))
|
||||
|
||||
|
||||
;; (abs x)
|
||||
;; Abs returns the magnitude of its argument.
|
||||
;; See R4RS 6.5.5.
|
||||
|
||||
(define (abs x) (if (< x 0) (- x) x))
|
||||
|
||||
|
||||
;; (quotient n1 n2)
|
||||
;; (remainder n1 n2)
|
||||
;; These procedures implement number-theoretic (integer) division: For
|
||||
;; positive integers n1 and n2, if n3 and n4 are integers such that
|
||||
;; n1=n2n3+n4 and 0<= n4<n2, then
|
||||
;;
|
||||
;; (quotient n1 n2) ==> n3
|
||||
;; (remainder n1 n2) ==> n4
|
||||
;;
|
||||
;; For integers n1 and n2 with n2 not equal to 0,
|
||||
;;
|
||||
;; (= n1 (+ (* n2 (quotient n1 n2))
|
||||
;; (remainder n1 n2)))
|
||||
;; ==> #t
|
||||
;;
|
||||
;; provided all numbers involved in that computation are exact.
|
||||
;; See R4RS 6.5.5.
|
||||
|
||||
(define quotient /)
|
||||
(define (remainder n1 n2) (- n1 (* n2 (quotient n1 n2))))
|
||||
|
||||
|
||||
;; (number->string number)
|
||||
;; (number->string number radix)
|
||||
;; Radix must be an exact integer, either 2, 8, 10, or 16. If omitted,
|
||||
;; radix defaults to 10. The procedure number->string takes a number
|
||||
;; and a radix and returns as a string an external representation of
|
||||
;; the given number in the given radix.
|
||||
;; See R4RS 6.5.6.
|
||||
|
||||
(define (number->string . args)
|
||||
(letrec ((number (car args))
|
||||
(radix (if (null? (cdr args)) 10 (cadr args)))
|
||||
(digits "0123456789ABCDEF")
|
||||
(n->s (lambda (n list)
|
||||
(if (zero? n) list
|
||||
(n->s (quotient n radix)
|
||||
(cons (string-ref digits (remainder n radix))
|
||||
list))))))
|
||||
(cond ((or (< radix 2) (> radix 16))
|
||||
(error "radix must be in the range 2-16"))
|
||||
((negative? number)
|
||||
(string-append "-" (number->string (abs number) radix)))
|
||||
((zero? number) "0")
|
||||
(else (list->string (n->s number '()))))))
|
||||
|
|
@ -21,4 +21,3 @@
|
|||
(define (for-each f l) (if (null? l) #f (begin (f (car l)) (for-each f (cdr l)))))
|
||||
(define (reduce f l a) (if (null? l) a (f (car l) (reduce f (cdr l) a))))
|
||||
(define (sum l) (reduce + l 0))
|
||||
(define (abs x) (if (< x 0) (- x) x))
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
;;; 2012-11-01 GDR Updated for toy Scheme in MPS kit.
|
||||
|
||||
(load "test-common.scm")
|
||||
(load "r4rs.scm")
|
||||
|
||||
;;; let, let*, letrec
|
||||
|
||||
|
|
@ -34,6 +35,11 @@
|
|||
(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))
|
||||
|
|
@ -48,20 +54,27 @@
|
|||
|
||||
(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)
|
||||
|
|
@ -70,7 +83,84 @@
|
|||
(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)
|
||||
|
||||
;; UNIMPL: (check '(string->number "100") 100)
|
||||
;; UNIMPL: (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?
|
||||
|
||||
|
|
@ -82,14 +172,12 @@
|
|||
(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))))
|
||||
|
|
@ -105,7 +193,6 @@
|
|||
(set-cdr! x x)
|
||||
;; UNIMPL: (check '(list? x) '#f)
|
||||
|
||||
|
||||
;;; pair?
|
||||
|
||||
(check '(pair? '(a . b)) '#t)
|
||||
|
|
@ -174,22 +261,22 @@
|
|||
|
||||
;;; memq, memv, member
|
||||
|
||||
;; UNIMPL: (check '(memq 'a '(a b c)) '(a b c))
|
||||
;; UNIMPL: (check '(memq 'b '(a b c)) '(b c))
|
||||
;; UNIMPL: (check '(memq 'a '(b c d)) #f)
|
||||
;; UNIMPL: (check '(memq (list 'a) '(b (a) c)) #f)
|
||||
;; UNIMPL: (check '(member (list 'a) '(b (a) c)) '((a) c))
|
||||
;; UNIMPL: (check '(memv 101 '(100 101 102)) '(101 102))
|
||||
(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
|
||||
|
||||
;; UNIMPL: (define e '((a 1) (b 2) (c 3)))
|
||||
;; UNIMPL: (check '(assq 'a e) '(a 1))
|
||||
;; UNIMPL: (check '(assq 'b e) '(b 2))
|
||||
;; UNIMPL: (check '(assq 'd e) #f)
|
||||
;; UNIMPL: (check '(assq (list 'a) '(((a)) ((b)) ((c)))) #f)
|
||||
;; UNIMPL: (check '(assoc (list 'a) '(((a)) ((b)) ((c)))) '((a)))
|
||||
;; UNIMPL: (check '(assv 5 '((2 3) (5 7) (11 13))) '(5 7))
|
||||
(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?
|
||||
|
||||
|
|
@ -213,6 +300,10 @@
|
|||
(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))
|
||||
|
|
@ -259,6 +350,24 @@
|
|||
|
||||
;; UNIMPL: (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)
|
||||
|
|
@ -280,26 +389,8 @@
|
|||
|
||||
;;; values, call-with-values
|
||||
|
||||
;; UNIMPL: (check '(call-with-values (lambda () (values 4 5)) (lambda (a b) b)) '5)
|
||||
;; UNIMPL: (check '(call-with-values * -) '-1)
|
||||
|
||||
;;; 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)
|
||||
;; UNIMPL: (check '(call-with-values (lambda () (values 4 5)) (lambda (a b) b)) 5)
|
||||
;; UNIMPL: (check '(call-with-values * -) -1)
|
||||
|
||||
;;; quasiquote
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue