From 39742eaceeb7b40ad009f61b8444795b6beb9948 Mon Sep 17 00:00:00 2001 From: ben Date: Wed, 2 Mar 2016 15:32:54 -0500 Subject: [PATCH] [vector] vector-map --- test/vector-fail.rkt | 6 ++++++ test/vector-pass.rkt | 41 +++++++++++++++++++++++++++++++++++++++++ vector.rkt | 41 +++++++++++++++++++++++++++++++++++------ 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/test/vector-fail.rkt b/test/vector-fail.rkt index 474fc08..0717b1a 100644 --- a/test/vector-fail.rkt +++ b/test/vector-fail.rkt @@ -21,6 +21,12 @@ (vector-set!: (vector 0) 0 "hello") ;; Strong update + (vector-ref: (vector-map: (lambda (x) x) (vector #t "ha")) 20) + + (vector-ref: + (vector-map: add1 (vector-map: add1 (vector-map: add1 (vector 0 0 0)))) + 3) + ))) ;; ----------------------------------------------------------------------------- diff --git a/test/vector-pass.rkt b/test/vector-pass.rkt index c22b1ef..c43b1c4 100644 --- a/test/vector-pass.rkt +++ b/test/vector-pass.rkt @@ -134,6 +134,47 @@ (lambda () ((lambda ([f : (-> (Vectorof Any) Natural Any Void)]) (f (vector 0 1 2) 10 9)) vector-set!:)))) + ;) + + ;(test-suite "vector-map:" + (test-case "vector/length map" + (check-equal? (vector-map: add1 (vector 1)) (vector 2))) + + (test-case "vector/length map via let" + (check-equal? + (let-vector: ([v (vector (vector 1) (vector 2 2) + (vector 3 3 3) (vector 4 4 4 4))]) + (vector-map: vector-length: v)) + (vector 1 2 3 4))) + + (test-case "map^3" + (check-equal? + (vector-map: add1 (vector-map: add1 (vector-map: add1 (vector 0 0 0)))) + (vector 3 3 3))) + + (test-case "plain map" + (check-equal? + ((lambda ([v : (Vectorof (Vectorof Any))]) + (vector-map: vector-length: v)) + (vector (vector 1) (vector 2 2) (vector 3 3 3) (vector 4 4 4 4))) + (vector 1 2 3 4))) + + (test-case "higher-order map pass" + (check-equal? + ((lambda ([f : (-> (-> Symbol String) (Vectorof Symbol) (Vectorof String))]) + (f symbol->string '#(x yy z))) + vector-map:) + (vector "x" "yy" "z"))) + + (test-case "higher-order map fail" + (check-exn exn:fail:contract? + (lambda () + ((lambda ([f : (-> (-> Integer Integer) (Vectorof Integer) (Vectorof Integer))]) + (vector-ref: (f add1 (vector 0 0)) 3)) + vector-map:)))) + ;) + + ;(test-suite "vector-map!:" ;) ;; -- define-vector: diff --git a/vector.rkt b/vector.rkt index f79b138..40ed7ce 100644 --- a/vector.rkt +++ b/vector.rkt @@ -8,9 +8,12 @@ vector-length: vector-ref: vector-set!: - ;vector-map: + vector-map: ;vector-append: ;vector->list + ;vector->immutable-vector + ;vector-fill! + ; ;; TODO and a few more @@ -24,6 +27,7 @@ (only-in racket/unsafe/ops unsafe-vector-set! unsafe-vector-ref) + racket/vector (for-syntax typed/racket/base syntax/id-table @@ -105,8 +109,29 @@ [(_ e* ...) (syntax/loc stx (vector-set! e* ...))])) +(define-syntax (vector-map: stx) + (syntax-parse stx + [(_ f v:vector/length) + #:with (i* ...) (for/list ([i (in-range (syntax-e #'v.length))]) i) + ;; TODO need to set syntax property? + #:with v+ (syntax-property + (if (small-vector-size? (syntax-e #'v.length)) + (syntax/loc stx (vector (f (unsafe-vector-ref v.expanded 'i*)) ...)) + (syntax/loc stx (build-vector 'v.length (lambda ([i : Integer]) + (unsafe-vector-ref v.expanded i))))) + vector-length-key + (syntax-e #'v.length)) + (syntax/loc stx v+)] + [_:id + (syntax/loc stx vector-map)] + [(_ e* ...) + (syntax/loc stx (vector-map e* ...))])) + ;; ----------------------------------------------------------------------------- +(define-for-syntax (small-vector-size? n) + (< n 101)) + ;; Assume `stx` is creating a vector; get the length of the vector to-be-made (define-for-syntax (parse-vector-length stx) (cond @@ -122,9 +147,13 @@ (_ vector e* ...) ;; TODO the _ should be matching #%app (vector e* ...)) (length (syntax->list #'(e* ...)))] - [(make-vector n:nat e* ...) - (syntax-e #'n)] - [(build-vector n:nat f) - (syntax-e #'n)] - [_ #f])])) + [(~or (make-vector n e* ...) + (_ make-vector n e* ...) + (build-vector n e* ...) + (_ build-vector n e* ...)) + (if (syntax-transforming?) + (quoted-stx-value? (expand-expr #'n)) + (and (exact-nonnegative-integer? (syntax-e #'n)) (syntax-e #'n)))] + [_ + #f])]))