From 3dd29044de8d8b33d52029094afc5fdb13a79290 Mon Sep 17 00:00:00 2001 From: ben Date: Wed, 2 Mar 2016 13:21:00 -0500 Subject: [PATCH] [vector] vector-set --- test/vector-fail.rkt | 6 ++++ test/vector-pass.rkt | 68 ++++++++++++++++++++++++++++++++------------ vector.rkt | 18 ++++++++++-- 3 files changed, 71 insertions(+), 21 deletions(-) diff --git a/test/vector-fail.rkt b/test/vector-fail.rkt index 8e2fbc7..474fc08 100644 --- a/test/vector-fail.rkt +++ b/test/vector-fail.rkt @@ -15,6 +15,12 @@ (define-vector: v (vector 3 4)) (vector-ref: v 9)) + (let-vector: ([v1 (vector 1)]) + (let-vector: ([v2 (vector v1)]) + (vector-ref: (vector-ref: v2 0) 1))) + + (vector-set!: (vector 0) 0 "hello") ;; Strong update + ))) ;; ----------------------------------------------------------------------------- diff --git a/test/vector-pass.rkt b/test/vector-pass.rkt index c4168fe..c22b1ef 100644 --- a/test/vector-pass.rkt +++ b/test/vector-pass.rkt @@ -81,28 +81,60 @@ Zero) 0)) - ;; -- vector-ref - (test-case "vector/length ref" - (check-equal? (vector-ref: (vector 1) 0) 1)) + ;(test-suite "vector-ref:" + (test-case "vector/length ref" + (check-equal? (vector-ref: (vector 1) 0) 1)) - (test-case "vector/length ref, via let" - (let-vector: ([v (vector 2)]) - (check-equal? (vector-ref: v 0) 2))) + (test-case "vector/length ref, via let" + (let-vector: ([v (vector 2)]) + (check-equal? (vector-ref: v 0) 2))) - (test-case "vector/length ref, via define" - (define-vector: v (vector "a" "bee" "sea")) - (check-equal? (vector-ref: v 2) "sea")) + (test-case "vector/length ref, via define" + (define-vector: v (vector "a" "bee" "sea")) + (check-equal? (vector-ref: v 2) "sea")) - (test-case "plain vector ref" - (check-equal? - ((lambda (v) (vector-ref: v 3)) (vector 8 2 19 3 0)) - 3)) + (test-case "plain vector ref" + (check-equal? + ((lambda (v) (vector-ref: v 3)) (vector 8 2 19 3 0)) + 3)) - (test-case "higher-order vector ref" - (check-exn exn:fail:contract? - (lambda () - ((lambda ([f : (-> (Vectorof Any) Natural Any)]) - (f (vector 0 1 2) 10)) vector-ref:)))) + (test-case "higher-order vector ref" + (check-exn exn:fail:contract? + (lambda () + ((lambda ([f : (-> (Vectorof Any) Natural Any)]) + (f (vector 0 1 2) 10)) vector-ref:)))) + + (test-case "2-level ref" + (let-vector: ([v1 (vector 'X)]) + (let-vector: ([v2 (vector v1)]) + (check-equal? (vector-ref: (vector-ref: v2 0) 0) 'X)))) + ;) + + ;(test-suite "vector-set!:" + (test-case "vector/length set!" + (check-equal? (vector-set!: (vector 1) 0 8) (void))) + + (test-case "vector/length set!, via let" + (let-vector: ([v (vector 2)]) + (vector-set! v 0 3) + (check-equal? (vector-ref: v 0) 3))) + + (test-case "vector/length set, via define" + (define-vector: v (vector "a" "bee" "sea")) + (vector-set! v 1 "bye") + (check-equal? (vector-ref: v 1) "bye")) + + (test-case "plain vector set" + (check-equal? + ((lambda (v) (vector-set!: v 3 4) (vector-ref: v 3)) (vector 8 2 19 3 0)) + 4)) + + (test-case "higher-order vector set" + (check-exn exn:fail:contract? + (lambda () + ((lambda ([f : (-> (Vectorof Any) Natural Any Void)]) + (f (vector 0 1 2) 10 9)) vector-set!:)))) + ;) ;; -- define-vector: (let () diff --git a/vector.rkt b/vector.rkt index fdc3c38..f79b138 100644 --- a/vector.rkt +++ b/vector.rkt @@ -7,7 +7,7 @@ let-vector: vector-length: vector-ref: - ;vector-set!: + vector-set!: ;vector-map: ;vector-append: ;vector->list @@ -22,6 +22,7 @@ (require (only-in racket/unsafe/ops + unsafe-vector-set! unsafe-vector-ref) (for-syntax typed/racket/base @@ -67,7 +68,7 @@ [(_ e* ...) #'(let e* ...)])) -(define-for-syntax (vector-ref-error v i) +(define-for-syntax (vector-bounds-error v i) (raise-argument-error errloc-key (format "Index out-of-bounds: ~a" i) @@ -86,13 +87,24 @@ (syntax-parse stx [(_ v:vector/length i:nat) (unless (< (syntax-e #'i) (syntax-e #'v.length)) - (vector-ref-error (syntax-e #'v) (syntax-e #'i))) + (vector-bounds-error (syntax-e #'v) (syntax-e #'i))) (syntax/loc stx (unsafe-vector-ref v.expanded i))] [_:id (syntax/loc stx vector-ref)] [(_ e* ...) (syntax/loc stx (vector-ref e* ...))])) +(define-syntax (vector-set!: stx) + (syntax-parse stx + [(_ v:vector/length i:nat val) + (unless (< (syntax-e #'i) (syntax-e #'v.length)) + (vector-bounds-error (syntax-e #'v) (syntax-e #'i))) + (syntax/loc stx (unsafe-vector-set! v.expanded i val))] + [_:id + (syntax/loc stx vector-set!)] + [(_ e* ...) + (syntax/loc stx (vector-set! e* ...))])) + ;; ----------------------------------------------------------------------------- ;; Assume `stx` is creating a vector; get the length of the vector to-be-made