~ chicken-r7rs (master) cf93413cd1380fe07452c7f162871fab7ce248f8
commit cf93413cd1380fe07452c7f162871fab7ce248f8 Author: Peter Bex <peter@more-magic.net> AuthorDate: Sun Jul 28 17:10:28 2013 +0000 Commit: Evan Hanson <evhan@foldling.org> CommitDate: Sun Jul 28 17:10:28 2013 +0000 Reverse, list-tail, list-ref and list-set! diff --git a/scheme.base-interface.scm b/scheme.base-interface.scm index 41014ba..3ac77e0 100644 --- a/scheme.base-interface.scm +++ b/scheme.base-interface.scm @@ -102,18 +102,15 @@ letrec letrec* let-values let*-values |# - let-syntax - letrec-syntax + let-syntax letrec-syntax #| library ; for "cond-expand" |# list #| list-copy - list-ref list-set! - list-tail |# - list? + list-ref list-set! list-tail list? #| make-bytevector |# @@ -161,7 +158,9 @@ read-string read-u8 real? + |# reverse + #| round set! |# diff --git a/scheme.base.scm b/scheme.base.scm index c7e4f1d..e6778a7 100644 --- a/scheme.base.scm +++ b/scheme.base.scm @@ -134,10 +134,36 @@ ((n fill) (##sys#check-integer n 'make-list) (unless (fx>= n 0) - (error 'make-list "Not a positive integer" n)) + (error 'make-list "not a positive integer" n)) (do ((i n (fx- i 1)) (result '() (cons fill result))) - ((fx<= i 0) result))))) + ((fx= i 0) result))))) + + +(: list-tail (forall (x) ((list-of x) fixnum -> (list-of x)))) + +(define (list-tail l n) + (##sys#check-integer n 'list-tail) + (unless (fx>= n 0) + (error 'list-tail "not a positive integer" n)) + (do ((i n (fx- i 1)) + (result l (cdr result))) + ((fx= i 0) result) + (when (null? result) + (error 'list-tail "out of range")))) + + +(: list-set! (list fixnum -> undefined)) + +(define (list-set! l n obj) + (##sys#check-integer n 'list-set!) + (unless (fx>= n 0) + (error 'list-set! "not a positive integer" n)) + (do ((i n (fx- i 1)) + (l l (cdr l))) + ((fx= i 0) (set-car! l obj)) + (when (null? l) + (error 'list-set! "out of range")))) ;;; ;;; 6.11. Exceptions diff --git a/tests/run.scm b/tests/run.scm index e017064..08164b8 100644 --- a/tests/run.scm +++ b/tests/run.scm @@ -162,7 +162,42 @@ (test 'a (append '() 'a)) (test '(a b . c) (append '(a b) 'c)) (test-error (append 'x '())) - (test-error (append '(x) 'y '())))) + (test-error (append '(x) 'y '()))) + + (test-group "reverse" + (test '(c b a) (reverse '(a b c))) + (test '((e (f)) d (b c) a) (reverse '(a (b c) d (e (f))))) + (test '() (reverse '())) + (test-error (reverse '(a . b))) + (test-error (reverse '(a b) '(c d))) + (test-error (reverse 'a)) + (test-error (reverse '#(a b c))) + (test-error (reverse "foo"))) + + (test-group "list-tail" + (test '(a b c d e f) (list-tail '(a b c d e f) 0)) + (test '(d e f) (list-tail '(a b c d e f) 3)) + (test '() (list-tail '(a b c d e f) 6)) + (test '() (list-tail '() 0)) + (test-error (list-tail '(a b c d e f) -1)) + (test-error (list-tail '(a b c d e f) 7)) + (test-error (list-tail '(a b c d e . f) 6))) + + (test-group "list-ref" + (test 'a (list-ref '(a b c d) 0)) + (test 'b (list-ref '(a b c d) 1)) + (test 'c (list-ref '(a b c d) 2)) + (test 'd (list-ref '(a b c d) 3)) + (test-error (list-ref '(a b c d) 4)) + (test-error (list-ref '(a b c d) -1))) + + (test-group "list-set!" + (let ((ls (list 'one 'two 'five!))) + (list-set! ls 2 'three) + (test '(two three) (cdr ls))) + ;; Should be an error? + #;(list-set! '(0 1 2) 1 "oops") + )) (define-syntax catch (syntax-rules ()Trap