From 72d244dfb0fbdcafbe1de1a74d352f4c840bebcc Mon Sep 17 00:00:00 2001 From: Tchido-o Date: Thu, 2 Jan 2020 10:40:57 -0500 Subject: [PATCH 1/4] Add srfi 43 --- srfi/43/43#.scm | 56 ++++ srfi/43/43.scm | 650 ++++++++++++++++++++++++++++++++++++ srfi/43/43.sld | 61 ++++ srfi/43/makefile | 12 + srfi/43/test.scm | 854 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1633 insertions(+) create mode 100644 srfi/43/43#.scm create mode 100644 srfi/43/43.scm create mode 100644 srfi/43/43.sld create mode 100644 srfi/43/makefile create mode 100644 srfi/43/test.scm diff --git a/srfi/43/43#.scm b/srfi/43/43#.scm new file mode 100644 index 0000000..396a966 --- /dev/null +++ b/srfi/43/43#.scm @@ -0,0 +1,56 @@ +;;;============================================================================ + +;;; File: "43#.scm" + +;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. + +;;;============================================================================ + +;;; SRFI 43, Vector library + +(##namespace ("srfi/43#" + + make-vector + vector + vector-unfold + vector-unfold-right + vector-copy + vector-reverse-copy + vector-append + vector-concatenate + + vector? + vector-empty? + vector= + + vector-ref + vector-length + + vector-fold + vector-fold-right + vector-map + vector-map! + vector-for-each + vector-count + + vector-index + vector-index-right + vector-skip + vector-skip-right + vector-binary-search + vector-any + vector-every + + vector-set! + vector-swap! + vector-fill! + vector-reverse! + vector-copy! + vector-reverse-copy! + + vector->list + reverse-vector->list + list->vector + reverse-list->vector +)) diff --git a/srfi/43/43.scm b/srfi/43/43.scm new file mode 100644 index 0000000..8bd7e1d --- /dev/null +++ b/srfi/43/43.scm @@ -0,0 +1,650 @@ +;;;============================================================================ + +;;; File: "43.scm" + +;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. + +;;;============================================================================ + +;;; SRFI 43, Vector library + +(##supply-module srfi/43) + +(##namespace ("srfi/43#")) ;; in srfi/43# +(##include "~~lib/_prim#.scm") +(##include "~~lib/_gambit#.scm") + +(##include "43#.scm") + +(declare (extended-bindings)) ;; ##fx+ is bound to fixnum addition, etc +(declare (not safe)) ;; claim code has no type errors +(declare (block)) ;; claim no global is assigned + + +;;;============================================================================ + +(define-syntax with-vector-check + (syntax-rules () + ((with-vector-check (function-name vec . rest) function-def) + (macro-force-vars (vec . rest) + (macro-check-vector + vec + 0 + (function-name vec . rest) + function-def))))) + +(define-syntax with-proc-check + (syntax-rules () + ((with-proc-check (function-name proc . rest) function-def) + (macro-force-vars (proc . rest) + (macro-check-procedure + proc + 0 + (function-name proc . rest) + function-def))))) + +(define-syntax define-vector-check + (syntax-rules () + ((define-vector-check (function-name vec . rest) function-def) + (define (function-name vec . rest) + (with-vector-check (function-name vec . rest) function-def))))) + +(define-syntax define-proc-check + (syntax-rules () + ((define-proc-check (function-name proc . rest) function-def) + (define (function-name proc . rest) + (with-proc-check (function-name proc . rest) function-def))))) + +(define-syntax define-proc-vector-check + (syntax-rules () + ((define-proc-vector-check (function-name proc vec . rest) function-def) + (define-proc-check (function-name proc vec . rest) + (macro-check-vector + vec + 1 + (function-name proc vec . rest) + function-def))))) + +;;; Todo: accept optional arguments ++ generalise + +;;;============================================================================ + +;;; Code ported to Gambit from Taylor Campbell's implementation +;;; (with corrections from Will Clinger, both in the public domain). + +;;;============================================================================ +;;;============================================================================ + +;;; Internal procedures + + ; This should be implemented more efficiently. It shouldn't cons a + ; closure, and the cons cells used in the loops when using this could + ; be reused. +(define (vectors-ref vectors i) + (map (lambda (v) (vector-ref v i)) vectors)) + + + +(define %smallest-length + (letrec ((loop (lambda (vector-list length callee) + (if (null? vector-list) + length + (loop (cdr vector-list) + (let ((vec (car vector-list)) + (vec-rest (cdr vector-list))) + (macro-force-vars (vec) + (macro-check-vector + vec + 3 + (%smallest-length vector-list length callee) + (min (##vector-length vec) + length)))) + callee))))) + loop)) + + +(define %vector-fold1 + (letrec ((loop (lambda (kons knil len vec i) + (if (= i len) + knil + (loop kons + (kons i knil (vector-ref vec i)) + len vec (+ i 1)))))) + (lambda (kons knil len vec) + (loop kons knil len vec 0)))) + + +(define %vector-fold2+ + (letrec ((loop (lambda (kons knil len vectors i) + (if (= i len) + knil + (loop kons + (apply kons i knil + (vectors-ref vectors i)) + len vectors (+ i 1)))))) + (lambda (kons knil len vectors) + (loop kons knil len vectors 0)))) + + +(define %vector-map1! + (letrec ((loop (lambda (f target vec i) + (if (zero? i) + target + (let ((j (- i 1))) + (##vector-set! target j + (f j (##vector-ref vec j))) + (loop f target vec j)))))) + (lambda (f target vec len) + (loop f target vec len)))) + + +(define %vector-map2+! + (letrec ((loop (lambda (f target vectors i) + (if (zero? i) + target + (let ((j (- i 1))) + (##vector-set! target j + (apply f j (vectors-ref vectors j))) + (loop f target vectors j)))))) + (lambda (f target vectors len) + (loop f target vectors len)))) + + +;;;============================================================================ + +;;; Constructors + + +(define make-vector ##make-vector) + + +(define vector ##vector) + + +(define-proc-check (vector-unfold f len . initial-seeds) + (letrec ((tabulate! ; Special zero-seed case. + (lambda (f vec i len) + (cond ((< i len) + (##vector-set! vec i (f i)) + (tabulate! f vec (+ i 1) len))))) + (unfold1! ; Fast path for one seed. + (lambda (f vec i len seed) + (if (< i len) + (receive (elt new-seed) + (f i seed) + (##vector-set! vec i elt) + (unfold1! f vec (+ i 1) len new-seed))))) + (unfold2+! ; Slower variant for N seeds. + (lambda (f vec i len seeds) + (if (< i len) + (receive (elt . new-seeds) + (apply f i seeds) + (##vector-set! vec i elt) + (unfold2+! f vec (+ i 1) len new-seeds)))))) + (let ((vec (make-vector len))) + (cond ((null? initial-seeds) + (tabulate! f vec 0 len)) + ((null? (cdr initial-seeds)) + (unfold1! f vec 0 len (car initial-seeds))) + (else + (unfold2+! f vec 0 len initial-seeds))) + vec))) + + +(define-proc-check (vector-unfold-right f len . initial-seeds) + (letrec ((tabulate! + (lambda (f vec i) + (cond ((>= i 0) + (##vector-set! vec i (f i)) + (tabulate! f vec (- i 1)))))) + (unfold1! + (lambda (f vec i seed) + (if (>= i 0) + (receive (elt new-seed) + (f i seed) + (##vector-set! vec i elt) + (unfold1! f vec (- i 1) new-seed))))) + (unfold2+! + (lambda (f vec i seeds) + (if (>= i 0) + (receive (elt . new-seeds) + (apply f i seeds) + (##vector-set! vec i elt) + (unfold2+! f vec (- i 1) new-seeds)))))) + (let ((vec (make-vector len)) + (i (- len 1))) + (cond ((null? initial-seeds) + (tabulate! f vec i)) + ((null? (cdr initial-seeds)) + (unfold1! f vec i (car initial-seeds))) + (else + (unfold2+! f vec i initial-seeds))) + vec))) + + +(define (vector-copy vec #!optional (start 0) + (end (macro-absent-obj)) + (fill 0)) + (with-vector-check (vector-copy vec start end fill) + (let* ((end (if (equal? end (macro-absent-obj)) + (##vector-length vec) + end)) + (new-vector (make-vector (- end start) fill))) + (subvector-move! vec start + (if (> end (vector-length vec)) + (vector-length vec) + end) + new-vector 0) + new-vector))) + +(define (vector-reverse-copy vec #!optional (start 0) + (end (macro-absent-obj))) + (with-vector-check (vector-reverse-copy vec start end) + (let ((end (if (equal? end (macro-absent-obj)) + (##vector-length vec) + end))) + (let ((new (make-vector (- end start)))) + (letrec ((loop (lambda (target source sstart i j) + (cond ((>= i sstart) + (##vector-set! target j (##vector-ref source i)) + (loop target source sstart + (- i 1) + (+ j 1))))))) + (begin (loop new vec start (- end 1) 0) + new)))))) + + +(define vector-append ##vector-append) + + +(define vector-concatenate append-vectors) + + +;;;============================================================================ + +;;; Predicates + + +(define vector? ##vector?) + + +(define-vector-check (vector-empty? vec) + (= (vector-length vec) 0)) + + +(define-proc-vector-check (vector= elt? vec1 vec2) + (macro-check-vector + vec2 + 2 + (vector= elt? vec1 vec2) + (elt? vec1 vec2))) + + +;;;============================================================================ + +;;; Selectors + + +(define vector-ref ##vector-ref) + + +(define vector-length ##vector-length) + + +;;;============================================================================ + +;;; Iteration + + +(define-proc-check (vector-fold kons knil vec . vectors) + (macro-check-vector + vec + 2 + (vector-fold kons knil vec vectors) + (if (null? vectors) + (%vector-fold1 kons knil (vector-length vec) vec) + (%vector-fold2+ kons knil + (%smallest-length vectors + (vector-length vec) + vector-fold) + (cons vec vectors))))) + +(define-proc-check (vector-fold-right kons knil vec . vectors) + (letrec ((loop1 (lambda (kons knil vec i) + (if (negative? i) + knil + (loop1 kons (kons i knil (vector-ref vec i)) + vec + (- i 1))))) + (loop2+ (lambda (kons knil vectors i) + (if (negative? i) + knil + (loop2+ kons + (apply kons i knil + (vectors-ref vectors i)) + vectors + (- i 1)))))) + (macro-check-vector + vec + 2 + (vector-fold-right kons knil vec) + (if (null? vectors) + (loop1 kons knil vec (- (vector-length vec) 1)) + (loop2+ kons knil (cons vec vectors) + (- (%smallest-length vectors + (vector-length vec) + vector-fold-right) + 1)))))) + + +(define-proc-vector-check + (vector-map f vec . vectors) + (if (null? vectors) + (let ((len (vector-length vec))) + (%vector-map1! f (make-vector len) vec len)) + (let ((len (%smallest-length vectors + (vector-length vec) + vector-map))) + (%vector-map2+! f (make-vector len) (cons vec vectors) + len)))) + + +(define-proc-vector-check + (vector-map! f vec . vectors) + (if (null? vectors) + (%vector-map1! f vec vec (vector-length vec)) + (%vector-map2+! f vec (cons vec vectors) + (%smallest-length vectors + (vector-length vec) + vector-map!)))) + + +(define-proc-vector-check + (vector-for-each f vec . vectors) + (letrec ((for-each1 + (lambda (f vec i len) + (cond ((< i len) + (f i (vector-ref vec i)) + (for-each1 f vec (+ i 1) len))))) + (for-each2+ + (lambda (f vecs i len) + (cond ((< i len) + (apply f i (vectors-ref vecs i)) + (for-each2+ f vecs (+ i 1) len)))))) + (if (null? vectors) + (for-each1 f vec 0 (vector-length vec)) + (for-each2+ f (cons vec vectors) 0 + (%smallest-length vectors + (vector-length vec) + vector-for-each))))) + + +(define-proc-vector-check (vector-count pred? vec . vectors) + (if (null? vectors) + (%vector-fold1 (lambda (index count elt) + (if (pred? index elt) + (+ count 1) + count)) + 0 + (vector-length vec) + vec) + (%vector-fold2+ (lambda (index count . elts) + (if (apply pred? index elts) + (+ count 1) + count)) + 0 + (%smallest-length vectors + (vector-length vec) + vector-count) + (cons vec vectors)))) + + +;;;============================================================================ + +;;; Searching + + +(define-proc-vector-check + (vector-index pred? vec . vectors) + (vector-index/skip pred? vec vectors vector-index)) + + +(define-proc-vector-check + (vector-skip pred? vec . vectors) + (vector-index/skip (lambda elts (not (apply pred? elts))) + vec vectors + vector-skip)) + + +(define vector-index/skip +(letrec ((loop1 (lambda (pred? vec len i) + (cond ((= i len) #f) + ((pred? (vector-ref vec i)) i) + (else (loop1 pred? vec len (+ i 1)))))) + (loop2+ (lambda (pred? vectors len i) + (cond ((= i len) #f) + ((apply pred? (vectors-ref vectors i)) i) + (else (loop2+ pred? vectors len + (+ i 1))))))) + (lambda (pred? vec vectors callee) + (if (null? vectors) + (loop1 pred? vec (vector-length vec) 0) + (loop2+ pred? (cons vec vectors) + (%smallest-length vectors + (vector-length vec) + callee) + 0))))) + + +(define-proc-vector-check + (vector-index-right pred? vec . vectors) + (vector-index/skip-right pred? vec vectors vector-index-right)) + + +(define-proc-vector-check + (vector-skip-right pred? vec . vectors) + (vector-index/skip-right (lambda elts (not (apply pred? elts))) + vec vectors + vector-index-right)) + + +(define vector-index/skip-right + (letrec ((loop1 (lambda (pred? vec i) + (cond ((negative? i) #f) + ((pred? (vector-ref vec i)) i) + (else (loop1 pred? vec (- i 1)))))) + (loop2+ (lambda (pred? vectors i) + (cond ((negative? i) #f) + ((apply pred? (vectors-ref vectors i)) i) + (else (loop2+ pred? vectors (- i 1))))))) + (lambda (pred? vec vectors callee) + (if (null? vectors) + (loop1 pred? vec (- (vector-length vec) 1)) + (loop2+ pred? (cons vec vectors) + (- (%smallest-length vectors + (vector-length vec) + callee) + 1)))))) + + +(define (vector-binary-search vec value cmp + #!optional (start 0) + (end (macro-absent-obj))) + (with-vector-check (vector-binary-search vec value cmp) + (macro-check-procedure + cmp + 2 + (vector-binary-search vec value cmp) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (let loop ((start start) (end end) (j #f)) + (let ((i (quotient (+ start end) 2))) + (if (or (= start end) (and j (= i j))) + #f + (let ((comparison (cmp (vector-ref vec i) value))) + (cond ((zero? comparison) i) + ((positive? comparison) (loop start i i)) + (else (loop i end i))))))))))) + + +(define-proc-vector-check + (vector-any pred? vec . vectors) + (letrec ((loop1 (lambda (pred? vec i len len-1) + (and (not (= i len)) + (if (= i len-1) + (pred? (vector-ref vec i)) + (or (pred? (vector-ref vec i)) + (loop1 pred? vec (+ i 1) + len len-1)))))) + (loop2+ (lambda (pred? vectors i len len-1) + (and (not (= i len)) + (if (= i len-1) + (apply pred? (vectors-ref vectors i)) + (or (apply pred? (vectors-ref vectors i)) + (loop2+ pred? vectors (+ i 1) + len len-1))))))) + (if (null? vectors) + (let ((len (vector-length vec))) + (loop1 pred? vec 0 len (- len 1))) + (let ((len (%smallest-length vectors + (vector-length vec) + vector-any))) + (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))) + + +(define-proc-vector-check + (vector-every pred? vec . vectors) + (letrec ((loop1 (lambda (pred? vec i len len-1) + (or (not (= i len)) + (if (= i len-1) + (pred? (vector-ref vec i)) + (and (pred? (vector-ref vec i)) + (loop1 pred? vec (+ i 1) + len len-1)))))) + (loop2+ (lambda (pred? vectors i len len-1) + (or (= i len) + (if (= i len-1) + (apply pred? (vectors-ref vectors i)) + (and (apply pred? (vectors-ref vectors i)) + (loop2+ pred? vectors (+ i 1) + len len-1))))))) + (if (null? vectors) + (let ((len (vector-length vec))) + (loop1 pred? vec 0 len (- len 1))) + (let ((len (%smallest-length vectors + (vector-length vec) + vector-every))) + (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))) + + +;;;============================================================================ + +;;; Mutators + + +(define vector-set! ##vector-set!) + + +(define-vector-check + (vector-swap! vec i j) + (let ((x (vector-ref vec i))) + (vector-set! vec i (vector-ref vec j)) + (vector-set! vec j x))) + +(define + (vector-fill! vec val #!optional (start 0) (end (macro-absent-obj))) + (with-vector-check (vector-fill! vec val start end) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (subvector-fill! vec start end val)))) + + +(define (vector-reverse! vec #!optional (start 0) (end (macro-absent-obj))) + (macro-force-vars (vec start end) + (macro-check-vector + vec + 0 + (vector-reverse! vec start end) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (letrec ((loop (lambda (vec i j) + (cond ((<= i j) + (let ((v (vector-ref vec i))) + (vector-set! vec i (vector-ref vec j)) + (vector-set! vec j v) + (loop vec (+ i 1) (- j 1)))))))) + (loop vec start (- end 1))))))) + + +(define (vector-copy! vec-target tstart vec-source + #!optional (sstart 0) (send (macro-absent-obj))) + (with-vector-check (vector-copy! vec-target tstart vec-source sstart send) + (macro-check-vector + vec-source + 2 + (vector-copy! vec-target tstart vec-source sstart send) + (let ((send (if (equal? send (macro-absent-obj)) + (vector-length vec-source) + send))) + (subvector-move! vec-source sstart send vec-target tstart))))) + + +(define (vector-reverse-copy! target tstart source + #!optional (sstart 0) (send (macro-absent-obj))) + (with-vector-check (vector-reverse-copy! target tstart source sstart send) + (macro-check-vector + source + 2 + (vector-reverse-copy! target tstart source sstart send) + (let ((send (if (equal? send (macro-absent-obj)) + (vector-length source) + send))) + (letrec ((loop (lambda (target source sstart i j) + (cond ((>= i sstart) + (vector-set! target j (vector-ref source i)) + (loop target source sstart + (- i 1) + (+ j 1))))))) + (loop target source sstart + (- send 1) + tstart)))))) + + +;;;============================================================================ + +;;; Conversion + + +(define vector->list ##vector->list) + + +(define (reverse-vector->list vec #!optional (start 0) + (end (macro-absent-obj))) + (with-vector-check + (reverse-vector->list vec start end) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (do ((i start (+ i 1)) + (result '() (cons (vector-ref vec i) result))) + ((= i end) result))))) + + +(define list->vector ##list->vector) + + +(define (reverse-list->vector lst #!optional (start 0) + (end (macro-absent-obj))) + (let ((end (if (equal? end (macro-absent-obj)) + (length lst) + end)) + (f (lambda (index l) (values (car l) (cdr l))))) + (vector-unfold-right f (- end start) (list-tail lst start)))) + + ;;; todo type check for list + +;;;============================================================================ diff --git a/srfi/43/43.sld b/srfi/43/43.sld new file mode 100644 index 0000000..ae0acbe --- /dev/null +++ b/srfi/43/43.sld @@ -0,0 +1,61 @@ +;;;============================================================================ + +;;; File: "43.sld" + +;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. + +;;;============================================================================ + +;;; SRFI 43, Vector library + +(define-library (srfi 43) + + (export + make-vector + vector + vector-unfold + vector-unfold-right + vector-copy + vector-reverse-copy + vector-append + vector-concatenate + + vector? + vector-empty? + vector= + + vector-ref + vector-length + + vector-fold + vector-fold-right + vector-map + vector-map! + vector-for-each + vector-count + + vector-index + vector-index-right + vector-skip + vector-skip-right + vector-binary-search + vector-any + vector-every + + vector-set! + vector-swap! + vector-fill! + vector-reverse! + vector-copy! + vector-reverse-copy! + + vector->list + reverse-vector->list + list->vector + reverse-list->vector + ) + +; (import (gambit)) + (include "43.scm") +) diff --git a/srfi/43/makefile b/srfi/43/makefile new file mode 100644 index 0000000..cd1513a --- /dev/null +++ b/srfi/43/makefile @@ -0,0 +1,12 @@ +# Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +# Copyright (c) 1994-2020 by Marc Feeley, All Rights Reserved. + +herefromlib = srfi/43 +libfromhere = ../.. +SUBDIRS = +HEADERS_SCM = 43\#.scm +MODULES_SCM = 43.scm 43.sld test.scm +MAIN_MODULES = 43 +OTHER_RCFILES = makefile + +include $(libfromhere)/module-common.mk diff --git a/srfi/43/test.scm b/srfi/43/test.scm new file mode 100644 index 0000000..2a400ab --- /dev/null +++ b/srfi/43/test.scm @@ -0,0 +1,854 @@ +;;;============================================================================ + +;;; File: "test.scm" + +;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. + +;;;============================================================================ + +;;; SRFI 43, Vector library. + +(import (srfi 43)) +(import (_test)) + +;;;============================================================================ +;;; Constructors +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; make-vector + + ;;; primitive R5Rs ##make-vector + + (check-equal? (make-vector 4) + #(0 0 0 0)) + + (check-equal? (make-vector 4 1) + #(1 1 1 1)) + +;;;---------------------------------------------------------------------------- +;;; vector + + ;;; primitive R5Rs ##vector + + (check-equal? (vector 0) + #(0)) + + (check-equal? (vector 0 1 2 3) + #(0 1 2 3)) + + +;;;---------------------------------------------------------------------------- +;;; vector-unfold + + (check-equal? + (vector-unfold + (lambda (i x) (values x (+ x 1))) + 5 + 0) + #(0 1 2 3 4)) + + (let ((vec (vector 0 1 2 3 4))) + (check-equal? + (vector-unfold (lambda (i) (vector-ref vec i)) + (vector-length vec)) + vec)) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold (lambda () '()) 1))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold (lambda (x1) '()) 1 2))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold (lambda (x1) '())))) + (check-exn + wrong-number-of-arguments-exception? + (lambda () (vector-unfold (lambda (x1 x2 x3) (values 1 2 3)) + 1 2 ))) + (check-tail-exn + type-exception? + (lambda () (vector-unfold 0 1 2))) + + +;;;---------------------------------------------------------------------------- +;;; vector-unfold-right + + (check-equal? + (vector-unfold-right (lambda (i x) (values x (+ x 1))) 5 0) + #(4 3 2 1 0)) + + (let ((vec #(1 2 3 4 5))) + (check-equal? + (vector-unfold-right (lambda (i x) (values (vector-ref vec x) (+ x 1))) + (vector-length vec) + 0) + #(5 4 3 2 1))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold-right (lambda () '()) 1))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold-right (lambda (x1) '()) 1 2))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold-right (lambda (x1) '())))) + (check-exn + wrong-number-of-arguments-exception? + (lambda () (vector-unfold-right (lambda (x1 x2 x3) (values 1 2 3)) + 1 2 ))) + + (check-tail-exn + type-exception? + (lambda () (vector-unfold 0 1 2))) + +;;;---------------------------------------------------------------------------- +;;; vector-copy + + (let ((vec #(0 1 2 3 4))) + (check-equal? + (vector-copy vec) + vec) + (check-equal? + vec #(0 1 2 3 4))) + + (let ((vec #(0 1 2 3 4 5))) + (check-equal? + (vector-copy vec 3) + #(3 4 5)) + (check-equal? + vec #(0 1 2 3 4 5))) + + (let ((vec #(0 1 2 3 4 5))) + (check-equal? + (vector-copy vec 3 10 6) + #(3 4 5 6 6 6 6))) + + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-copy))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-copy 0 1 2 3 4))) + + (check-tail-exn + type-exception? + (lambda () (vector-copy 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-reverse-copy + + (let ((vec #(5 4 3 2 1))) + (check-equal? + (vector-reverse-copy vec 2 5) + #(1 2 3)) + (check-equal? + vec + #(5 4 3 2 1))) + + (let ((vec #(3 2 1))) + (check-equal? + (vector-reverse-copy vec ) + #(1 2 3))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse-copy))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse-copy 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (vector-reverse-copy 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-append + + ;;; primitive R5Rs ##vector-append + +;;;---------------------------------------------------------------------------- +;;; vector-concatenate + + ;;; primitive ##append-vectors + +;;;============================================================================ +;;; Predicates +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector? + + ;;; primitive R5Rs ##vector? + +;;;---------------------------------------------------------------------------- +;;; vector-empty? + + (check-true (vector-empty? #())) + (check-false (vector-empty? #(0))) + (check-false (vector-empty? #(#()))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-empty?))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-empty? 0 1))) + + (check-tail-exn + type-exception? + (lambda () (vector-empty? 0))) + +;;;---------------------------------------------------------------------------- +;;; vector= + + (check-true (vector= equal? #() #())) + + (let ((vec #())) + (check-true (vector= eq? vec vec))) + (check-true (vector= (lambda (a b) #t) #(1 2 3) #(4 5 6))) + (check-false (vector= eq? #(0 1 2 3) #())) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector= 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector= 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (vector= 0 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector= eq? 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector= eq? #() 0))) + + +;;;============================================================================ +;;; Selectors +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector-ref + + ;;; primitive R5Rs ##vector-ref + +;;;---------------------------------------------------------------------------- +;;; vector-length + + ;;; primitive R5Rs ##vector-length + + +;;;============================================================================ +;;; Iteration +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector-fold + + (let ((vec #(0 1 2 3))) + (check-equal? + (vector-fold (lambda (index tail elt) (cons elt tail)) + '() vec) + '(3 2 1 0)) + (check-equal? + vec + #(0 1 2 3))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-fold 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-fold 0 1 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-fold (lambda (x1 x2) '()) 1 0 #()))) + + (check-exn + type-exception? + (lambda () (vector-fold (lambda (x1 x2) '()) 1 #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-fold-right + + + (check-equal? + (vector-fold-right (lambda (index tail elt) (cons elt tail)) + '() #(0 1 2 3)) + '(0 1 2 3)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-fold-right 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-fold-right 0 1 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-fold-right (lambda (x1 x2) '()) 1 0 #()))) + + (check-exn + type-exception? + (lambda () (vector-fold-right (lambda (x1 x2) '()) 1 #() 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-map + + (let ((vec #(0 1 2 3 4))) + (check-equal? + (vector-map (lambda (i x) (* x x)) vec) + #(0 1 4 9 16)) + (check-equal? + vec + #(0 1 2 3 4))) + + (let ((vec #(1 2 3 4 5))) + (check-equal? + (vector-map (lambda (i x) (- x i)) vec ) + #(1 1 1 1 1)) + (check-equal? + vec + #(1 2 3 4 5))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-map 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-map 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-map (lambda (x1 x2) '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-map (lambda (x1 x2) '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-map! + + (check-equal? + (vector-map (lambda (i x) (* x x)) #(0 1 2 3 4)) + #(0 1 4 9 16)) + + (check-equal? + (vector-map (lambda (i x) (- x i)) #(1 2 3 4 5) ) + #(1 1 1 1 1)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-map 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-map 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-map (lambda (i x) '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-map (lambda (i x) '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-for-each + + (let ((vec #(0 1 2 3))) + (vector-for-each (lambda (i x) (vector-set! vec i (* x x))) + vec) + (check-equal? vec + #(0 1 4 9))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-for-each 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-for-each 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-for-each (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-for-each (lambda () '()) #() 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-count + + (check-equal? + (vector-count (lambda (i elt) (even? elt)) #(1 2 3 4)) + 2) + + (check-equal? + (vector-count (lambda (i x y) (< x y)) '#(0 1 2 3 4) '#(1 2 3 4 4 4)) + 4) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-count 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-count 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-count (lambda () '()) 0))) + + + (check-exn + type-exception? + (lambda () (vector-count (lambda () '()) #() 0))) + + +;;;============================================================================ +;;; Searching +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector-index + + (check-equal? + (vector-index even? #(1 2 3 4)) + 1) + + (check-equal? + (vector-index < #(1 2 3 4) #(2 2 2 2)) + 0) + + (check-false + (vector-index = #(1 1 1) #(2 2 2 2 2))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-index 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-index 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-index (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-index (lambda () '()) #() 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-index-right + + (check-equal? + (vector-index-right even? #(1 2 3 4)) + 3) + + (check-equal? + (vector-index-right <= #(1 2 3 4) #(2 2 2 2)) + 1) + + (check-false + (vector-index-right = #(1 1 1) #(2 2 2 2 2))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-index-right 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-index-right 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-index-right (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-index-right (lambda () '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-skip + + (check-equal? + (vector-skip number? #(0 1 2 a b 1 2 3)) + 3) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-skip 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-skip 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-skip (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-skip (lambda () '()) #() 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-skip-right + + (check-equal? + (vector-skip-right number? #(0 1 2 a b 0 1 2)) + 4) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-skip-right 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-skip-right 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-skip-right (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-skip-right (lambda () '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-binary-search + + (let ((comp? (lambda (x1 x2) + (cond ((< x1 x2) -1) + ((= x1 x2) 0) + (else 1))))) + (check-equal? + (vector-binary-search #(1 2 3 4) 2 comp?) + 1)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-binary-search 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-binary-search 0 1 2 3 4 5))) + + + (check-tail-exn + type-exception? + (lambda () (vector-binary-search 0 0 (lambda () '())))) + + (check-tail-exn + type-exception? + (lambda () (vector-binary-search #() 0 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-any + + (check-true + (vector-any = #(0 0 0 0) #(1 0 1) #(2 0 2 0))) + + (check-false + (vector-any = #(0 0 0) #(1 1 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-any 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-any 0 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-any (lambda () '()) 0 #()))) + + (check-exn + type-exception? + (lambda () (vector-any (lambda () '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-every + + (check-false + (vector-every = #(0 0 0 0) #(1 0 1) #(2 0 2 0))) + + (check-true + (vector-every = #(1 1 1) #(1 1 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-every 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-every 0 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-every (lambda () '()) 0 #()))) + + (check-exn + type-exception? + (lambda () (vector-every (lambda () '()) #() 0))) + +;;;============================================================================ +;;; Mutators +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector-set! + + ;;; primitive R5Rs ##vector-set! + +;;;---------------------------------------------------------------------------- +;;; vector-swap! + + (let ((vec #(0 1 2 3 4))) + (vector-swap! vec 0 1) + (check-equal? + vec + #(1 0 2 3 4))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-swap! 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-swap! 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (vector-swap! 0 0 1))) + +;;;---------------------------------------------------------------------------- +;;; vector-fill! + + (let ((vec #(0 0 0 0))) + (vector-fill! vec 1 0 2) + (check-equal? + vec + #(1 1 0 0))) + + (let ((vec #(0 0 0 0))) + (vector-fill! vec 1) + (check-equal? + vec + #(1 1 1 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-fill! 0))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-fill! 0 1 2 3 4))) + + (check-tail-exn + type-exception? + (lambda () (vector-fill! 0 1))) + +;;;---------------------------------------------------------------------------- +;;; vector-reverse! + + + (let ((vec #(0 1 2 3 4))) + (vector-reverse! vec) + (check-equal? + vec + #(4 3 2 1 0))) + + (let ((vec #(0 1 2 3 4))) + (vector-reverse! vec 0 3) + (check-equal? + vec + #(2 1 0 3 4))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse!))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse! 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (vector-reverse! 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-copy! + + (let ((vec1 #(0 1 2 3 4)) + (vec2 #(5 6 7 8 9))) + (vector-copy! vec2 0 vec1) + (check-equal? vec2 vec1)) + + (let ((vec1 #(0 1 2 3 4)) + (vec2 #(5 6 7 8 9))) + (vector-copy! vec2 2 vec1 0 2 ) + (check-equal? + vec2 + #(5 6 0 1 9))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-copy! 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-copy! 0 1 2 3 4 5))) + + (check-tail-exn + type-exception? + (lambda () (vector-copy! 0 1 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-copy! #() 1 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-reverse-copy! + + (let ((vec1 #(0 1 2 3 4)) + (vec2 #(5 6 7 8 9))) + (vector-reverse-copy! vec2 0 vec1) + (check-equal? + vec2 + #(4 3 2 1 0))) + + (let ((vec1 #(0 1 2 3 4)) + (vec2 #(5 6 7 8 9))) + (vector-reverse-copy! vec2 2 vec1 0 2 ) + (check-equal? + vec2 + #(5 6 1 0 9))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse-copy! 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse-copy! 0 1 2 3 4 5))) + + (check-tail-exn + type-exception? + (lambda () (vector-reverse-copy! 0 1 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-reverse-copy! #() 1 0))) + + +;;;============================================================================ +;;; Conversion +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector->list + + ;;; primitive R5Rs ##vector->list + +;;;---------------------------------------------------------------------------- +;;; reverse-vector->list + + (check-equal? + (reverse-vector->list #(0 1 2 3 4)) + '(4 3 2 1 0)) + + (check-equal? + (reverse-vector->list #(0 1 2 3 4) 1 3) + '(2 1)) + + (check-equal? + (reverse-vector->list #()) + '()) + + (check-equal? + (reverse-vector->list #(0)) + '(0)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (reverse-vector->list))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (reverse-vector->list 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (reverse-vector->list 0))) + + (check-tail-exn + type-exception? + (lambda () (reverse-vector->list 0))) + +;;;---------------------------------------------------------------------------- +;;; list->vector + + ;;; primitive R5Rs ##list->vector + + (check-equal? + (list->vector '(0 1 2 3)) + #(0 1 2 3)) + +;;;---------------------------------------------------------------------------- +;;; reverse-list->vector + + (check-equal? + (reverse-list->vector '(0 1 2)) + #(2 1 0)) + + (check-equal? + (reverse-list->vector '()) + #()) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (reverse-list->vector))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (reverse-list->vector 0 1 2 3))) + +;;;============================================================================ From 8e3903f47dedade835ea3ea7aa45a60e1e1bffe5 Mon Sep 17 00:00:00 2001 From: Tchido-o Date: Sun, 5 Jan 2020 15:05:04 -0500 Subject: [PATCH 2/4] Update srfi 43 to 133 --- srfi/{43/43#.scm => 133/133#.scm} | 14 +- srfi/{43/43.scm => 133/133.scm} | 752 ++++++++++++++++++------------ srfi/{43/43.sld => 133/133.sld} | 17 +- srfi/{43 => 133}/makefile | 8 +- srfi/{43 => 133}/test.scm | 214 +++++++-- 5 files changed, 676 insertions(+), 329 deletions(-) rename srfi/{43/43#.scm => 133/133#.scm} (80%) rename srfi/{43/43.scm => 133/133.scm} (56%) rename srfi/{43/43.sld => 133/133.sld} (78%) rename srfi/{43 => 133}/makefile (68%) rename srfi/{43 => 133}/test.scm (81%) diff --git a/srfi/43/43#.scm b/srfi/133/133#.scm similarity index 80% rename from srfi/43/43#.scm rename to srfi/133/133#.scm index 396a966..580e585 100644 --- a/srfi/43/43#.scm +++ b/srfi/133/133#.scm @@ -1,15 +1,15 @@ ;;;============================================================================ -;;; File: "43#.scm" +;;; File: "133#.scm" ;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. ;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. ;;;============================================================================ -;;; SRFI 43, Vector library +;;; SRFI 133, Vector library -(##namespace ("srfi/43#" +(##namespace ("srfi/133#" make-vector vector @@ -19,6 +19,7 @@ vector-reverse-copy vector-append vector-concatenate + vector-append-subvectors vector? vector-empty? @@ -33,6 +34,7 @@ vector-map! vector-for-each vector-count + vector-cumulate vector-index vector-index-right @@ -41,6 +43,7 @@ vector-binary-search vector-any vector-every + vector-partition vector-set! vector-swap! @@ -48,9 +51,14 @@ vector-reverse! vector-copy! vector-reverse-copy! + vector-unfold! + vector-unfold-right! vector->list reverse-vector->list list->vector reverse-list->vector + string->vector + vector->string + )) diff --git a/srfi/43/43.scm b/srfi/133/133.scm similarity index 56% rename from srfi/43/43.scm rename to srfi/133/133.scm index 8bd7e1d..c0b6b50 100644 --- a/srfi/43/43.scm +++ b/srfi/133/133.scm @@ -1,27 +1,31 @@ ;;;============================================================================ -;;; File: "43.scm" +;;; File: "133.scm" ;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. ;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. ;;;============================================================================ -;;; SRFI 43, Vector library +;;; SRFI 133, Vector library -(##supply-module srfi/43) +(##supply-module srfi/133) -(##namespace ("srfi/43#")) ;; in srfi/43# (##include "~~lib/_prim#.scm") (##include "~~lib/_gambit#.scm") -(##include "43#.scm") +(##include "133#.scm") (declare (extended-bindings)) ;; ##fx+ is bound to fixnum addition, etc (declare (not safe)) ;; claim code has no type errors (declare (block)) ;; claim no global is assigned +;;;============================================================================ + +;;; Code ported to Gambit from Taylor Campbell's implementation +;;; (with corrections from Will Clinger, both in the public domain). + ;;;============================================================================ (define-syntax with-vector-check @@ -68,91 +72,18 @@ ;;; Todo: accept optional arguments ++ generalise -;;;============================================================================ - -;;; Code ported to Gambit from Taylor Campbell's implementation -;;; (with corrections from Will Clinger, both in the public domain). ;;;============================================================================ -;;;============================================================================ - -;;; Internal procedures - - ; This should be implemented more efficiently. It shouldn't cons a - ; closure, and the cons cells used in the loops when using this could - ; be reused. -(define (vectors-ref vectors i) - (map (lambda (v) (vector-ref v i)) vectors)) - - - -(define %smallest-length - (letrec ((loop (lambda (vector-list length callee) - (if (null? vector-list) - length - (loop (cdr vector-list) - (let ((vec (car vector-list)) - (vec-rest (cdr vector-list))) - (macro-force-vars (vec) - (macro-check-vector - vec - 3 - (%smallest-length vector-list length callee) - (min (##vector-length vec) - length)))) - callee))))) - loop)) - - -(define %vector-fold1 - (letrec ((loop (lambda (kons knil len vec i) - (if (= i len) - knil - (loop kons - (kons i knil (vector-ref vec i)) - len vec (+ i 1)))))) - (lambda (kons knil len vec) - (loop kons knil len vec 0)))) - - -(define %vector-fold2+ - (letrec ((loop (lambda (kons knil len vectors i) - (if (= i len) - knil - (loop kons - (apply kons i knil - (vectors-ref vectors i)) - len vectors (+ i 1)))))) - (lambda (kons knil len vectors) - (loop kons knil len vectors 0)))) - - -(define %vector-map1! - (letrec ((loop (lambda (f target vec i) - (if (zero? i) - target - (let ((j (- i 1))) - (##vector-set! target j - (f j (##vector-ref vec j))) - (loop f target vec j)))))) - (lambda (f target vec len) - (loop f target vec len)))) +;;; Taylor Campbell wrote this code; he places it in the public domain. +;;; Will Clinger [wdc] made some corrections, also in the public domain. +;;; John Cowan modified this code for SRFI 133; his changes are also in +;;; the public domain. -(define %vector-map2+! - (letrec ((loop (lambda (f target vectors i) - (if (zero? i) - target - (let ((j (- i 1))) - (##vector-set! target j - (apply f j (vectors-ref vectors j))) - (loop f target vectors j)))))) - (lambda (f target vectors len) - (loop f target vectors len)))) - +;;; The code was then adapted to Gambit. ;;;============================================================================ - +;;;============================================================================ ;;; Constructors @@ -162,65 +93,15 @@ (define vector ##vector) -(define-proc-check (vector-unfold f len . initial-seeds) - (letrec ((tabulate! ; Special zero-seed case. - (lambda (f vec i len) - (cond ((< i len) - (##vector-set! vec i (f i)) - (tabulate! f vec (+ i 1) len))))) - (unfold1! ; Fast path for one seed. - (lambda (f vec i len seed) - (if (< i len) - (receive (elt new-seed) - (f i seed) - (##vector-set! vec i elt) - (unfold1! f vec (+ i 1) len new-seed))))) - (unfold2+! ; Slower variant for N seeds. - (lambda (f vec i len seeds) - (if (< i len) - (receive (elt . new-seeds) - (apply f i seeds) - (##vector-set! vec i elt) - (unfold2+! f vec (+ i 1) len new-seeds)))))) - (let ((vec (make-vector len))) - (cond ((null? initial-seeds) - (tabulate! f vec 0 len)) - ((null? (cdr initial-seeds)) - (unfold1! f vec 0 len (car initial-seeds))) - (else - (unfold2+! f vec 0 len initial-seeds))) - vec))) - - -(define-proc-check (vector-unfold-right f len . initial-seeds) - (letrec ((tabulate! - (lambda (f vec i) - (cond ((>= i 0) - (##vector-set! vec i (f i)) - (tabulate! f vec (- i 1)))))) - (unfold1! - (lambda (f vec i seed) - (if (>= i 0) - (receive (elt new-seed) - (f i seed) - (##vector-set! vec i elt) - (unfold1! f vec (- i 1) new-seed))))) - (unfold2+! - (lambda (f vec i seeds) - (if (>= i 0) - (receive (elt . new-seeds) - (apply f i seeds) - (##vector-set! vec i elt) - (unfold2+! f vec (- i 1) new-seeds)))))) - (let ((vec (make-vector len)) - (i (- len 1))) - (cond ((null? initial-seeds) - (tabulate! f vec i)) - ((null? (cdr initial-seeds)) - (unfold1! f vec i (car initial-seeds))) - (else - (unfold2+! f vec i initial-seeds))) - vec))) +(define (vector-unfold f len . initial-seeds) + (define vec (make-vector len)) + (apply vector-unfold! f vec 0 len initial-seeds) + vec) + +(define (vector-unfold-right f len . initial-seeds) + (define vec (make-vector len)) + (apply vector-unfold-right! f vec 0 len initial-seeds) + vec) (define (vector-copy vec #!optional (start 0) @@ -228,7 +109,7 @@ (fill 0)) (with-vector-check (vector-copy vec start end fill) (let* ((end (if (equal? end (macro-absent-obj)) - (##vector-length vec) + (vector-length vec) end)) (new-vector (make-vector (- end start) fill))) (subvector-move! vec start @@ -242,12 +123,12 @@ (end (macro-absent-obj))) (with-vector-check (vector-reverse-copy vec start end) (let ((end (if (equal? end (macro-absent-obj)) - (##vector-length vec) + (vector-length vec) end))) (let ((new (make-vector (- end start)))) (letrec ((loop (lambda (target source sstart i j) (cond ((>= i sstart) - (##vector-set! target j (##vector-ref source i)) + (vector-set! target j (vector-ref source i)) (loop target source sstart (- i 1) (+ j 1))))))) @@ -255,11 +136,54 @@ new)))))) -(define vector-append ##vector-append) - - -(define vector-concatenate append-vectors) - +(define vector-append ##vector-append) ;;; R7RS + + +(define vector-concatenate append-vectors) + +(define (vector-append-subvectors . args) + ;; GATHER-ARGS returns three values: vectors, starts, ends + (define (gather-args args) + (let loop ((args args) (vecs '()) (starts '()) (ends '())) + (if (null? args) + (values (reverse vecs) (reverse starts) (reverse ends)) + (if (and (pair? args) + (pair? (cdr args)) + (pair? (cddr args))) + (macro-force-vars (args) + (macro-check-vector + (car args) + 0 + (vector-append-subvectors . args) + (loop (cdddr args) + (cons (car args) vecs) + (cons (cadr args) starts) + (cons (caddr args) ends)))) + (##raise-wrong-number-of-arguments-exception + vector-append-subvectors args))))) + ;; TOTAL-LENGTH computes the length of all subvectors + (define (total-length starts ends) + (let loop ((count 0) (starts starts) (ends ends)) + (if (null? starts) + count + (let ((start (car starts)) (end (car ends))) + (loop (+ count (- end start)) + (cdr starts) + (cdr ends)))))) + ;; COPY-EACH! copies each subvector into a result vector + (define (copy-each! result vecs starts ends) + (let loop ((at 0) (vecs vecs) (starts starts) (ends ends)) + (if (null? vecs) + result + (let ((vec (car vecs)) (start (car starts)) (end (car ends))) + (%vector-copy! result at vec start end) + (loop (+ at (- end start)) + (cdr vecs) + (cdr starts) + (cdr ends)))))) + (receive (vecs starts ends) (gather-args args) + (define result (make-vector (total-length starts ends))) + (copy-each! result vecs starts ends))) ;;;============================================================================ @@ -272,14 +196,41 @@ (define-vector-check (vector-empty? vec) (= (vector-length vec) 0)) - -(define-proc-vector-check (vector= elt? vec1 vec2) +(define-proc-check (vector= elt=? . vectors) + (if (null? vectors) + #t + (macro-check-vector + (car vectors) + 1 + (vector= elt=? vectors) + (if (null? (cdr vectors)) + #t + (let loop ((vecs vectors)) + (let ((vec1 (car vecs)) + (vec2+ (cdr vecs))) + (or (null? vec2+) + (and (binary-vector= elt=? vec1 (car vec2+)) + (loop vec2+))))))))) + +(define (binary-vector= elt=? vector-a vector-b) (macro-check-vector - vec2 - 2 - (vector= elt? vec1 vec2) - (elt? vec1 vec2))) - + vector-a + 1 + (vector= elt? vector-a vector-b) + (macro-check-vector + vector-b + 2 + (vector= elt? vector-a vector-b) + (let ((length-a (vector-length vector-a)) + (length-b (vector-length vector-b))) + (and (= length-a length-b) + (let loop ((i 0)) + (cond + ((= i length-a) #t) + ((elt=? (vector-ref vector-a i) + (vector-ref vector-b i)) + (loop (+ i 1))) + (else #f)))))))) ;;;============================================================================ @@ -294,6 +245,141 @@ ;;;============================================================================ + +;;; Mutators + + +(define vector-set! ##vector-set!) + + +(define-vector-check + (vector-swap! vec i j) + (let ((x (vector-ref vec i))) + (vector-set! vec i (vector-ref vec j)) + (vector-set! vec j x))) + +(define + (vector-fill! vec val #!optional (start 0) (end (macro-absent-obj))) + (with-vector-check (vector-fill! vec val start end) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (subvector-fill! vec start end val)))) + + +(define (vector-reverse! vec #!optional (start 0) (end (macro-absent-obj))) + (macro-force-vars (vec start end) + (macro-check-vector + vec + 0 + (vector-reverse! vec start end) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (letrec ((loop (lambda (vec i j) + (cond ((<= i j) + (let ((v (vector-ref vec i))) + (vector-set! vec i (vector-ref vec j)) + (vector-set! vec j v) + (loop vec (+ i 1) (- j 1)))))))) + (loop vec start (- end 1))))))) + + +(define (vector-copy! vec-target tstart vec-source + #!optional (sstart 0) (send (macro-absent-obj))) + (with-vector-check (vector-copy! vec-target tstart vec-source sstart send) + (macro-check-vector + vec-source + 2 + (vector-copy! vec-target tstart vec-source sstart send) + (let ((send (if (equal? send (macro-absent-obj)) + (vector-length vec-source) + send))) + (subvector-move! vec-source sstart send vec-target tstart))))) + + +(define (vector-reverse-copy! target tstart source + #!optional (sstart 0) (send (macro-absent-obj))) + (with-vector-check (vector-reverse-copy! target tstart source sstart send) + (macro-check-vector + source + 2 + (vector-reverse-copy! target tstart source sstart send) + (let ((send (if (equal? send (macro-absent-obj)) + (vector-length source) + send))) + (letrec ((loop (lambda (target source sstart i j) + (cond ((>= i sstart) + (vector-set! target j (vector-ref source i)) + (loop target source sstart + (- i 1) + (+ j 1))))))) + (loop target source sstart + (- send 1) + tstart)))))) + +(define-proc-vector-check + (vector-unfold! f vec start end . initial-seeds) + (letrec ((tabulate! ; Special zero-seed case. + (lambda (f vec i len) + (cond ((< i len) + (vector-set! vec i (f i)) + (tabulate! f vec (+ i 1) len))))) + (unfold1! ; Fast path for one seed. + (lambda (f vec i len seed) + (if (< i len) + (receive (elt new-seed) + (f i seed) + (vector-set! vec i elt) + (unfold1! f vec (+ i 1) len new-seed))))) + (unfold2+! ; Slower variant for N seeds. + (lambda (f vec i len seeds) + (if (< i len) + (receive (elt . new-seeds) + (apply f i seeds) + (vector-set! vec i elt) + (unfold2+! f vec (+ i 1) len new-seeds)))))) + (if (< (vector-length vec) start) + #!void + (cond ((null? initial-seeds) + (tabulate! f vec start end)) + ((null? (cdr initial-seeds)) + (unfold1! f vec start end (car initial-seeds))) + (else + (unfold2+! f vec start end initial-seeds)))))) + +(define-proc-vector-check + (vector-unfold-right! f vec start end . initial-seeds) + (letrec ((tabulate! + (lambda (f vec i) + (cond ((>= i start) + (vector-set! vec i (f i)) + (tabulate! f vec (- i 1)))))) + (unfold1! + (lambda (f vec i seed) + (if (>= i start) + (receive (elt new-seed) + (f i seed) + (vector-set! vec i elt) + (unfold1! f vec (- i 1) new-seed))))) + (unfold2+! + (lambda (f vec i seeds) + (if (>= i start) + (receive (elt . new-seeds) + (apply f i seeds) + (vector-set! vec i elt) + (unfold2+! f vec (- i 1) new-seeds)))))) + (let ((i (- end 1))) + (cond ((null? initial-seeds) + (tabulate! f vec i)) + ((null? (cdr initial-seeds)) + (unfold1! f vec i (car initial-seeds))) + (else + (unfold2+! f vec i initial-seeds)))))) + + + +;;;============================================================================ ;;; Iteration @@ -305,24 +391,24 @@ (if (null? vectors) (%vector-fold1 kons knil (vector-length vec) vec) (%vector-fold2+ kons knil - (%smallest-length vectors - (vector-length vec) - vector-fold) - (cons vec vectors))))) + (%smallest-length vectors + (vector-length vec) + vector-fold) + (cons vec vectors))))) (define-proc-check (vector-fold-right kons knil vec . vectors) (letrec ((loop1 (lambda (kons knil vec i) (if (negative? i) knil - (loop1 kons (kons i knil (vector-ref vec i)) + (loop1 kons (kons knil (vector-ref vec i)) vec (- i 1))))) (loop2+ (lambda (kons knil vectors i) (if (negative? i) knil (loop2+ kons - (apply kons i knil - (vectors-ref vectors i)) + (apply kons knil + (vectors-ref vectors i)) vectors (- i 1)))))) (macro-check-vector @@ -333,22 +419,29 @@ (loop1 kons knil vec (- (vector-length vec) 1)) (loop2+ kons knil (cons vec vectors) (- (%smallest-length vectors - (vector-length vec) - vector-fold-right) - 1)))))) + (vector-length vec) + vector-fold-right) + 1)))))) +(define-proc-vector-check + (vector-map f vec . vectors) ;;; R7Rs #unimplemented in Gambit + (if (null? vectors) + (let ((len (vector-length vec))) + (%vector-map1! f (make-vector len) vec len)) + (let ((len (%smallest-length vectors + (vector-length vec) + vector-map))) + (%vector-map2+! f (make-vector len) (cons vec vectors) + len)))) -(define-proc-vector-check - (vector-map f vec . vectors) - (if (null? vectors) - (let ((len (vector-length vec))) - (%vector-map1! f (make-vector len) vec len)) - (let ((len (%smallest-length vectors - (vector-length vec) - vector-map))) - (%vector-map2+! f (make-vector len) (cons vec vectors) - len)))) +(define-proc-vector-check (vector-map! f vec . vectors) + (if (null? vectors) + (%vector-map1! f vec vec (vector-length vec)) + (%vector-map2+! f vec (cons vec vectors) + (%smallest-length vectors + (vector-length vec) + vector-map!)))) (define-proc-vector-check (vector-map! f vec . vectors) @@ -361,43 +454,57 @@ (define-proc-vector-check - (vector-for-each f vec . vectors) - (letrec ((for-each1 - (lambda (f vec i len) - (cond ((< i len) - (f i (vector-ref vec i)) - (for-each1 f vec (+ i 1) len))))) - (for-each2+ - (lambda (f vecs i len) - (cond ((< i len) - (apply f i (vectors-ref vecs i)) - (for-each2+ f vecs (+ i 1) len)))))) - (if (null? vectors) - (for-each1 f vec 0 (vector-length vec)) - (for-each2+ f (cons vec vectors) 0 - (%smallest-length vectors - (vector-length vec) - vector-for-each))))) + (vector-for-each f vec . vectors ) ;;; R7Rs #unimplemented in Gambit + (letrec ((for-each1 + (lambda (f vec i len) + (cond ((< i len) + (f (vector-ref vec i)) + (for-each1 f vec (+ i 1) len))))) + (for-each2+ + (lambda (f vecs i len) + (cond ((< i len) + (apply f (vectors-ref vecs i)) + (for-each2+ f vecs (+ i 1) len)))))) + (if (null? vectors) + (for-each1 f vec 0 (vector-length vec)) + (for-each2+ f (cons vec vectors) 0 + (%smallest-length vectors + (vector-length vec) + vector-for-each))))) (define-proc-vector-check (vector-count pred? vec . vectors) (if (null? vectors) - (%vector-fold1 (lambda (index count elt) - (if (pred? index elt) - (+ count 1) - count)) - 0 - (vector-length vec) - vec) - (%vector-fold2+ (lambda (index count . elts) - (if (apply pred? index elts) - (+ count 1) - count)) - 0 - (%smallest-length vectors - (vector-length vec) - vector-count) - (cons vec vectors)))) + (%vector-fold1 (lambda (count elt) + (if (pred? elt) + (+ count 1) + count)) + 0 + (vector-length vec) + vec) + (%vector-fold2+ (lambda (count . elts) + (if (apply pred? elts) + (+ count 1) + count)) + 0 + (%smallest-length vectors + (vector-length vec) + vector-count) + (cons vec vectors)))) + +(define-proc-check (vector-cumulate f knil vec) + (macro-check-vector + vec + 2 + (vector-cumulate f knil vec) + (let* ((len (vector-length vec)) + (result (make-vector len))) + (let loop ((i 0) (left knil)) + (if (= i len) + result + (let* ((right (vector-ref vec i)) (r (f left right))) + (vector-set! result i r) + (loop (+ i 1) r))))))) ;;;============================================================================ @@ -538,81 +645,22 @@ vector-every))) (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))) - -;;;============================================================================ - -;;; Mutators - - -(define vector-set! ##vector-set!) - - -(define-vector-check - (vector-swap! vec i j) - (let ((x (vector-ref vec i))) - (vector-set! vec i (vector-ref vec j)) - (vector-set! vec j x))) - -(define - (vector-fill! vec val #!optional (start 0) (end (macro-absent-obj))) - (with-vector-check (vector-fill! vec val start end) - (let ((end (if (equal? end (macro-absent-obj)) - (vector-length vec) - end))) - (subvector-fill! vec start end val)))) - - -(define (vector-reverse! vec #!optional (start 0) (end (macro-absent-obj))) - (macro-force-vars (vec start end) - (macro-check-vector - vec - 0 - (vector-reverse! vec start end) - (let ((end (if (equal? end (macro-absent-obj)) - (vector-length vec) - end))) - (letrec ((loop (lambda (vec i j) - (cond ((<= i j) - (let ((v (vector-ref vec i))) - (vector-set! vec i (vector-ref vec j)) - (vector-set! vec j v) - (loop vec (+ i 1) (- j 1)))))))) - (loop vec start (- end 1))))))) - - -(define (vector-copy! vec-target tstart vec-source - #!optional (sstart 0) (send (macro-absent-obj))) - (with-vector-check (vector-copy! vec-target tstart vec-source sstart send) - (macro-check-vector - vec-source - 2 - (vector-copy! vec-target tstart vec-source sstart send) - (let ((send (if (equal? send (macro-absent-obj)) - (vector-length vec-source) - send))) - (subvector-move! vec-source sstart send vec-target tstart))))) - - -(define (vector-reverse-copy! target tstart source - #!optional (sstart 0) (send (macro-absent-obj))) - (with-vector-check (vector-reverse-copy! target tstart source sstart send) - (macro-check-vector - source - 2 - (vector-reverse-copy! target tstart source sstart send) - (let ((send (if (equal? send (macro-absent-obj)) - (vector-length source) - send))) - (letrec ((loop (lambda (target source sstart i j) - (cond ((>= i sstart) - (vector-set! target j (vector-ref source i)) - (loop target source sstart - (- i 1) - (+ j 1))))))) - (loop target source sstart - (- send 1) - tstart)))))) - +(define-proc-vector-check + (vector-partition pred? vec) + (let* ((len (vector-length vec)) + (cnt (vector-count pred? vec)) + (result (make-vector len))) + (let loop ((i 0) (yes 0) (no cnt)) + (if (= i len) + (values result cnt) + (let ((elem (vector-ref vec i))) + (if (pred? elem) + (begin + (vector-set! result yes elem) + (loop (+ i 1) (+ yes 1) no)) + (begin + (vector-set! result no elem) + (loop (+ i 1) yes (+ no 1))))))))) ;;;============================================================================ @@ -647,4 +695,136 @@ ;;; todo type check for list + +(define (vector->string vec #!optional (start 0) (end (macro-absent-obj))) + (with-vector-check (vector->string vec start end) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (define result (make-string (- end start))) + (let loop ((at 0) (i start)) + (if (= i end) + result + (let ((val (vector-ref vec i))) + (macro-check-char + val + i + (vector->string vec) + (begin + (string-set! result at val) + (loop (+ at 1) (+ i 1)))))))))) + +(define (string->vector str #!optional (start 0) (end (macro-absent-obj))) + (macro-force-vars (str) + (macro-check-string + str + 0 + (string->vector str start end) + (let ((end (if (equal? end (macro-absent-obj)) + (string-length str) + end))) + (define result (make-vector (- end start))) + (let loop ((at 0) (i start)) + (if (= i end) + result + (begin + (vector-set! result at (string-ref str i)) + (loop (+ at 1) (+ i 1))))))))) + +;;;============================================================================ +;;;============================================================================ + +;;; Internal procedures + + ; This should be implemented more efficiently. It shouldn't cons a + ; closure, and the cons cells used in the loops when using this could + ; be reused. +(define (vectors-ref vectors i) + (map (lambda (v) (vector-ref v i)) vectors)) + + + +(define %smallest-length + (letrec ((loop (lambda (vector-list length callee) + (if (null? vector-list) + length + (loop (cdr vector-list) + (let ((vec (car vector-list)) + (vec-rest (cdr vector-list))) + (macro-force-vars (vec) + (macro-check-vector + vec + 3 + (%smallest-length vector-list length callee) + (min (vector-length vec) + length)))) + callee))))) + loop)) + + +(define %vector-fold1 + (letrec ((loop (lambda (kons knil len vec i) + (if (= i len) + knil + (loop kons + (kons knil (vector-ref vec i)) + len vec (+ i 1)))))) + (lambda (kons knil len vec) + (loop kons knil len vec 0)))) + + +(define %vector-fold2+ + (letrec ((loop (lambda (kons knil len vectors i) + (if (= i len) + knil + (loop kons + (apply kons knil + (vectors-ref vectors i)) + len vectors (+ i 1)))))) + (lambda (kons knil len vectors) + (loop kons knil len vectors 0)))) + +(define %vector-map1! + (letrec ((loop (lambda (f target vec i) + (if (zero? i) + target + (let ((j (- i 1))) + (vector-set! target j + (f (vector-ref vec j))) + (loop f target vec j)))))) + (lambda (f target vec len) + (loop f target vec len)))) + + +(define %vector-map2+! + (letrec ((loop (lambda (f target vectors i) + (if (zero? i) + target + (let ((j (- i 1))) + (vector-set! target j + (apply f (vectors-ref vectors j))) + (loop f target vectors j)))))) + (lambda (f target vectors len) + (loop f target vectors len)))) + +(define %vector-copy! + (letrec ((loop/l->r (lambda (target source send i j) + (cond ((< i send) + (vector-set! target j + (vector-ref source i)) + (loop/l->r target source send + (+ i 1) (+ j 1)))))) + (loop/r->l (lambda (target source sstart i j) + (cond ((>= i sstart) + (vector-set! target j + (vector-ref source i)) + (loop/r->l target source sstart + (- i 1) (- j 1))))))) + (lambda (target tstart source sstart send) + (if (> sstart tstart) ; Make sure we don't copy over + ; ourselves. + (loop/l->r target source send sstart tstart) + (loop/r->l target source sstart (- send 1) + (+ -1 tstart send (- sstart))))))) + ;;;============================================================================ diff --git a/srfi/43/43.sld b/srfi/133/133.sld similarity index 78% rename from srfi/43/43.sld rename to srfi/133/133.sld index ae0acbe..7073b8b 100644 --- a/srfi/43/43.sld +++ b/srfi/133/133.sld @@ -1,15 +1,15 @@ ;;;============================================================================ -;;; File: "43.sld" +;;; File: "133.sld" ;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. ;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. ;;;============================================================================ -;;; SRFI 43, Vector library +;;; SRFI 133, Vector library -(define-library (srfi 43) +(define-library (srfi 133) (export make-vector @@ -20,6 +20,7 @@ vector-reverse-copy vector-append vector-concatenate + vector-append-subvectors vector? vector-empty? @@ -34,6 +35,7 @@ vector-map! vector-for-each vector-count + vector-cumulate vector-index vector-index-right @@ -42,6 +44,7 @@ vector-binary-search vector-any vector-every + vector-partition vector-set! vector-swap! @@ -49,13 +52,17 @@ vector-reverse! vector-copy! vector-reverse-copy! + vector-unfold! + vector-unfold-right! vector->list reverse-vector->list list->vector reverse-list->vector + string->vector + vector->string ) -; (import (gambit)) - (include "43.scm") + (import (gambit)) + (include "133.scm") ) diff --git a/srfi/43/makefile b/srfi/133/makefile similarity index 68% rename from srfi/43/makefile rename to srfi/133/makefile index cd1513a..e4053e8 100644 --- a/srfi/43/makefile +++ b/srfi/133/makefile @@ -1,12 +1,12 @@ # Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. # Copyright (c) 1994-2020 by Marc Feeley, All Rights Reserved. -herefromlib = srfi/43 +herefromlib = srfi/133 libfromhere = ../.. SUBDIRS = -HEADERS_SCM = 43\#.scm -MODULES_SCM = 43.scm 43.sld test.scm -MAIN_MODULES = 43 +HEADERS_SCM = 133\#.scm +MODULES_SCM = 133.scm 133.sld test.scm +MAIN_MODULES = 133 OTHER_RCFILES = makefile include $(libfromhere)/module-common.mk diff --git a/srfi/43/test.scm b/srfi/133/test.scm similarity index 81% rename from srfi/43/test.scm rename to srfi/133/test.scm index 2a400ab..02132ee 100644 --- a/srfi/43/test.scm +++ b/srfi/133/test.scm @@ -7,9 +7,9 @@ ;;;============================================================================ -;;; SRFI 43, Vector library. +;;; SRFI 133, Vector library. -(import (srfi 43)) +(import (srfi 133)) (import (_test)) ;;;============================================================================ @@ -73,7 +73,7 @@ wrong-number-of-arguments-exception? (lambda () (vector-unfold (lambda (x1 x2 x3) (values 1 2 3)) 1 2 ))) - (check-tail-exn + (check-exn type-exception? (lambda () (vector-unfold 0 1 2))) @@ -111,7 +111,7 @@ (lambda () (vector-unfold-right (lambda (x1 x2 x3) (values 1 2 3)) 1 2 ))) - (check-tail-exn + (check-exn type-exception? (lambda () (vector-unfold 0 1 2))) @@ -182,12 +182,37 @@ ;;; vector-append ;;; primitive R5Rs ##vector-append - + (check-equal? (vector-append #(0) #(1)) + #(0 1)) ;;;---------------------------------------------------------------------------- ;;; vector-concatenate ;;; primitive ##append-vectors +;;;---------------------------------------------------------------------------- +;;; vector-append-subvectors + +(let ((vec1 #(0 1 2 3)) + (vec2 #(4 5 6 7))) + (check-equal? + (vector-append-subvectors vec1 0 1 vec2 2 4) + #(0 6 7)) + (check-equal? vec1 #(0 1 2 3)) + (check-equal? vec2 #(4 5 6 7))) + +(check-exn + wrong-number-of-arguments-exception? + (lambda () (vector-append-subvectors 0 1))) + +(check-exn + wrong-number-of-arguments-exception? + (lambda () (vector-append-subvectors #(0) 1 2 3))) + +(check-exn + type-exception? + (lambda () (vector-append-subvectors 0 1 2))) + + ;;;============================================================================ ;;; Predicates ;;;============================================================================ @@ -219,6 +244,9 @@ ;;;---------------------------------------------------------------------------- ;;; vector= + + (check-true (vector= equal?)) + (check-true (vector= equal? #())) (check-true (vector= equal? #() #())) (let ((vec #())) @@ -228,11 +256,7 @@ (check-tail-exn wrong-number-of-arguments-exception? - (lambda () (vector= 0 1))) - - (check-tail-exn - wrong-number-of-arguments-exception? - (lambda () (vector= 0 1 2 3))) + (lambda () (vector=))) (check-tail-exn type-exception? @@ -242,7 +266,7 @@ type-exception? (lambda () (vector= eq? 0 #()))) - (check-tail-exn + (check-exn type-exception? (lambda () (vector= eq? #() 0))) @@ -271,7 +295,7 @@ (let ((vec #(0 1 2 3))) (check-equal? - (vector-fold (lambda (index tail elt) (cons elt tail)) + (vector-fold (lambda (tail elt) (cons elt tail)) '() vec) '(3 2 1 0)) (check-equal? @@ -294,13 +318,12 @@ type-exception? (lambda () (vector-fold (lambda (x1 x2) '()) 1 #() 0))) - ;;;---------------------------------------------------------------------------- ;;; vector-fold-right (check-equal? - (vector-fold-right (lambda (index tail elt) (cons elt tail)) + (vector-fold-right (lambda (tail elt) (cons elt tail)) '() #(0 1 2 3)) '(0 1 2 3)) @@ -320,25 +343,18 @@ type-exception? (lambda () (vector-fold-right (lambda (x1 x2) '()) 1 #() 0))) + ;;;---------------------------------------------------------------------------- ;;; vector-map (let ((vec #(0 1 2 3 4))) (check-equal? - (vector-map (lambda (i x) (* x x)) vec) + (vector-map (lambda (x) (* x x)) vec) #(0 1 4 9 16)) (check-equal? vec #(0 1 2 3 4))) - (let ((vec #(1 2 3 4 5))) - (check-equal? - (vector-map (lambda (i x) (- x i)) vec ) - #(1 1 1 1 1)) - (check-equal? - vec - #(1 2 3 4 5))) - (check-tail-exn wrong-number-of-arguments-exception? (lambda () (vector-map 0))) @@ -360,13 +376,9 @@ ;;; vector-map! (check-equal? - (vector-map (lambda (i x) (* x x)) #(0 1 2 3 4)) + (vector-map (lambda (x) (* x x)) #(0 1 2 3 4)) #(0 1 4 9 16)) - (check-equal? - (vector-map (lambda (i x) (- x i)) #(1 2 3 4 5) ) - #(1 1 1 1 1)) - (check-tail-exn wrong-number-of-arguments-exception? (lambda () (vector-map 0))) @@ -388,7 +400,7 @@ ;;; vector-for-each (let ((vec #(0 1 2 3))) - (vector-for-each (lambda (i x) (vector-set! vec i (* x x))) + (vector-for-each (lambda (x) (vector-set! vec x (* x x))) vec) (check-equal? vec #(0 1 4 9))) @@ -413,11 +425,11 @@ ;;; vector-count (check-equal? - (vector-count (lambda (i elt) (even? elt)) #(1 2 3 4)) + (vector-count (lambda (elt) (even? elt)) #(1 2 3 4)) 2) (check-equal? - (vector-count (lambda (i x y) (< x y)) '#(0 1 2 3 4) '#(1 2 3 4 4 4)) + (vector-count (lambda (x y) (< x y)) '#(0 1 2 3 4) '#(1 2 3 4 4 4)) 4) (check-tail-exn @@ -438,6 +450,29 @@ (lambda () (vector-count (lambda () '()) #() 0))) +;;;---------------------------------------------------------------------------- +;;; vector-cumulate + + (check-equal? + (vector-cumulate + 0 #(1 1 1 1 1 1)) + #(1 2 3 4 5 6)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-cumulate 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-cumulate 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (vector-cumulate 0 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-cumulate + 0 0))) + ;;;============================================================================ ;;; Searching ;;;============================================================================ @@ -629,6 +664,32 @@ type-exception? (lambda () (vector-every (lambda () '()) #() 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-partition + + (let-values (((new-vec mid) (vector-partition (lambda (x) (< x 3)) + #(0 3 1 4 2 5)))) + (check-equal? new-vec #(0 1 2 3 4 5)) + (check-equal? mid 3)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-partition 0))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-partition 0 1 2))) + + (check-tail-exn + type-exception? + (lambda () (vector-partition 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-partition (lambda () '()) 0))) + + ;;;============================================================================ ;;; Mutators ;;;============================================================================ @@ -778,6 +839,49 @@ type-exception? (lambda () (vector-reverse-copy! #() 1 0))) +;;;---------------------------------------------------------------------------- +;;; vector-unfold! + + + + (let ((vec #(0 0 0 0 0))) + (vector-unfold! (lambda (i) (* i i)) vec 1 4) + (check-equal? vec #(0 1 4 9 0))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-unfold! 0 1 2))) + + (check-tail-exn + type-exception? + (lambda () (vector-unfold! 0 #() 0 1))) + + (check-tail-exn + type-exception? + (lambda () (vector-unfold! (lambda () '()) 0 0 1))) + +;;;---------------------------------------------------------------------------- +;;; vector-unfold-right! + + (let ((vec1 #(0 0 0 0 0)) + (vec2 #())) + (vector-unfold-right! (lambda (i) (* i i)) vec1 1 4) + (check-equal? vec1 #(0 1 4 9 0))) + + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-unfold-right! 0 1 2))) + + (check-tail-exn + type-exception? + (lambda () (vector-unfold-right! 0 #() 0 1))) + + (check-tail-exn + type-exception? + (lambda () (vector-unfold-right! (lambda () '()) 0 0 1))) + + ;;;============================================================================ ;;; Conversion @@ -851,4 +955,52 @@ wrong-number-of-arguments-exception? (lambda () (reverse-list->vector 0 1 2 3))) +;;;---------------------------------------------------------------------------- +;;; string->vector ;;; R7Rs primitive unimplemented in Gambit + + (check-equal? (string->vector "abc") #(#\a #\b #\c)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (string->vector))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (string->vector 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (string->vector 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector->string ;;; R7Rs primitive unimplemented in Gambit + + (check-equal? (vector->string (vector #\a #\b #\c)) + "abc") + + (check-equal? (vector->string #(#\a #\b #\c) 1 2) + "b") + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector->string))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector->string 0 1 2 3))) + + + (check-tail-exn + type-exception? + (lambda () (vector->string 0))) + + (check-tail-exn + type-exception? + (lambda () (vector->string #(0 1 2)))) + + (check-tail-exn + type-exception? + (lambda () (vector->string #(#\a #\b 0)))) + ;;;============================================================================ From c4adb8d49cf370f2ce0aab5a40fdce22a76b956d Mon Sep 17 00:00:00 2001 From: Tchido-o Date: Wed, 8 Jan 2020 22:35:02 -0500 Subject: [PATCH 3/4] Add test for srfi 43 --- srfi/43/43#.scm | 56 ++++ srfi/43/43.scm | 650 ++++++++++++++++++++++++++++++++++++ srfi/43/43.sld | 61 ++++ srfi/43/makefile | 12 + srfi/43/test.scm | 854 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1633 insertions(+) create mode 100644 srfi/43/43#.scm create mode 100644 srfi/43/43.scm create mode 100644 srfi/43/43.sld create mode 100644 srfi/43/makefile create mode 100644 srfi/43/test.scm diff --git a/srfi/43/43#.scm b/srfi/43/43#.scm new file mode 100644 index 0000000..396a966 --- /dev/null +++ b/srfi/43/43#.scm @@ -0,0 +1,56 @@ +;;;============================================================================ + +;;; File: "43#.scm" + +;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. + +;;;============================================================================ + +;;; SRFI 43, Vector library + +(##namespace ("srfi/43#" + + make-vector + vector + vector-unfold + vector-unfold-right + vector-copy + vector-reverse-copy + vector-append + vector-concatenate + + vector? + vector-empty? + vector= + + vector-ref + vector-length + + vector-fold + vector-fold-right + vector-map + vector-map! + vector-for-each + vector-count + + vector-index + vector-index-right + vector-skip + vector-skip-right + vector-binary-search + vector-any + vector-every + + vector-set! + vector-swap! + vector-fill! + vector-reverse! + vector-copy! + vector-reverse-copy! + + vector->list + reverse-vector->list + list->vector + reverse-list->vector +)) diff --git a/srfi/43/43.scm b/srfi/43/43.scm new file mode 100644 index 0000000..8bd7e1d --- /dev/null +++ b/srfi/43/43.scm @@ -0,0 +1,650 @@ +;;;============================================================================ + +;;; File: "43.scm" + +;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. + +;;;============================================================================ + +;;; SRFI 43, Vector library + +(##supply-module srfi/43) + +(##namespace ("srfi/43#")) ;; in srfi/43# +(##include "~~lib/_prim#.scm") +(##include "~~lib/_gambit#.scm") + +(##include "43#.scm") + +(declare (extended-bindings)) ;; ##fx+ is bound to fixnum addition, etc +(declare (not safe)) ;; claim code has no type errors +(declare (block)) ;; claim no global is assigned + + +;;;============================================================================ + +(define-syntax with-vector-check + (syntax-rules () + ((with-vector-check (function-name vec . rest) function-def) + (macro-force-vars (vec . rest) + (macro-check-vector + vec + 0 + (function-name vec . rest) + function-def))))) + +(define-syntax with-proc-check + (syntax-rules () + ((with-proc-check (function-name proc . rest) function-def) + (macro-force-vars (proc . rest) + (macro-check-procedure + proc + 0 + (function-name proc . rest) + function-def))))) + +(define-syntax define-vector-check + (syntax-rules () + ((define-vector-check (function-name vec . rest) function-def) + (define (function-name vec . rest) + (with-vector-check (function-name vec . rest) function-def))))) + +(define-syntax define-proc-check + (syntax-rules () + ((define-proc-check (function-name proc . rest) function-def) + (define (function-name proc . rest) + (with-proc-check (function-name proc . rest) function-def))))) + +(define-syntax define-proc-vector-check + (syntax-rules () + ((define-proc-vector-check (function-name proc vec . rest) function-def) + (define-proc-check (function-name proc vec . rest) + (macro-check-vector + vec + 1 + (function-name proc vec . rest) + function-def))))) + +;;; Todo: accept optional arguments ++ generalise + +;;;============================================================================ + +;;; Code ported to Gambit from Taylor Campbell's implementation +;;; (with corrections from Will Clinger, both in the public domain). + +;;;============================================================================ +;;;============================================================================ + +;;; Internal procedures + + ; This should be implemented more efficiently. It shouldn't cons a + ; closure, and the cons cells used in the loops when using this could + ; be reused. +(define (vectors-ref vectors i) + (map (lambda (v) (vector-ref v i)) vectors)) + + + +(define %smallest-length + (letrec ((loop (lambda (vector-list length callee) + (if (null? vector-list) + length + (loop (cdr vector-list) + (let ((vec (car vector-list)) + (vec-rest (cdr vector-list))) + (macro-force-vars (vec) + (macro-check-vector + vec + 3 + (%smallest-length vector-list length callee) + (min (##vector-length vec) + length)))) + callee))))) + loop)) + + +(define %vector-fold1 + (letrec ((loop (lambda (kons knil len vec i) + (if (= i len) + knil + (loop kons + (kons i knil (vector-ref vec i)) + len vec (+ i 1)))))) + (lambda (kons knil len vec) + (loop kons knil len vec 0)))) + + +(define %vector-fold2+ + (letrec ((loop (lambda (kons knil len vectors i) + (if (= i len) + knil + (loop kons + (apply kons i knil + (vectors-ref vectors i)) + len vectors (+ i 1)))))) + (lambda (kons knil len vectors) + (loop kons knil len vectors 0)))) + + +(define %vector-map1! + (letrec ((loop (lambda (f target vec i) + (if (zero? i) + target + (let ((j (- i 1))) + (##vector-set! target j + (f j (##vector-ref vec j))) + (loop f target vec j)))))) + (lambda (f target vec len) + (loop f target vec len)))) + + +(define %vector-map2+! + (letrec ((loop (lambda (f target vectors i) + (if (zero? i) + target + (let ((j (- i 1))) + (##vector-set! target j + (apply f j (vectors-ref vectors j))) + (loop f target vectors j)))))) + (lambda (f target vectors len) + (loop f target vectors len)))) + + +;;;============================================================================ + +;;; Constructors + + +(define make-vector ##make-vector) + + +(define vector ##vector) + + +(define-proc-check (vector-unfold f len . initial-seeds) + (letrec ((tabulate! ; Special zero-seed case. + (lambda (f vec i len) + (cond ((< i len) + (##vector-set! vec i (f i)) + (tabulate! f vec (+ i 1) len))))) + (unfold1! ; Fast path for one seed. + (lambda (f vec i len seed) + (if (< i len) + (receive (elt new-seed) + (f i seed) + (##vector-set! vec i elt) + (unfold1! f vec (+ i 1) len new-seed))))) + (unfold2+! ; Slower variant for N seeds. + (lambda (f vec i len seeds) + (if (< i len) + (receive (elt . new-seeds) + (apply f i seeds) + (##vector-set! vec i elt) + (unfold2+! f vec (+ i 1) len new-seeds)))))) + (let ((vec (make-vector len))) + (cond ((null? initial-seeds) + (tabulate! f vec 0 len)) + ((null? (cdr initial-seeds)) + (unfold1! f vec 0 len (car initial-seeds))) + (else + (unfold2+! f vec 0 len initial-seeds))) + vec))) + + +(define-proc-check (vector-unfold-right f len . initial-seeds) + (letrec ((tabulate! + (lambda (f vec i) + (cond ((>= i 0) + (##vector-set! vec i (f i)) + (tabulate! f vec (- i 1)))))) + (unfold1! + (lambda (f vec i seed) + (if (>= i 0) + (receive (elt new-seed) + (f i seed) + (##vector-set! vec i elt) + (unfold1! f vec (- i 1) new-seed))))) + (unfold2+! + (lambda (f vec i seeds) + (if (>= i 0) + (receive (elt . new-seeds) + (apply f i seeds) + (##vector-set! vec i elt) + (unfold2+! f vec (- i 1) new-seeds)))))) + (let ((vec (make-vector len)) + (i (- len 1))) + (cond ((null? initial-seeds) + (tabulate! f vec i)) + ((null? (cdr initial-seeds)) + (unfold1! f vec i (car initial-seeds))) + (else + (unfold2+! f vec i initial-seeds))) + vec))) + + +(define (vector-copy vec #!optional (start 0) + (end (macro-absent-obj)) + (fill 0)) + (with-vector-check (vector-copy vec start end fill) + (let* ((end (if (equal? end (macro-absent-obj)) + (##vector-length vec) + end)) + (new-vector (make-vector (- end start) fill))) + (subvector-move! vec start + (if (> end (vector-length vec)) + (vector-length vec) + end) + new-vector 0) + new-vector))) + +(define (vector-reverse-copy vec #!optional (start 0) + (end (macro-absent-obj))) + (with-vector-check (vector-reverse-copy vec start end) + (let ((end (if (equal? end (macro-absent-obj)) + (##vector-length vec) + end))) + (let ((new (make-vector (- end start)))) + (letrec ((loop (lambda (target source sstart i j) + (cond ((>= i sstart) + (##vector-set! target j (##vector-ref source i)) + (loop target source sstart + (- i 1) + (+ j 1))))))) + (begin (loop new vec start (- end 1) 0) + new)))))) + + +(define vector-append ##vector-append) + + +(define vector-concatenate append-vectors) + + +;;;============================================================================ + +;;; Predicates + + +(define vector? ##vector?) + + +(define-vector-check (vector-empty? vec) + (= (vector-length vec) 0)) + + +(define-proc-vector-check (vector= elt? vec1 vec2) + (macro-check-vector + vec2 + 2 + (vector= elt? vec1 vec2) + (elt? vec1 vec2))) + + +;;;============================================================================ + +;;; Selectors + + +(define vector-ref ##vector-ref) + + +(define vector-length ##vector-length) + + +;;;============================================================================ + +;;; Iteration + + +(define-proc-check (vector-fold kons knil vec . vectors) + (macro-check-vector + vec + 2 + (vector-fold kons knil vec vectors) + (if (null? vectors) + (%vector-fold1 kons knil (vector-length vec) vec) + (%vector-fold2+ kons knil + (%smallest-length vectors + (vector-length vec) + vector-fold) + (cons vec vectors))))) + +(define-proc-check (vector-fold-right kons knil vec . vectors) + (letrec ((loop1 (lambda (kons knil vec i) + (if (negative? i) + knil + (loop1 kons (kons i knil (vector-ref vec i)) + vec + (- i 1))))) + (loop2+ (lambda (kons knil vectors i) + (if (negative? i) + knil + (loop2+ kons + (apply kons i knil + (vectors-ref vectors i)) + vectors + (- i 1)))))) + (macro-check-vector + vec + 2 + (vector-fold-right kons knil vec) + (if (null? vectors) + (loop1 kons knil vec (- (vector-length vec) 1)) + (loop2+ kons knil (cons vec vectors) + (- (%smallest-length vectors + (vector-length vec) + vector-fold-right) + 1)))))) + + +(define-proc-vector-check + (vector-map f vec . vectors) + (if (null? vectors) + (let ((len (vector-length vec))) + (%vector-map1! f (make-vector len) vec len)) + (let ((len (%smallest-length vectors + (vector-length vec) + vector-map))) + (%vector-map2+! f (make-vector len) (cons vec vectors) + len)))) + + +(define-proc-vector-check + (vector-map! f vec . vectors) + (if (null? vectors) + (%vector-map1! f vec vec (vector-length vec)) + (%vector-map2+! f vec (cons vec vectors) + (%smallest-length vectors + (vector-length vec) + vector-map!)))) + + +(define-proc-vector-check + (vector-for-each f vec . vectors) + (letrec ((for-each1 + (lambda (f vec i len) + (cond ((< i len) + (f i (vector-ref vec i)) + (for-each1 f vec (+ i 1) len))))) + (for-each2+ + (lambda (f vecs i len) + (cond ((< i len) + (apply f i (vectors-ref vecs i)) + (for-each2+ f vecs (+ i 1) len)))))) + (if (null? vectors) + (for-each1 f vec 0 (vector-length vec)) + (for-each2+ f (cons vec vectors) 0 + (%smallest-length vectors + (vector-length vec) + vector-for-each))))) + + +(define-proc-vector-check (vector-count pred? vec . vectors) + (if (null? vectors) + (%vector-fold1 (lambda (index count elt) + (if (pred? index elt) + (+ count 1) + count)) + 0 + (vector-length vec) + vec) + (%vector-fold2+ (lambda (index count . elts) + (if (apply pred? index elts) + (+ count 1) + count)) + 0 + (%smallest-length vectors + (vector-length vec) + vector-count) + (cons vec vectors)))) + + +;;;============================================================================ + +;;; Searching + + +(define-proc-vector-check + (vector-index pred? vec . vectors) + (vector-index/skip pred? vec vectors vector-index)) + + +(define-proc-vector-check + (vector-skip pred? vec . vectors) + (vector-index/skip (lambda elts (not (apply pred? elts))) + vec vectors + vector-skip)) + + +(define vector-index/skip +(letrec ((loop1 (lambda (pred? vec len i) + (cond ((= i len) #f) + ((pred? (vector-ref vec i)) i) + (else (loop1 pred? vec len (+ i 1)))))) + (loop2+ (lambda (pred? vectors len i) + (cond ((= i len) #f) + ((apply pred? (vectors-ref vectors i)) i) + (else (loop2+ pred? vectors len + (+ i 1))))))) + (lambda (pred? vec vectors callee) + (if (null? vectors) + (loop1 pred? vec (vector-length vec) 0) + (loop2+ pred? (cons vec vectors) + (%smallest-length vectors + (vector-length vec) + callee) + 0))))) + + +(define-proc-vector-check + (vector-index-right pred? vec . vectors) + (vector-index/skip-right pred? vec vectors vector-index-right)) + + +(define-proc-vector-check + (vector-skip-right pred? vec . vectors) + (vector-index/skip-right (lambda elts (not (apply pred? elts))) + vec vectors + vector-index-right)) + + +(define vector-index/skip-right + (letrec ((loop1 (lambda (pred? vec i) + (cond ((negative? i) #f) + ((pred? (vector-ref vec i)) i) + (else (loop1 pred? vec (- i 1)))))) + (loop2+ (lambda (pred? vectors i) + (cond ((negative? i) #f) + ((apply pred? (vectors-ref vectors i)) i) + (else (loop2+ pred? vectors (- i 1))))))) + (lambda (pred? vec vectors callee) + (if (null? vectors) + (loop1 pred? vec (- (vector-length vec) 1)) + (loop2+ pred? (cons vec vectors) + (- (%smallest-length vectors + (vector-length vec) + callee) + 1)))))) + + +(define (vector-binary-search vec value cmp + #!optional (start 0) + (end (macro-absent-obj))) + (with-vector-check (vector-binary-search vec value cmp) + (macro-check-procedure + cmp + 2 + (vector-binary-search vec value cmp) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (let loop ((start start) (end end) (j #f)) + (let ((i (quotient (+ start end) 2))) + (if (or (= start end) (and j (= i j))) + #f + (let ((comparison (cmp (vector-ref vec i) value))) + (cond ((zero? comparison) i) + ((positive? comparison) (loop start i i)) + (else (loop i end i))))))))))) + + +(define-proc-vector-check + (vector-any pred? vec . vectors) + (letrec ((loop1 (lambda (pred? vec i len len-1) + (and (not (= i len)) + (if (= i len-1) + (pred? (vector-ref vec i)) + (or (pred? (vector-ref vec i)) + (loop1 pred? vec (+ i 1) + len len-1)))))) + (loop2+ (lambda (pred? vectors i len len-1) + (and (not (= i len)) + (if (= i len-1) + (apply pred? (vectors-ref vectors i)) + (or (apply pred? (vectors-ref vectors i)) + (loop2+ pred? vectors (+ i 1) + len len-1))))))) + (if (null? vectors) + (let ((len (vector-length vec))) + (loop1 pred? vec 0 len (- len 1))) + (let ((len (%smallest-length vectors + (vector-length vec) + vector-any))) + (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))) + + +(define-proc-vector-check + (vector-every pred? vec . vectors) + (letrec ((loop1 (lambda (pred? vec i len len-1) + (or (not (= i len)) + (if (= i len-1) + (pred? (vector-ref vec i)) + (and (pred? (vector-ref vec i)) + (loop1 pred? vec (+ i 1) + len len-1)))))) + (loop2+ (lambda (pred? vectors i len len-1) + (or (= i len) + (if (= i len-1) + (apply pred? (vectors-ref vectors i)) + (and (apply pred? (vectors-ref vectors i)) + (loop2+ pred? vectors (+ i 1) + len len-1))))))) + (if (null? vectors) + (let ((len (vector-length vec))) + (loop1 pred? vec 0 len (- len 1))) + (let ((len (%smallest-length vectors + (vector-length vec) + vector-every))) + (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))) + + +;;;============================================================================ + +;;; Mutators + + +(define vector-set! ##vector-set!) + + +(define-vector-check + (vector-swap! vec i j) + (let ((x (vector-ref vec i))) + (vector-set! vec i (vector-ref vec j)) + (vector-set! vec j x))) + +(define + (vector-fill! vec val #!optional (start 0) (end (macro-absent-obj))) + (with-vector-check (vector-fill! vec val start end) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (subvector-fill! vec start end val)))) + + +(define (vector-reverse! vec #!optional (start 0) (end (macro-absent-obj))) + (macro-force-vars (vec start end) + (macro-check-vector + vec + 0 + (vector-reverse! vec start end) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (letrec ((loop (lambda (vec i j) + (cond ((<= i j) + (let ((v (vector-ref vec i))) + (vector-set! vec i (vector-ref vec j)) + (vector-set! vec j v) + (loop vec (+ i 1) (- j 1)))))))) + (loop vec start (- end 1))))))) + + +(define (vector-copy! vec-target tstart vec-source + #!optional (sstart 0) (send (macro-absent-obj))) + (with-vector-check (vector-copy! vec-target tstart vec-source sstart send) + (macro-check-vector + vec-source + 2 + (vector-copy! vec-target tstart vec-source sstart send) + (let ((send (if (equal? send (macro-absent-obj)) + (vector-length vec-source) + send))) + (subvector-move! vec-source sstart send vec-target tstart))))) + + +(define (vector-reverse-copy! target tstart source + #!optional (sstart 0) (send (macro-absent-obj))) + (with-vector-check (vector-reverse-copy! target tstart source sstart send) + (macro-check-vector + source + 2 + (vector-reverse-copy! target tstart source sstart send) + (let ((send (if (equal? send (macro-absent-obj)) + (vector-length source) + send))) + (letrec ((loop (lambda (target source sstart i j) + (cond ((>= i sstart) + (vector-set! target j (vector-ref source i)) + (loop target source sstart + (- i 1) + (+ j 1))))))) + (loop target source sstart + (- send 1) + tstart)))))) + + +;;;============================================================================ + +;;; Conversion + + +(define vector->list ##vector->list) + + +(define (reverse-vector->list vec #!optional (start 0) + (end (macro-absent-obj))) + (with-vector-check + (reverse-vector->list vec start end) + (let ((end (if (equal? end (macro-absent-obj)) + (vector-length vec) + end))) + (do ((i start (+ i 1)) + (result '() (cons (vector-ref vec i) result))) + ((= i end) result))))) + + +(define list->vector ##list->vector) + + +(define (reverse-list->vector lst #!optional (start 0) + (end (macro-absent-obj))) + (let ((end (if (equal? end (macro-absent-obj)) + (length lst) + end)) + (f (lambda (index l) (values (car l) (cdr l))))) + (vector-unfold-right f (- end start) (list-tail lst start)))) + + ;;; todo type check for list + +;;;============================================================================ diff --git a/srfi/43/43.sld b/srfi/43/43.sld new file mode 100644 index 0000000..ae0acbe --- /dev/null +++ b/srfi/43/43.sld @@ -0,0 +1,61 @@ +;;;============================================================================ + +;;; File: "43.sld" + +;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. + +;;;============================================================================ + +;;; SRFI 43, Vector library + +(define-library (srfi 43) + + (export + make-vector + vector + vector-unfold + vector-unfold-right + vector-copy + vector-reverse-copy + vector-append + vector-concatenate + + vector? + vector-empty? + vector= + + vector-ref + vector-length + + vector-fold + vector-fold-right + vector-map + vector-map! + vector-for-each + vector-count + + vector-index + vector-index-right + vector-skip + vector-skip-right + vector-binary-search + vector-any + vector-every + + vector-set! + vector-swap! + vector-fill! + vector-reverse! + vector-copy! + vector-reverse-copy! + + vector->list + reverse-vector->list + list->vector + reverse-list->vector + ) + +; (import (gambit)) + (include "43.scm") +) diff --git a/srfi/43/makefile b/srfi/43/makefile new file mode 100644 index 0000000..cd1513a --- /dev/null +++ b/srfi/43/makefile @@ -0,0 +1,12 @@ +# Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +# Copyright (c) 1994-2020 by Marc Feeley, All Rights Reserved. + +herefromlib = srfi/43 +libfromhere = ../.. +SUBDIRS = +HEADERS_SCM = 43\#.scm +MODULES_SCM = 43.scm 43.sld test.scm +MAIN_MODULES = 43 +OTHER_RCFILES = makefile + +include $(libfromhere)/module-common.mk diff --git a/srfi/43/test.scm b/srfi/43/test.scm new file mode 100644 index 0000000..2a400ab --- /dev/null +++ b/srfi/43/test.scm @@ -0,0 +1,854 @@ +;;;============================================================================ + +;;; File: "test.scm" + +;;; Copyright (c) 2018-2020 by Antoine Doucet, All Rights Reserved. +;;; Copyright (c) 2018-2020 by Marc Feeley, All Rights Reserved. + +;;;============================================================================ + +;;; SRFI 43, Vector library. + +(import (srfi 43)) +(import (_test)) + +;;;============================================================================ +;;; Constructors +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; make-vector + + ;;; primitive R5Rs ##make-vector + + (check-equal? (make-vector 4) + #(0 0 0 0)) + + (check-equal? (make-vector 4 1) + #(1 1 1 1)) + +;;;---------------------------------------------------------------------------- +;;; vector + + ;;; primitive R5Rs ##vector + + (check-equal? (vector 0) + #(0)) + + (check-equal? (vector 0 1 2 3) + #(0 1 2 3)) + + +;;;---------------------------------------------------------------------------- +;;; vector-unfold + + (check-equal? + (vector-unfold + (lambda (i x) (values x (+ x 1))) + 5 + 0) + #(0 1 2 3 4)) + + (let ((vec (vector 0 1 2 3 4))) + (check-equal? + (vector-unfold (lambda (i) (vector-ref vec i)) + (vector-length vec)) + vec)) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold (lambda () '()) 1))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold (lambda (x1) '()) 1 2))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold (lambda (x1) '())))) + (check-exn + wrong-number-of-arguments-exception? + (lambda () (vector-unfold (lambda (x1 x2 x3) (values 1 2 3)) + 1 2 ))) + (check-tail-exn + type-exception? + (lambda () (vector-unfold 0 1 2))) + + +;;;---------------------------------------------------------------------------- +;;; vector-unfold-right + + (check-equal? + (vector-unfold-right (lambda (i x) (values x (+ x 1))) 5 0) + #(4 3 2 1 0)) + + (let ((vec #(1 2 3 4 5))) + (check-equal? + (vector-unfold-right (lambda (i x) (values (vector-ref vec x) (+ x 1))) + (vector-length vec) + 0) + #(5 4 3 2 1))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold-right (lambda () '()) 1))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold-right (lambda (x1) '()) 1 2))) + + (check-exn + wrong-number-of-arguments-exception? + (lambda () + (vector-unfold-right (lambda (x1) '())))) + (check-exn + wrong-number-of-arguments-exception? + (lambda () (vector-unfold-right (lambda (x1 x2 x3) (values 1 2 3)) + 1 2 ))) + + (check-tail-exn + type-exception? + (lambda () (vector-unfold 0 1 2))) + +;;;---------------------------------------------------------------------------- +;;; vector-copy + + (let ((vec #(0 1 2 3 4))) + (check-equal? + (vector-copy vec) + vec) + (check-equal? + vec #(0 1 2 3 4))) + + (let ((vec #(0 1 2 3 4 5))) + (check-equal? + (vector-copy vec 3) + #(3 4 5)) + (check-equal? + vec #(0 1 2 3 4 5))) + + (let ((vec #(0 1 2 3 4 5))) + (check-equal? + (vector-copy vec 3 10 6) + #(3 4 5 6 6 6 6))) + + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-copy))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-copy 0 1 2 3 4))) + + (check-tail-exn + type-exception? + (lambda () (vector-copy 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-reverse-copy + + (let ((vec #(5 4 3 2 1))) + (check-equal? + (vector-reverse-copy vec 2 5) + #(1 2 3)) + (check-equal? + vec + #(5 4 3 2 1))) + + (let ((vec #(3 2 1))) + (check-equal? + (vector-reverse-copy vec ) + #(1 2 3))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse-copy))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse-copy 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (vector-reverse-copy 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-append + + ;;; primitive R5Rs ##vector-append + +;;;---------------------------------------------------------------------------- +;;; vector-concatenate + + ;;; primitive ##append-vectors + +;;;============================================================================ +;;; Predicates +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector? + + ;;; primitive R5Rs ##vector? + +;;;---------------------------------------------------------------------------- +;;; vector-empty? + + (check-true (vector-empty? #())) + (check-false (vector-empty? #(0))) + (check-false (vector-empty? #(#()))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-empty?))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-empty? 0 1))) + + (check-tail-exn + type-exception? + (lambda () (vector-empty? 0))) + +;;;---------------------------------------------------------------------------- +;;; vector= + + (check-true (vector= equal? #() #())) + + (let ((vec #())) + (check-true (vector= eq? vec vec))) + (check-true (vector= (lambda (a b) #t) #(1 2 3) #(4 5 6))) + (check-false (vector= eq? #(0 1 2 3) #())) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector= 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector= 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (vector= 0 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector= eq? 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector= eq? #() 0))) + + +;;;============================================================================ +;;; Selectors +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector-ref + + ;;; primitive R5Rs ##vector-ref + +;;;---------------------------------------------------------------------------- +;;; vector-length + + ;;; primitive R5Rs ##vector-length + + +;;;============================================================================ +;;; Iteration +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector-fold + + (let ((vec #(0 1 2 3))) + (check-equal? + (vector-fold (lambda (index tail elt) (cons elt tail)) + '() vec) + '(3 2 1 0)) + (check-equal? + vec + #(0 1 2 3))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-fold 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-fold 0 1 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-fold (lambda (x1 x2) '()) 1 0 #()))) + + (check-exn + type-exception? + (lambda () (vector-fold (lambda (x1 x2) '()) 1 #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-fold-right + + + (check-equal? + (vector-fold-right (lambda (index tail elt) (cons elt tail)) + '() #(0 1 2 3)) + '(0 1 2 3)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-fold-right 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-fold-right 0 1 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-fold-right (lambda (x1 x2) '()) 1 0 #()))) + + (check-exn + type-exception? + (lambda () (vector-fold-right (lambda (x1 x2) '()) 1 #() 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-map + + (let ((vec #(0 1 2 3 4))) + (check-equal? + (vector-map (lambda (i x) (* x x)) vec) + #(0 1 4 9 16)) + (check-equal? + vec + #(0 1 2 3 4))) + + (let ((vec #(1 2 3 4 5))) + (check-equal? + (vector-map (lambda (i x) (- x i)) vec ) + #(1 1 1 1 1)) + (check-equal? + vec + #(1 2 3 4 5))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-map 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-map 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-map (lambda (x1 x2) '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-map (lambda (x1 x2) '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-map! + + (check-equal? + (vector-map (lambda (i x) (* x x)) #(0 1 2 3 4)) + #(0 1 4 9 16)) + + (check-equal? + (vector-map (lambda (i x) (- x i)) #(1 2 3 4 5) ) + #(1 1 1 1 1)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-map 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-map 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-map (lambda (i x) '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-map (lambda (i x) '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-for-each + + (let ((vec #(0 1 2 3))) + (vector-for-each (lambda (i x) (vector-set! vec i (* x x))) + vec) + (check-equal? vec + #(0 1 4 9))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-for-each 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-for-each 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-for-each (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-for-each (lambda () '()) #() 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-count + + (check-equal? + (vector-count (lambda (i elt) (even? elt)) #(1 2 3 4)) + 2) + + (check-equal? + (vector-count (lambda (i x y) (< x y)) '#(0 1 2 3 4) '#(1 2 3 4 4 4)) + 4) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-count 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-count 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-count (lambda () '()) 0))) + + + (check-exn + type-exception? + (lambda () (vector-count (lambda () '()) #() 0))) + + +;;;============================================================================ +;;; Searching +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector-index + + (check-equal? + (vector-index even? #(1 2 3 4)) + 1) + + (check-equal? + (vector-index < #(1 2 3 4) #(2 2 2 2)) + 0) + + (check-false + (vector-index = #(1 1 1) #(2 2 2 2 2))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-index 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-index 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-index (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-index (lambda () '()) #() 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-index-right + + (check-equal? + (vector-index-right even? #(1 2 3 4)) + 3) + + (check-equal? + (vector-index-right <= #(1 2 3 4) #(2 2 2 2)) + 1) + + (check-false + (vector-index-right = #(1 1 1) #(2 2 2 2 2))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-index-right 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-index-right 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-index-right (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-index-right (lambda () '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-skip + + (check-equal? + (vector-skip number? #(0 1 2 a b 1 2 3)) + 3) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-skip 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-skip 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-skip (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-skip (lambda () '()) #() 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-skip-right + + (check-equal? + (vector-skip-right number? #(0 1 2 a b 0 1 2)) + 4) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-skip-right 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-skip-right 0 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-skip-right (lambda () '()) 0))) + + (check-exn + type-exception? + (lambda () (vector-skip-right (lambda () '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-binary-search + + (let ((comp? (lambda (x1 x2) + (cond ((< x1 x2) -1) + ((= x1 x2) 0) + (else 1))))) + (check-equal? + (vector-binary-search #(1 2 3 4) 2 comp?) + 1)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-binary-search 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-binary-search 0 1 2 3 4 5))) + + + (check-tail-exn + type-exception? + (lambda () (vector-binary-search 0 0 (lambda () '())))) + + (check-tail-exn + type-exception? + (lambda () (vector-binary-search #() 0 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-any + + (check-true + (vector-any = #(0 0 0 0) #(1 0 1) #(2 0 2 0))) + + (check-false + (vector-any = #(0 0 0) #(1 1 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-any 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-any 0 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-any (lambda () '()) 0 #()))) + + (check-exn + type-exception? + (lambda () (vector-any (lambda () '()) #() 0))) + + +;;;---------------------------------------------------------------------------- +;;; vector-every + + (check-false + (vector-every = #(0 0 0 0) #(1 0 1) #(2 0 2 0))) + + (check-true + (vector-every = #(1 1 1) #(1 1 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-every 0))) + + (check-tail-exn + type-exception? + (lambda () (vector-every 0 #() #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-every (lambda () '()) 0 #()))) + + (check-exn + type-exception? + (lambda () (vector-every (lambda () '()) #() 0))) + +;;;============================================================================ +;;; Mutators +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector-set! + + ;;; primitive R5Rs ##vector-set! + +;;;---------------------------------------------------------------------------- +;;; vector-swap! + + (let ((vec #(0 1 2 3 4))) + (vector-swap! vec 0 1) + (check-equal? + vec + #(1 0 2 3 4))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-swap! 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-swap! 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (vector-swap! 0 0 1))) + +;;;---------------------------------------------------------------------------- +;;; vector-fill! + + (let ((vec #(0 0 0 0))) + (vector-fill! vec 1 0 2) + (check-equal? + vec + #(1 1 0 0))) + + (let ((vec #(0 0 0 0))) + (vector-fill! vec 1) + (check-equal? + vec + #(1 1 1 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-fill! 0))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-fill! 0 1 2 3 4))) + + (check-tail-exn + type-exception? + (lambda () (vector-fill! 0 1))) + +;;;---------------------------------------------------------------------------- +;;; vector-reverse! + + + (let ((vec #(0 1 2 3 4))) + (vector-reverse! vec) + (check-equal? + vec + #(4 3 2 1 0))) + + (let ((vec #(0 1 2 3 4))) + (vector-reverse! vec 0 3) + (check-equal? + vec + #(2 1 0 3 4))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse!))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse! 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (vector-reverse! 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-copy! + + (let ((vec1 #(0 1 2 3 4)) + (vec2 #(5 6 7 8 9))) + (vector-copy! vec2 0 vec1) + (check-equal? vec2 vec1)) + + (let ((vec1 #(0 1 2 3 4)) + (vec2 #(5 6 7 8 9))) + (vector-copy! vec2 2 vec1 0 2 ) + (check-equal? + vec2 + #(5 6 0 1 9))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-copy! 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-copy! 0 1 2 3 4 5))) + + (check-tail-exn + type-exception? + (lambda () (vector-copy! 0 1 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-copy! #() 1 0))) + +;;;---------------------------------------------------------------------------- +;;; vector-reverse-copy! + + (let ((vec1 #(0 1 2 3 4)) + (vec2 #(5 6 7 8 9))) + (vector-reverse-copy! vec2 0 vec1) + (check-equal? + vec2 + #(4 3 2 1 0))) + + (let ((vec1 #(0 1 2 3 4)) + (vec2 #(5 6 7 8 9))) + (vector-reverse-copy! vec2 2 vec1 0 2 ) + (check-equal? + vec2 + #(5 6 1 0 9))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse-copy! 0 1))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (vector-reverse-copy! 0 1 2 3 4 5))) + + (check-tail-exn + type-exception? + (lambda () (vector-reverse-copy! 0 1 #()))) + + (check-tail-exn + type-exception? + (lambda () (vector-reverse-copy! #() 1 0))) + + +;;;============================================================================ +;;; Conversion +;;;============================================================================ +;;; +;;;---------------------------------------------------------------------------- +;;; vector->list + + ;;; primitive R5Rs ##vector->list + +;;;---------------------------------------------------------------------------- +;;; reverse-vector->list + + (check-equal? + (reverse-vector->list #(0 1 2 3 4)) + '(4 3 2 1 0)) + + (check-equal? + (reverse-vector->list #(0 1 2 3 4) 1 3) + '(2 1)) + + (check-equal? + (reverse-vector->list #()) + '()) + + (check-equal? + (reverse-vector->list #(0)) + '(0)) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (reverse-vector->list))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (reverse-vector->list 0 1 2 3))) + + (check-tail-exn + type-exception? + (lambda () (reverse-vector->list 0))) + + (check-tail-exn + type-exception? + (lambda () (reverse-vector->list 0))) + +;;;---------------------------------------------------------------------------- +;;; list->vector + + ;;; primitive R5Rs ##list->vector + + (check-equal? + (list->vector '(0 1 2 3)) + #(0 1 2 3)) + +;;;---------------------------------------------------------------------------- +;;; reverse-list->vector + + (check-equal? + (reverse-list->vector '(0 1 2)) + #(2 1 0)) + + (check-equal? + (reverse-list->vector '()) + #()) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (reverse-list->vector))) + + (check-tail-exn + wrong-number-of-arguments-exception? + (lambda () (reverse-list->vector 0 1 2 3))) + +;;;============================================================================ From 2c7e944bb7bdbbea30b409210fcda6b5aa66bf01 Mon Sep 17 00:00:00 2001 From: Tchido-o Date: Fri, 10 Jan 2020 18:23:29 -0500 Subject: [PATCH 4/4] Add optimisations to srfi 43 & srfi 133 --- srfi/133/133.scm | 199 +++++++++++++++++++++++++--------------------- srfi/133/test.scm | 2 +- srfi/43/43.scm | 99 +++++++++++++---------- srfi/43/43.sld | 2 +- srfi/43/test.scm | 10 +-- 5 files changed, 173 insertions(+), 139 deletions(-) diff --git a/srfi/133/133.scm b/srfi/133/133.scm index c0b6b50..9665aae 100644 --- a/srfi/133/133.scm +++ b/srfi/133/133.scm @@ -37,7 +37,6 @@ 0 (function-name vec . rest) function-def))))) - (define-syntax with-proc-check (syntax-rules () ((with-proc-check (function-name proc . rest) function-def) @@ -48,6 +47,16 @@ (function-name proc . rest) function-def))))) +(define-syntax with-proc-vector-check + (syntax-rules () + ((with-proc-vector-check (function-name proc vec . rest) function-def) + (with-proc-check(function-name proc vec . rest) + (macro-check-vector + vec + 1 + (function-name proc vec . rest) + function-def))))) + (define-syntax define-vector-check (syntax-rules () ((define-vector-check (function-name vec . rest) function-def) @@ -318,9 +327,8 @@ (- send 1) tstart)))))) -(define-proc-vector-check - (vector-unfold! f vec start end . initial-seeds) - (letrec ((tabulate! ; Special zero-seed case. +(define vector-unfold! + (letrec ((tabulate! ; Special zero-seed case. (lambda (f vec i len) (cond ((< i len) (vector-set! vec i (f i)) @@ -339,44 +347,45 @@ (apply f i seeds) (vector-set! vec i elt) (unfold2+! f vec (+ i 1) len new-seeds)))))) - (if (< (vector-length vec) start) - #!void - (cond ((null? initial-seeds) - (tabulate! f vec start end)) - ((null? (cdr initial-seeds)) - (unfold1! f vec start end (car initial-seeds))) - (else - (unfold2+! f vec start end initial-seeds)))))) - -(define-proc-vector-check - (vector-unfold-right! f vec start end . initial-seeds) - (letrec ((tabulate! - (lambda (f vec i) - (cond ((>= i start) - (vector-set! vec i (f i)) - (tabulate! f vec (- i 1)))))) - (unfold1! - (lambda (f vec i seed) - (if (>= i start) - (receive (elt new-seed) - (f i seed) - (vector-set! vec i elt) - (unfold1! f vec (- i 1) new-seed))))) - (unfold2+! - (lambda (f vec i seeds) - (if (>= i start) - (receive (elt . new-seeds) - (apply f i seeds) - (vector-set! vec i elt) - (unfold2+! f vec (- i 1) new-seeds)))))) + (lambda (f vec start end . initial-seeds) + (with-proc-vector-check (vector-unfold! f vec start end . initial-seeds) + (if (< (vector-length vec) start) + (void) + (cond ((null? initial-seeds) + (tabulate! f vec start end)) + ((null? (cdr initial-seeds)) + (unfold1! f vec start end (car initial-seeds))) + (else + (unfold2+! f vec start end initial-seeds)))))))) + +(define (vector-unfold-right! f vec start end . initial-seeds) + (letrec ((tabulate! + (lambda (f vec i) + (cond ((>= i start) + (vector-set! vec i (f i)) + (tabulate! f vec (- i 1)))))) + (unfold1! + (lambda (f vec i seed) + (if (>= i start) + (receive (elt new-seed) + (f i seed) + (vector-set! vec i elt) + (unfold1! f vec (- i 1) new-seed))))) + (unfold2+! + (lambda (f vec i seeds) + (if (>= i start) + (receive (elt . new-seeds) + (apply f i seeds) + (vector-set! vec i elt) + (unfold2+! f vec (- i 1) new-seeds)))))) + (with-proc-vector-check (vector-unfold-right! f vec start end initial-seeds) (let ((i (- end 1))) (cond ((null? initial-seeds) (tabulate! f vec i)) ((null? (cdr initial-seeds)) (unfold1! f vec i (car initial-seeds))) (else - (unfold2+! f vec i initial-seeds)))))) - + (unfold2+! f vec i initial-seeds))))))) ;;;============================================================================ @@ -396,7 +405,7 @@ vector-fold) (cons vec vectors))))) -(define-proc-check (vector-fold-right kons knil vec . vectors) +(define vector-fold-right (letrec ((loop1 (lambda (kons knil vec i) (if (negative? i) knil @@ -411,6 +420,8 @@ (vectors-ref vectors i)) vectors (- i 1)))))) + (lambda (kons knil vec . vectors) + (with-proc-check (vector-fold-right kons knil vec . vectors) (macro-check-vector vec 2 @@ -421,7 +432,7 @@ (- (%smallest-length vectors (vector-length vec) vector-fold-right) - 1)))))) + 1)))))))) (define-proc-vector-check (vector-map f vec . vectors) ;;; R7Rs #unimplemented in Gambit @@ -453,9 +464,8 @@ vector-map!)))) -(define-proc-vector-check - (vector-for-each f vec . vectors ) ;;; R7Rs #unimplemented in Gambit - (letrec ((for-each1 +(define vector-for-each + (letrec ((for-each1 ;;; R7Rs #unimplemented in Gambit (lambda (f vec i len) (cond ((< i len) (f (vector-ref vec i)) @@ -465,12 +475,14 @@ (cond ((< i len) (apply f (vectors-ref vecs i)) (for-each2+ f vecs (+ i 1) len)))))) + (lambda (f vec . vectors) + (with-proc-vector-check (vector-for-each f vec . vectors) (if (null? vectors) (for-each1 f vec 0 (vector-length vec)) (for-each2+ f (cons vec vectors) 0 (%smallest-length vectors (vector-length vec) - vector-for-each))))) + vector-for-each))))))) (define-proc-vector-check (vector-count pred? vec . vectors) @@ -514,65 +526,26 @@ (define-proc-vector-check (vector-index pred? vec . vectors) - (vector-index/skip pred? vec vectors vector-index)) + (%vector-index/skip pred? vec vectors vector-index)) (define-proc-vector-check (vector-skip pred? vec . vectors) - (vector-index/skip (lambda elts (not (apply pred? elts))) + (%vector-index/skip (lambda elts (not (apply pred? elts))) vec vectors vector-skip)) - - -(define vector-index/skip -(letrec ((loop1 (lambda (pred? vec len i) - (cond ((= i len) #f) - ((pred? (vector-ref vec i)) i) - (else (loop1 pred? vec len (+ i 1)))))) - (loop2+ (lambda (pred? vectors len i) - (cond ((= i len) #f) - ((apply pred? (vectors-ref vectors i)) i) - (else (loop2+ pred? vectors len - (+ i 1))))))) - (lambda (pred? vec vectors callee) - (if (null? vectors) - (loop1 pred? vec (vector-length vec) 0) - (loop2+ pred? (cons vec vectors) - (%smallest-length vectors - (vector-length vec) - callee) - 0))))) - - (define-proc-vector-check (vector-index-right pred? vec . vectors) - (vector-index/skip-right pred? vec vectors vector-index-right)) + (%vector-index/skip-right pred? vec vectors vector-index-right)) (define-proc-vector-check (vector-skip-right pred? vec . vectors) - (vector-index/skip-right (lambda elts (not (apply pred? elts))) + (%vector-index/skip-right (lambda elts (not (apply pred? elts))) vec vectors vector-index-right)) -(define vector-index/skip-right - (letrec ((loop1 (lambda (pred? vec i) - (cond ((negative? i) #f) - ((pred? (vector-ref vec i)) i) - (else (loop1 pred? vec (- i 1)))))) - (loop2+ (lambda (pred? vectors i) - (cond ((negative? i) #f) - ((apply pred? (vectors-ref vectors i)) i) - (else (loop2+ pred? vectors (- i 1))))))) - (lambda (pred? vec vectors callee) - (if (null? vectors) - (loop1 pred? vec (- (vector-length vec) 1)) - (loop2+ pred? (cons vec vectors) - (- (%smallest-length vectors - (vector-length vec) - callee) - 1)))))) (define (vector-binary-search vec value cmp @@ -596,8 +569,7 @@ (else (loop i end i))))))))))) -(define-proc-vector-check - (vector-any pred? vec . vectors) +(define vector-any (letrec ((loop1 (lambda (pred? vec i len len-1) (and (not (= i len)) (if (= i len-1) @@ -612,17 +584,18 @@ (or (apply pred? (vectors-ref vectors i)) (loop2+ pred? vectors (+ i 1) len len-1))))))) + (lambda (pred? vec . vectors) + (with-proc-vector-check (vector-any pred? vec . vectors) (if (null? vectors) (let ((len (vector-length vec))) (loop1 pred? vec 0 len (- len 1))) (let ((len (%smallest-length vectors (vector-length vec) vector-any))) - (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))) + (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))))) -(define-proc-vector-check - (vector-every pred? vec . vectors) +(define vector-every (letrec ((loop1 (lambda (pred? vec i len len-1) (or (not (= i len)) (if (= i len-1) @@ -637,13 +610,15 @@ (and (apply pred? (vectors-ref vectors i)) (loop2+ pred? vectors (+ i 1) len len-1))))))) + (lambda (pred? vec . vectors) + (with-proc-vector-check (vector-every pred? vec . vectors) (if (null? vectors) (let ((len (vector-length vec))) (loop1 pred? vec 0 len (- len 1))) (let ((len (%smallest-length vectors (vector-length vec) vector-every))) - (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))) + (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))))) (define-proc-vector-check (vector-partition pred? vec) @@ -827,4 +802,46 @@ (loop/r->l target source sstart (- send 1) (+ -1 tstart send (- sstart))))))) + + +(define %vector-index/skip +(letrec ((loop1 (lambda (pred? vec len i) + (cond ((= i len) #f) + ((pred? (vector-ref vec i)) i) + (else (loop1 pred? vec len (+ i 1)))))) + (loop2+ (lambda (pred? vectors len i) + (cond ((= i len) #f) + ((apply pred? (vectors-ref vectors i)) i) + (else (loop2+ pred? vectors len + (+ i 1))))))) + (lambda (pred? vec vectors callee) + (if (null? vectors) + (loop1 pred? vec (vector-length vec) 0) + (loop2+ pred? (cons vec vectors) + (%smallest-length vectors + (vector-length vec) + callee) + 0))))) + + + + +(define %vector-index/skip-right + (letrec ((loop1 (lambda (pred? vec i) + (cond ((negative? i) #f) + ((pred? (vector-ref vec i)) i) + (else (loop1 pred? vec (- i 1)))))) + (loop2+ (lambda (pred? vectors i) + (cond ((negative? i) #f) + ((apply pred? (vectors-ref vectors i)) i) + (else (loop2+ pred? vectors (- i 1))))))) + (lambda (pred? vec vectors callee) + (if (null? vectors) + (loop1 pred? vec (- (vector-length vec) 1)) + (loop2+ pred? (cons vec vectors) + (- (%smallest-length vectors + (vector-length vec) + callee) + 1)))))) + ;;;============================================================================ diff --git a/srfi/133/test.scm b/srfi/133/test.scm index 02132ee..af60a00 100644 --- a/srfi/133/test.scm +++ b/srfi/133/test.scm @@ -73,6 +73,7 @@ wrong-number-of-arguments-exception? (lambda () (vector-unfold (lambda (x1 x2 x3) (values 1 2 3)) 1 2 ))) + (check-exn type-exception? (lambda () (vector-unfold 0 1 2))) @@ -395,7 +396,6 @@ type-exception? (lambda () (vector-map (lambda (i x) '()) #() 0))) - ;;;---------------------------------------------------------------------------- ;;; vector-for-each diff --git a/srfi/43/43.scm b/srfi/43/43.scm index 8bd7e1d..2aff39f 100644 --- a/srfi/43/43.scm +++ b/srfi/43/43.scm @@ -11,7 +11,6 @@ (##supply-module srfi/43) -(##namespace ("srfi/43#")) ;; in srfi/43# (##include "~~lib/_prim#.scm") (##include "~~lib/_gambit#.scm") @@ -43,7 +42,18 @@ 0 (function-name proc . rest) function-def))))) - + +(define-syntax with-proc-vector-check + (syntax-rules () + ((with-proc-vector-check (function-name proc vec . rest) function-def) + (with-proc-check (function-name proc vec . rest) + (macro-check-vector + vec + 1 + (function-name proc vec . rest) + function-def))))) + + (define-syntax define-vector-check (syntax-rules () ((define-vector-check (function-name vec . rest) function-def) @@ -65,7 +75,6 @@ 1 (function-name proc vec . rest) function-def))))) - ;;; Todo: accept optional arguments ++ generalise ;;;============================================================================ @@ -98,12 +107,11 @@ vec 3 (%smallest-length vector-list length callee) - (min (##vector-length vec) + (min (vector-length vec) length)))) callee))))) loop)) - (define %vector-fold1 (letrec ((loop (lambda (kons knil len vec i) (if (= i len) @@ -162,7 +170,7 @@ (define vector ##vector) -(define-proc-check (vector-unfold f len . initial-seeds) +(define vector-unfold (letrec ((tabulate! ; Special zero-seed case. (lambda (f vec i len) (cond ((< i len) @@ -182,6 +190,8 @@ (apply f i seeds) (##vector-set! vec i elt) (unfold2+! f vec (+ i 1) len new-seeds)))))) + (lambda (f len . initial-seeds) + (with-proc-check (vector-unfold f len initial-seeds) (let ((vec (make-vector len))) (cond ((null? initial-seeds) (tabulate! f vec 0 len)) @@ -189,10 +199,10 @@ (unfold1! f vec 0 len (car initial-seeds))) (else (unfold2+! f vec 0 len initial-seeds))) - vec))) + vec))))) -(define-proc-check (vector-unfold-right f len . initial-seeds) +(define vector-unfold-right (letrec ((tabulate! (lambda (f vec i) (cond ((>= i 0) @@ -212,6 +222,8 @@ (apply f i seeds) (##vector-set! vec i elt) (unfold2+! f vec (- i 1) new-seeds)))))) + (lambda (f len . initial-seeds) + (with-proc-check (vector-unfold-right f len initial-seeds) (let ((vec (make-vector len)) (i (- len 1))) (cond ((null? initial-seeds) @@ -220,7 +232,7 @@ (unfold1! f vec i (car initial-seeds))) (else (unfold2+! f vec i initial-seeds))) - vec))) + vec))))) (define (vector-copy vec #!optional (start 0) @@ -310,7 +322,7 @@ vector-fold) (cons vec vectors))))) -(define-proc-check (vector-fold-right kons knil vec . vectors) +(define vector-fold-right (letrec ((loop1 (lambda (kons knil vec i) (if (negative? i) knil @@ -325,17 +337,19 @@ (vectors-ref vectors i)) vectors (- i 1)))))) - (macro-check-vector - vec - 2 - (vector-fold-right kons knil vec) - (if (null? vectors) - (loop1 kons knil vec (- (vector-length vec) 1)) - (loop2+ kons knil (cons vec vectors) - (- (%smallest-length vectors - (vector-length vec) - vector-fold-right) - 1)))))) + (lambda (kons knil vec . vectors) + (with-proc-check (vector-fold-right kons knil vec vectors) + (macro-check-vector + vec + 2 + (vector-fold-right kons knil vec) + (if (null? vectors) + (loop1 kons knil vec (- (vector-length vec) 1)) + (loop2+ kons knil (cons vec vectors) + (- (%smallest-length vectors + (vector-length vec) + vector-fold-right) + 1)))))))) (define-proc-vector-check @@ -360,8 +374,7 @@ vector-map!)))) -(define-proc-vector-check - (vector-for-each f vec . vectors) +(define vector-for-each (letrec ((for-each1 (lambda (f vec i len) (cond ((< i len) @@ -372,12 +385,14 @@ (cond ((< i len) (apply f i (vectors-ref vecs i)) (for-each2+ f vecs (+ i 1) len)))))) - (if (null? vectors) - (for-each1 f vec 0 (vector-length vec)) - (for-each2+ f (cons vec vectors) 0 - (%smallest-length vectors - (vector-length vec) - vector-for-each))))) + (lambda (f vec . vectors) + (with-proc-vector-check (vector-for-each f vec vectors) + (if (null? vectors) + (for-each1 f vec 0 (vector-length vec)) + (for-each2+ f (cons vec vectors) 0 + (%smallest-length vectors + (vector-length vec) + vector-for-each))))))) (define-proc-vector-check (vector-count pred? vec . vectors) @@ -407,17 +422,17 @@ (define-proc-vector-check (vector-index pred? vec . vectors) - (vector-index/skip pred? vec vectors vector-index)) + (%vector-index/skip pred? vec vectors vector-index)) (define-proc-vector-check (vector-skip pred? vec . vectors) - (vector-index/skip (lambda elts (not (apply pred? elts))) + (%vector-index/skip (lambda elts (not (apply pred? elts))) vec vectors vector-skip)) -(define vector-index/skip +(define %vector-index/skip (letrec ((loop1 (lambda (pred? vec len i) (cond ((= i len) #f) ((pred? (vector-ref vec i)) i) @@ -439,17 +454,17 @@ (define-proc-vector-check (vector-index-right pred? vec . vectors) - (vector-index/skip-right pred? vec vectors vector-index-right)) + (%vector-index/skip-right pred? vec vectors vector-index-right)) (define-proc-vector-check (vector-skip-right pred? vec . vectors) - (vector-index/skip-right (lambda elts (not (apply pred? elts))) + (%vector-index/skip-right (lambda elts (not (apply pred? elts))) vec vectors vector-index-right)) -(define vector-index/skip-right +(define %vector-index/skip-right (letrec ((loop1 (lambda (pred? vec i) (cond ((negative? i) #f) ((pred? (vector-ref vec i)) i) @@ -489,8 +504,7 @@ (else (loop i end i))))))))))) -(define-proc-vector-check - (vector-any pred? vec . vectors) +(define vector-any (letrec ((loop1 (lambda (pred? vec i len len-1) (and (not (= i len)) (if (= i len-1) @@ -505,17 +519,18 @@ (or (apply pred? (vectors-ref vectors i)) (loop2+ pred? vectors (+ i 1) len len-1))))))) + (lambda (pred? vec . vectors) + (with-proc-vector-check (vector-any pred? vec vectors) (if (null? vectors) (let ((len (vector-length vec))) (loop1 pred? vec 0 len (- len 1))) (let ((len (%smallest-length vectors (vector-length vec) vector-any))) - (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))) + (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))))) -(define-proc-vector-check - (vector-every pred? vec . vectors) +(define vector-every (letrec ((loop1 (lambda (pred? vec i len len-1) (or (not (= i len)) (if (= i len-1) @@ -530,13 +545,15 @@ (and (apply pred? (vectors-ref vectors i)) (loop2+ pred? vectors (+ i 1) len len-1))))))) + (lambda (pred? vec . vectors) + (with-proc-vector-check (vector-every pred? vec vectors) (if (null? vectors) (let ((len (vector-length vec))) (loop1 pred? vec 0 len (- len 1))) (let ((len (%smallest-length vectors (vector-length vec) vector-every))) - (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))) + (loop2+ pred? (cons vec vectors) 0 len (- len 1)))))))) ;;;============================================================================ diff --git a/srfi/43/43.sld b/srfi/43/43.sld index ae0acbe..7670529 100644 --- a/srfi/43/43.sld +++ b/srfi/43/43.sld @@ -56,6 +56,6 @@ reverse-list->vector ) -; (import (gambit)) + (import (gambit)) (include "43.scm") ) diff --git a/srfi/43/test.scm b/srfi/43/test.scm index 2a400ab..7ad9768 100644 --- a/srfi/43/test.scm +++ b/srfi/43/test.scm @@ -1,4 +1,4 @@ -;;;============================================================================ + ;;; File: "test.scm" @@ -18,7 +18,6 @@ ;;; ;;;---------------------------------------------------------------------------- ;;; make-vector - ;;; primitive R5Rs ##make-vector (check-equal? (make-vector 4) @@ -114,7 +113,6 @@ (check-tail-exn type-exception? (lambda () (vector-unfold 0 1 2))) - ;;;---------------------------------------------------------------------------- ;;; vector-copy @@ -246,7 +244,6 @@ type-exception? (lambda () (vector= eq? #() 0))) - ;;;============================================================================ ;;; Selectors ;;;============================================================================ @@ -320,6 +317,7 @@ type-exception? (lambda () (vector-fold-right (lambda (x1 x2) '()) 1 #() 0))) + ;;;---------------------------------------------------------------------------- ;;; vector-map @@ -409,6 +407,7 @@ type-exception? (lambda () (vector-for-each (lambda () '()) #() 0))) + ;;;---------------------------------------------------------------------------- ;;; vector-count @@ -437,7 +436,6 @@ type-exception? (lambda () (vector-count (lambda () '()) #() 0))) - ;;;============================================================================ ;;; Searching ;;;============================================================================ @@ -852,3 +850,5 @@ (lambda () (reverse-list->vector 0 1 2 3))) ;;;============================================================================ + +