From 443bd6e830d078acb8c4266bd52bb8e9de18c8e2 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 15 Jul 2014 20:59:29 +0900 Subject: [PATCH 1/7] initial array support --- piclib/CMakeLists.txt | 1 + piclib/picrin/array.scm | 55 +++++++++++++++++++++++++++++++++++++++++ t/array.scm | 24 ++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 piclib/picrin/array.scm create mode 100644 t/array.scm diff --git a/piclib/CMakeLists.txt b/piclib/CMakeLists.txt index 49f1c4b3..aaf66fdd 100644 --- a/piclib/CMakeLists.txt +++ b/piclib/CMakeLists.txt @@ -1,5 +1,6 @@ list(APPEND PICLIB_SCHEME_LIBS ${PROJECT_SOURCE_DIR}/piclib/built-in.scm + ${PROJECT_SOURCE_DIR}/piclib/picrin/array.scm ${PROJECT_SOURCE_DIR}/piclib/picrin/dictionary.scm ${PROJECT_SOURCE_DIR}/piclib/srfi/1.scm ${PROJECT_SOURCE_DIR}/piclib/srfi/8.scm diff --git a/piclib/picrin/array.scm b/piclib/picrin/array.scm new file mode 100644 index 00000000..04167d6d --- /dev/null +++ b/piclib/picrin/array.scm @@ -0,0 +1,55 @@ +(define-library (picrin array) + (import (scheme base)) + + (define-record-type array + (create-array data size head tail) + array? + (data array-data set-array-data!) + (size array-size set-array-size!) + (head array-head set-array-head!) + (tail array-tail set-array-tail!)) + + (define (translate ary i) + (floor-remainder i (array-size ary))) + + (define (make-array) + (create-array (vector) 0 0 0)) + + (define (array-length ary) + (let ((size (- (array-tail ary) (array-head ary)))) + (translate ary size))) + + (define (array-rotate! ary) + (when (< (array-tail ary) (array-head ary)) + (let ((xs (vector-copy (array-data ary) 0 (array-head ary))) + (ys (vector-copy (array-data ary) (array-head ary)))) + (set-array-data! ary (vector-append ys xs)) + (set-array-tail! ary (array-length ary)) + (set-array-head! ary 0)))) + + (define (array-reserve! ary size) + (set! size (+ size 1)) ; capa == size - 1 + (when (< (array-size ary) size) + (array-rotate! ary) + (set-array-data! ary (vector-append (array-data ary) (make-vector (- size (array-size ary))))) + (set-array-size! ary size))) + + (define (array-ref ary i) + (let ((data (array-data ary))) + (vector-ref data (translate ary (+ (array-head ary) i))))) + + (define (array-set! ary i obj) + (let ((data (array-data ary))) + (vector-set! data (translate ary (+ (array-head ary) i)) obj))) + + (define (array-push! ary obj) + (array-reserve! ary (+ (array-length ary) 1)) + (array-set! ary (array-length ary) obj) + (set-array-tail! ary (translate ary (+ (array-tail ary) 1)))) + + (export make-array + array? + array-length + array-ref + array-set! + array-push!)) diff --git a/t/array.scm b/t/array.scm new file mode 100644 index 00000000..dc41f462 --- /dev/null +++ b/t/array.scm @@ -0,0 +1,24 @@ +(import (scheme base) + (scheme write) + (picrin array)) + +(define ary (make-array)) + +(write ary) +(newline) +(array-push! ary 1) +(write ary) +(newline) +(array-push! ary 2) +(write ary) +(newline) +(array-push! ary 3) +(write ary) +(newline) +(write (array-ref ary 0)) +(newline) +(write (array-ref ary 1)) +(newline) +(write (array-ref ary 2)) +(newline) + From 2da5d440a8ab26d71d9fe4173368881357d16376 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 15 Jul 2014 21:26:08 +0900 Subject: [PATCH 2/7] more array functions --- piclib/picrin/array.scm | 22 ++++++++++++++++++++-- t/array.scm | 24 +++++++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/piclib/picrin/array.scm b/piclib/picrin/array.scm index 04167d6d..deb9cc21 100644 --- a/piclib/picrin/array.scm +++ b/piclib/picrin/array.scm @@ -31,7 +31,9 @@ (set! size (+ size 1)) ; capa == size - 1 (when (< (array-size ary) size) (array-rotate! ary) - (set-array-data! ary (vector-append (array-data ary) (make-vector (- size (array-size ary))))) + (set-array-data! ary (vector-append + (array-data ary) + (make-vector (- size (array-size ary))))) (set-array-size! ary size))) (define (array-ref ary i) @@ -47,9 +49,25 @@ (array-set! ary (array-length ary) obj) (set-array-tail! ary (translate ary (+ (array-tail ary) 1)))) + (define (array-pop! ary) + (set-array-tail! ary (translate ary (- (array-tail ary) 1))) + (array-ref ary (array-length ary))) + + (define (array-shift! ary) + (set-array-head! ary (translate ary (+ (array-head ary) 1))) + (array-ref ary -1)) + + (define (array-unshift! ary obj) + (array-reserve! ary (+ (array-length ary) 1)) + (array-set! ary -1 obj) + (set-array-head! ary (translate ary (- (array-head ary) 1)))) + (export make-array array? array-length array-ref array-set! - array-push!)) + array-push! + array-pop! + array-shift! + array-unshift!)) diff --git a/t/array.scm b/t/array.scm index dc41f462..22593546 100644 --- a/t/array.scm +++ b/t/array.scm @@ -15,10 +15,28 @@ (array-push! ary 3) (write ary) (newline) -(write (array-ref ary 0)) +(write (array-pop! ary)) (newline) -(write (array-ref ary 1)) +(write (array-pop! ary)) (newline) -(write (array-ref ary 2)) +(write (array-pop! ary)) +(newline) + +(write ary) +(newline) +(array-unshift! ary 1) +(write ary) +(newline) +(array-unshift! ary 2) +(write ary) +(newline) +(array-unshift! ary 3) +(write ary) +(newline) +(write (array-shift! ary)) +(newline) +(write (array-shift! ary)) +(newline) +(write (array-shift! ary)) (newline) From d358c8873da21e17de7182c5c38c7fdb46117d4b Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 15 Jul 2014 22:20:32 +0900 Subject: [PATCH 3/7] add array<->list converters --- piclib/picrin/array.scm | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/piclib/picrin/array.scm b/piclib/picrin/array.scm index deb9cc21..f2926fac 100644 --- a/piclib/picrin/array.scm +++ b/piclib/picrin/array.scm @@ -12,9 +12,6 @@ (define (translate ary i) (floor-remainder i (array-size ary))) - (define (make-array) - (create-array (vector) 0 0 0)) - (define (array-length ary) (let ((size (- (array-tail ary) (array-head ary)))) (translate ary size))) @@ -36,6 +33,9 @@ (make-vector (- size (array-size ary))))) (set-array-size! ary size))) + (define (make-array . rest) + (create-array (vector) 0 0 0)) + (define (array-ref ary i) (let ((data (array-data ary))) (vector-ref data (translate ary (+ (array-head ary) i))))) @@ -62,7 +62,22 @@ (array-set! ary -1 obj) (set-array-head! ary (translate ary (- (array-head ary) 1)))) + (define (array->list ary) + (do ((i 0 (+ i 1)) + (x '() (cons (array-ref ary i) x))) + ((= i (array-length ary)) + (reverse x)))) + + (define (list->array list) + (let ((ary (make-array))) + (for-each (lambda (x) (array-push! ary x)) list) + ary)) + + (define (array . objs) + (list->array objs)) + (export make-array + array array? array-length array-ref @@ -70,4 +85,6 @@ array-push! array-pop! array-shift! - array-unshift!)) + array-unshift! + array->list + list->array)) From 4f5a92d921581b4b483145d14721a70d7587dcbf Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 15 Jul 2014 22:20:45 +0900 Subject: [PATCH 4/7] rename array type; avoid variable conflict --- piclib/picrin/array.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/piclib/picrin/array.scm b/piclib/picrin/array.scm index f2926fac..7fc6f050 100644 --- a/piclib/picrin/array.scm +++ b/piclib/picrin/array.scm @@ -1,7 +1,7 @@ (define-library (picrin array) (import (scheme base)) - (define-record-type array + (define-record-type array-type (create-array data size head tail) array? (data array-data set-array-data!) From 318475c14b0efe6f7d1635403e6ec54399689721 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 15 Jul 2014 22:27:48 +0900 Subject: [PATCH 5/7] optional argument for make-array --- piclib/picrin/array.scm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/piclib/picrin/array.scm b/piclib/picrin/array.scm index 7fc6f050..bc667ac8 100644 --- a/piclib/picrin/array.scm +++ b/piclib/picrin/array.scm @@ -34,7 +34,12 @@ (set-array-size! ary size))) (define (make-array . rest) - (create-array (vector) 0 0 0)) + (if (null? rest) + (make-array 0) + (let ((capacity (car rest)) + (ary (create-array (vector) 0 0 0))) + (array-reserve! ary capacity) + ary))) (define (array-ref ary i) (let ((data (array-data ary))) From 632529c9a5071a103e94d60ba3ba44a086c71398 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 15 Jul 2014 22:45:04 +0900 Subject: [PATCH 6/7] add array-map and array-for-each --- piclib/picrin/array.scm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/piclib/picrin/array.scm b/piclib/picrin/array.scm index bc667ac8..4f8295d5 100644 --- a/piclib/picrin/array.scm +++ b/piclib/picrin/array.scm @@ -81,6 +81,12 @@ (define (array . objs) (list->array objs)) + (define (array-map proc ary) + (list->array (map proc (array->list ary)))) + + (define (array-for-each proc ary) + (for-each proc (array->list ary))) + (export make-array array array? @@ -91,5 +97,7 @@ array-pop! array-shift! array-unshift! + array-map + array-for-each array->list list->array)) From 033b26d1e8671e685ff70a6052f9323c02191aca Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 15 Jul 2014 23:54:50 +0900 Subject: [PATCH 7/7] update docs --- docs/libs.rst | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/docs/libs.rst b/docs/libs.rst index 102a1b54..98686ec1 100644 --- a/docs/libs.rst +++ b/docs/libs.rst @@ -137,6 +137,70 @@ This expression is equivalent to ``(filter even? (iota 10))`` but it is more pro Returns ``()`` whatever value is given. The identity element of list composition. This operator corresponds to Haskell's fail method of Monad class. +(picrin array) +-------------- + +Resizable random-access list. + +Technically, picrin's array is implemented as a ring-buffer, effective double-ended queue data structure (deque) that can operate pushing and poping from both of front and back in constant time. In addition to the deque interface, array provides standard sequence interface similar to functions specified by R7RS. + +- **(make-array [capacity])** + + Returns a newly allocated array object. If capacity is given, internal data chunk of the array object will be initialized by capacity size. + +- **(array . objs)** + + Returns an array initialized with objs. + +- **(array? . obj)** + + Returns #t if obj is an array. + +- **(array-length ary)** + + Returns the length of ary. + +- **(array-ref ary i)** + + Like ``list-ref``, return the object pointed by the index i. + +- **(array-set! ary i obj)** + + Like ``list-set!``, substitutes the object pointed by the index i with given obj. + +- **(array-push! ary obj)** + + Adds obj to the end of ary. + +- **(array-pop! ary)** + + Removes the last element of ary, and returns it. + +- **(array-unshift! ary obj)** + + Adds obj to the front of ary. + +- **(array-shift! ary)** + + Removes the first element of ary, and returns it. + +- **(array-map proc ary)** + + Performs mapping operation on ary. + +- **(array-for-each proc ary)** + + Performs mapping operation on ary, but discards the result. + +- **(array->list ary)** + + Converts ary into list. + +- **(list->array list)** + + Converts list into array. + + (picrin dictionary) -------------------