~ 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