From cdae13498c3386d1bd8440891c7cbda43c26efe8 Mon Sep 17 00:00:00 2001 From: ben Date: Wed, 9 Mar 2016 03:14:45 -0500 Subject: [PATCH] [vector] works for no-colon, too --- private/common.rkt | 12 +- private/math.rkt | 50 ++++---- private/vector.rkt | 257 +++++++++++++++++++++++++++++++++++++ test/vector-pass.rkt | 102 ++++++++------- vector.rkt | 298 +++---------------------------------------- vector/no-colon.rkt | 19 +++ 6 files changed, 380 insertions(+), 358 deletions(-) create mode 100644 private/vector.rkt create mode 100644 vector/no-colon.rkt diff --git a/private/common.rkt b/private/common.rkt index a59c104..56d2b36 100644 --- a/private/common.rkt +++ b/private/common.rkt @@ -20,6 +20,7 @@ ;; TODO make-alias + make-keyword-alias ;; TODO ) @@ -125,9 +126,16 @@ (or (parser stx) (syntax-parse stx [_:id - #:with id-stx (format-id stx "~a" id-sym) + #:with id-stx (format-id id-sym "~a" (syntax-e id-sym)) (syntax/loc stx id-stx)] [(_ e* ...) - #:with id-stx (format-id stx "~a" id-sym) + #:with id-stx (format-id id-sym "~a" (syntax-e id-sym)) #:with app-stx (format-id stx "#%app") (syntax/loc stx (app-stx id-stx e* ...))]))) + +(define ((make-keyword-alias id-sym parser) stx) + (or (parser stx) + (syntax-parse stx + [(_ e* ...) + #:with id-stx (format-id stx "~a" id-sym) + (syntax/loc stx (id-stx e* ...))]))) diff --git a/private/math.rkt b/private/math.rkt index b76e10c..fa6eb36 100644 --- a/private/math.rkt +++ b/private/math.rkt @@ -3,8 +3,6 @@ ;; Constant-folding math operators. ;; Where possible, they simplify their arguments. -;; TODO the or- stuff is not so pretty, but it's working anyway - (provide +: -: *: /: ;; Same signature as the racket/base operators, @@ -16,6 +14,7 @@ ;; -- (for-syntax + stx->num nat/expand int/expand num/expand) @@ -36,6 +35,14 @@ (define (division-by-zero stx) (raise-syntax-error '/ "division by zero" stx)) + (define (stx->num stx) + (syntax-parse stx + [v:num/expand + (if (identifier? #'v.expanded) + (quoted-stx-value? #'v.evidence) + (quoted-stx-value? #'v.expanded))] + [_ #f])) + ;; Simplify a list of expressions using an associative binary operator. ;; Return either: ;; - A numeric value @@ -53,21 +60,18 @@ prev (reverse (if prev (cons prev acc) acc))) ;; else: pop the next argument from e*, fold if it's a constant - (syntax-parse (car e*) - [v:num/expand - (define v (or (quoted-stx-value? #'v.expanded) - (quoted-stx-value? #'v.evidence))) - ;; then: reduce the number - (if prev - ;; Watch for division-by-zero - (if (and (zero? v) (eq? / op)) - (division-by-zero stx) - (loop (op prev v) acc (cdr e*))) - (loop v acc (cdr e*)))] - [v - ;; else: save value in acc - (let ([acc+ (cons (car e*) (if prev (cons prev acc) acc))]) - (loop #f acc+ (cdr e*)))])))] + (let ([v (stx->num (car e*))]) + (if v + ;; then: reduce the number + (if prev + ;; Watch for division-by-zero + (if (and (zero? v) (eq? / op)) + (division-by-zero stx) + (loop (op prev v) acc (cdr e*))) + (loop v acc (cdr e*))) + ;; else: save value in acc + (let ([acc+ (cons (car e*) (if prev (cons prev acc) acc))]) + (loop #f acc+ (cdr e*)))))))] [else #f])) (define-values (nat-key nat? nat-define nat-let) @@ -85,8 +89,8 @@ ;; ----------------------------------------------------------------------------- -(define-syntax define-num: (make-alias 'define num-define)) -(define-syntax let-num: (make-alias 'let num-let)) +(define-syntax define-num: (make-keyword-alias 'define num-define)) +(define-syntax let-num: (make-keyword-alias 'let num-let)) (define-syntax make-numeric-operator (syntax-parser @@ -109,11 +113,9 @@ (define-syntax expt: (make-alias 'expt (lambda (stx) (syntax-parse stx - [(_ n1:num/expand n2:num/expand) - (let ([v1 (or (quoted-stx-value? #'n1.expanded) - (quoted-stx-value? #'n1.evidence))] - [v2 (or (quoted-stx-value? #'n2.expanded) - (quoted-stx-value? #'n2.evidence))]) + [(_ n1 n2) + (let ([v1 (stx->num #'n1)] + [v2 (stx->num #'n2)]) (and v1 v2 ;; Should never fail (quasisyntax/loc stx #,(expt v1 v2))))] [_ #f])))) diff --git a/private/vector.rkt b/private/vector.rkt new file mode 100644 index 0000000..9932856 --- /dev/null +++ b/private/vector.rkt @@ -0,0 +1,257 @@ +#lang typed/racket/base + +(provide + define-vector: + let-vector: + vector-length: + vector-ref: + vector-set!: + vector-map: + vector-map!: + vector-append: + vector->list: + vector->immutable-vector: + vector-fill!: + vector-take: + vector-take-right: + vector-drop: + vector-drop-right: +; vector-split-at: +; vector-split-at-right: + + ;; --- private + (for-syntax parse-vector-length) +) + +;; ----------------------------------------------------------------------------- + +(require + (only-in racket/unsafe/ops + unsafe-vector-set! + unsafe-vector-ref) + trivial/private/math + racket/vector + (for-syntax + trivial/private/common + typed/racket/base + syntax/parse)) + +;; ============================================================================= + +(begin-for-syntax + (define (small-vector-size? n) + (< n 20)) + + (define (vector-bounds-error sym v-stx i) + (raise-syntax-error + sym + "Index out-of-bounds" + (syntax->datum v-stx) + i + (list v-stx))) + + (define (parse-vector-length stx) + (syntax-parse stx #:literals (#%plain-app vector make-vector build-vector) + [(~or '#(e* ...) + #(e* ...) + ;; TODO #{} #[] #6{} ... + (#%plain-app vector e* ...) + (vector e* ...)) + (length (syntax-e #'(e* ...)))] + [(~or (make-vector n e* ...) + (#%plain-app make-vector n e* ...) + (build-vector n e* ...) + (#%plain-app build-vector n e* ...)) + #:with n-stx (stx->num #'n) + #:when (syntax-e #'n-stx) + (syntax-e #'n-stx)] + [_ #f])) + + (define-values (vector-length-key vec? vec-define vec-let) + (make-value-property 'vector:length parse-vector-length)) + (define-syntax-class/predicate vector/length vec?) +) + +;; ----------------------------------------------------------------------------- + +(define-syntax define-vector: (make-keyword-alias 'define vec-define)) +(define-syntax let-vector: (make-keyword-alias 'let vec-let)) + +(define-syntax vector-length: (make-alias #'vector-length + (lambda (stx) (syntax-parse stx + [(_ v:vector/length) + (syntax/loc stx 'v.evidence)] + [_ #f])))) + +(define-syntax vector-ref: (make-alias #'vector-ref + (lambda (stx) (syntax-parse stx + [(_ v:vector/length e) + #:with i-stx (stx->num #'e) + #:when (syntax-e #'i-stx) + (let ([i (syntax-e #'i-stx)]) + (unless (< i (syntax-e #'v.evidence)) + (vector-bounds-error 'vector-ref: #'v i)) + (syntax/loc stx (unsafe-vector-ref v.expanded 'i-stx)))] + [_ #f])))) + +(define-syntax vector-set!: (make-alias #'vector-set! + (lambda (stx) (syntax-parse stx + [(_ v:vector/length e val) + #:with i-stx (stx->num #'e) + #:when (syntax-e #'i-stx) + (let ([i (syntax-e #'i-stx)]) + (unless (< i (syntax-e #'v.evidence)) + (vector-bounds-error 'vector-set!: #'v i)) + (syntax/loc stx (unsafe-vector-set! v.expanded 'i-stx val)))] + [_ #f])))) + +(define-syntax vector-map: (make-alias #'vector-map + (lambda (stx) (syntax-parse stx + [(_ f v:vector/length) + #:with f+ (gensym 'f) + #:with v+ (gensym 'v) + #:with v++ (syntax-property + (if (small-vector-size? (syntax-e #'v.evidence)) + (with-syntax ([(i* ...) (for/list ([i (in-range (syntax-e #'v.evidence))]) i)]) + (syntax/loc stx + (let ([f+ f] [v+ v.expanded]) + (vector (f+ (unsafe-vector-ref v+ 'i*)) ...)))) + (syntax/loc stx + (let ([f+ f] [v+ v.expanded]) + (build-vector 'v.evidence (lambda ([i : Integer]) + (f+ (vector-ref: v+ i))))))) + vector-length-key + (syntax-e #'v.evidence)) + (syntax/loc stx v++)] + [_ #f])))) + +(define-syntax vector-map!: (make-alias #'vector-map! + (lambda (stx) (syntax-parse stx + [(_ f v:vector/length) + #:with f+ (gensym 'f) + #:with v+ (gensym 'v) + #:with v++ (syntax-property + #'(let ([f+ f] + [v+ v.expanded]) + (for ([i (in-range 'v.evidence)]) + (unsafe-vector-set! v+ i (f+ (unsafe-vector-ref v+ i)))) + v+) + vector-length-key + (syntax-e #'v.evidence)) + (syntax/loc stx v++)] + [_ #f])))) + +(define-syntax vector-append: (make-alias #'vector-append + (lambda (stx) (syntax-parse stx + [(_ v1:vector/length v2:vector/length) + #:with v1+ (gensym 'v1) + #:with v2+ (gensym 'v2) + (define l1 (syntax-e #'v1.evidence)) + (define l2 (syntax-e #'v2.evidence)) + (syntax-property + (if (and (small-vector-size? l1) + (small-vector-size? l2)) + (with-syntax ([(i1* ...) (for/list ([i (in-range l1)]) i)] + [(i2* ...) (for/list ([i (in-range l2)]) i)]) + (syntax/loc stx + (let ([v1+ v1.expanded] + [v2+ v2.expanded]) + (vector (vector-ref: v1+ i1*) ... + (vector-ref: v2+ i2*) ...)))) + (quasisyntax/loc stx + (let ([v1+ v1.expanded] + [v2+ v2.expanded]) + (build-vector + #,(+ l1 l2) + (lambda (i) + (if (< i '#,l1) + (unsafe-vector-ref v1+ i) + (unsafe-vector-ref v2+ i))))))) + vector-length-key + (+ l1 l2))] + [_ #f])))) + +(define-syntax vector->list: (make-alias #'vector->list + (lambda (stx) (syntax-parse stx + [(_ v:vector/length) + #:with v+ (gensym 'v) + (define len (syntax-e #'v.evidence)) + (if (small-vector-size? len) + (with-syntax ([(i* ...) (for/list ([i (in-range len)]) i)]) + (syntax/loc stx + (let ([v+ v.expanded]) + (list (unsafe-vector-ref v+ i*) ...)))) + (syntax/loc stx + (let ([v+ v.expanded]) + (build-list 'v.evidence (lambda (i) (unsafe-vector-ref v+ i))))))] + [_ #f])))) + +(define-syntax vector->immutable-vector: (make-alias #'vector->immutable-vector + (lambda (stx) (syntax-parse stx + [(_ v:vector/length) + (syntax-property + (syntax/loc stx (vector->immutable-vector v.expanded)) + vector-length-key + (syntax-e #'v.evidence))] + [_ #f])))) + +(define-syntax vector-fill!: (make-alias #'vector-fill! + (lambda (stx) (syntax-parse stx + [(_ v:vector/length val) + #:with v+ (gensym 'v) + (define len (syntax-e #'v.evidence)) + (syntax-property + (syntax/loc stx + (let ([v+ v.expanded]) + (for ([i (in-range 'v.evidence)]) + (unsafe-vector-set! v+ i val)))) + vector-length-key + (syntax-e #'v.evidence))] + [_ #f])))) + +(begin-for-syntax (define-syntax-rule (make-slice-op left? take?) + (lambda (stx) + (syntax-parse stx + [(op-name v:vector/length n) + #:with n-stx (stx->num #'n) + #:when (exact-nonnegative-integer? (syntax-e #'n-stx)) + #:with (lo hi) + (if 'take? + (if 'left? + (list 0 (syntax-e #'n-stx)) + (list + (- (syntax-e #'v.evidence) (syntax-e #'n-stx)) + (syntax-e #'v.evidence))) + (if 'left? + (list (syntax-e #'n-stx) (syntax-e #'v.evidence)) + (list 0 (- (syntax-e #'v.evidence) (syntax-e #'n-stx))))) + #:with n+ (gensym 'n) + #:with v+ (gensym 'v) + (unless (<= (syntax-e #'n-stx) (syntax-e #'v.evidence)) + (vector-bounds-error (syntax-e #'op-name) #'v + (if 'take? (if 'left? (syntax-e #'hi) (syntax-e #'lo)) + (if 'left? (syntax-e #'lo) (syntax-e #'hi))))) + (syntax-property + (syntax/loc stx + (let ([v+ v.expanded] + [n+ (-: 'hi 'lo)]) + (build-vector n+ (lambda ([i : Integer]) (unsafe-vector-ref v+ (+: i 'lo)))))) + vector-length-key + (syntax-e #'v.evidence))] + [(op-name v n:int/expand) + (vector-bounds-error (syntax-e #'op-name) #'v (stx->num #'n.expanded))] + [_ #f])))) + +(define-syntax vector-take: + (make-alias #'vector-take (make-slice-op #t #t))) + +(define-syntax vector-take-right: + (make-alias #'vector-take-right (make-slice-op #f #t))) + +(define-syntax vector-drop-right: + (make-alias #'vector-drop-right (make-slice-op #f #f))) + +(define-syntax vector-drop: + (make-alias #'vector-drop (make-slice-op #t #f))) + + diff --git a/test/vector-pass.rkt b/test/vector-pass.rkt index f511e4f..8b5868c 100644 --- a/test/vector-pass.rkt +++ b/test/vector-pass.rkt @@ -6,58 +6,6 @@ trivial/vector typed/rackunit) - (require/typed (for-template trivial/vector) - (parse-vector-length (-> Syntax (Option Natural)))) - - ;; -- parse-vector-length - ;; --- '# - (check-equal? - (parse-vector-length #'#()) - 0) -; (check-equal? -; (parse-vector-length #`#,'#(1 2)) -; 2) - (check-equal? - (parse-vector-length #'#(1 2 3 4)) - 4) - (check-equal? - (parse-vector-length #'#(a b c e s aue d al)) - 8) - ;; --- vector - (check-equal? - (parse-vector-length #'(vector)) - 0) - (check-equal? - (parse-vector-length #'(vector 0 1)) - 2) - ;; --- make-vector - (check-equal? - (parse-vector-length #'(make-vector -1 1)) - #f) - (check-equal? - (parse-vector-length #'(make-vector 0 8)) - 0) - (check-equal? - (parse-vector-length #'(make-vector 3 3)) - 3) - (check-equal? - (parse-vector-length #'(make-vector 99)) - 99) - ;; --- build-vector - (check-equal? - ;; Type error - (parse-vector-length #'(build-vector -1)) - #f) - (check-equal? - (parse-vector-length #'(build-vector 0 (lambda (x) x))) - 0) - (check-equal? - (parse-vector-length #'(build-vector 3 (lambda (x) 8))) - 3) - (check-equal? - (parse-vector-length #'(build-vector 61 add1)) - 61) - ;; -- vector-length: (check-equal? (vector-length: '#()) 0) @@ -304,3 +252,53 @@ (check-equal? (vector-ref: v 0) 1)) ;; -- let-vector: ) + +;; ----------------------------------------------------------------------------- +; ;; -- parse-vector-length +; ;; --- '# +; (check-equal? +; (parse-vector-length #'#()) +; 0) +;; (check-equal? +;; (parse-vector-length #`#,'#(1 2)) +;; 2) +; (check-equal? +; (parse-vector-length #'#(1 2 3 4)) +; 4) +; (check-equal? +; (parse-vector-length #'#(a b c e s aue d al)) +; 8) +; ;; --- vector +; (check-equal? +; (parse-vector-length #'(vector)) +; 0) +; (check-equal? +; (parse-vector-length #'(vector 0 1)) +; 2) +; ;; --- make-vector +; (check-equal? +; (parse-vector-length #'(make-vector -1 1)) +; #f) +; (check-equal? +; (parse-vector-length #'(make-vector 0 8)) +; 0) +; (check-equal? +; (parse-vector-length #'(make-vector 3 3)) +; 3) +; (check-equal? +; (parse-vector-length #'(make-vector 99)) +; 99) +; ;; --- build-vector +; (check-equal? +; ;; Type error +; (parse-vector-length #'(build-vector -1)) +; #f) +; (check-equal? +; (parse-vector-length #'(build-vector 0 (lambda (x) x))) +; 0) +; (check-equal? +; (parse-vector-length #'(build-vector 3 (lambda (x) 8))) +; 3) +; (check-equal? +; (parse-vector-length #'(build-vector 61 add1)) +; 61) diff --git a/vector.rkt b/vector.rkt index 0122a12..286d6d5 100644 --- a/vector.rkt +++ b/vector.rkt @@ -1,8 +1,8 @@ #lang typed/racket/base -;; TOOD abstract some designs - (provide + (all-from-out racket/vector) + define-vector: let-vector: vector-length: @@ -20,288 +20,26 @@ vector-drop-right: ; vector-split-at: ; vector-split-at-right: - - ;; --- private - (for-syntax parse-vector-length) ) ;; ----------------------------------------------------------------------------- (require - (only-in racket/unsafe/ops - unsafe-vector-set! - unsafe-vector-ref) racket/vector - trivial/math - (for-syntax - typed/racket/base - racket/syntax - syntax/id-table - syntax/parse - syntax/stx - trivial/private/common - )) - -;; ============================================================================= - -(define-for-syntax vector-length-key 'vector:length) -(define-for-syntax id+vector-length (make-free-id-table)) - -(begin-for-syntax (define-syntax-class vector/length - #:attributes (expanded length) - (pattern e - #:with e+ (expand-expr #'e) - #:with len (parse-vector-length #'e+) - #:when (syntax-e #'len) - #:attr expanded #'e+ - #:attr length #'len) + (only-in trivial/private/vector + define-vector: + let-vector: + vector-length: + vector-ref: + vector-set!: + vector-map: + vector-map!: + vector-append: + vector->list: + vector->immutable-vector: + vector-fill!: + vector-take: + vector-take-right: + vector-drop: + vector-drop-right: )) - -(define-syntax (define-vector: stx) - (syntax-parse stx - [(_ name:id v:vector/length) - (free-id-table-set! id+vector-length #'name (syntax-e #'v.length)) - #'(define name v.expanded)] - [(_ e* ...) - #'(define e* ...)])) - -(define-syntax (let-vector: stx) - (syntax-parse stx - [(_ ([name*:id v*:vector/length] ...) e* ...) - #'(let ([name* v*.expanded] ...) - (let-syntax ([name* (make-rename-transformer - (syntax-property #'name* - vector-length-key - 'v*.length))] ...) - e* ...))] - [(_ e* ...) - #'(let e* ...)])) - -(define-for-syntax (vector-bounds-error sym v-stx i) - (raise-syntax-error - sym - "Index out-of-bounds" - (syntax->datum v-stx) - i - (list v-stx))) - -(define-syntax (vector-length: stx) - (syntax-parse stx - [(_ v:vector/length) - (syntax/loc stx 'v.length)] - [_:id - (syntax/loc stx vector-length)] - [(_ e* ...) - (syntax/loc stx (vector-length e* ...))])) - -(define-syntax (vector-ref: stx) - (syntax-parse stx - [(_ v:vector/length i:nat/expand) - (unless (< (syntax-e #'i.expanded) (syntax-e #'v.length)) - (vector-bounds-error 'vector-ref: #'v (syntax-e #'i.expanded))) - (syntax/loc stx (unsafe-vector-ref v.expanded 'i.expanded))] - [_: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/expand val) - (unless (< (syntax-e #'i.expanded) (syntax-e #'v.length)) - (vector-bounds-error 'vector-set!: #'v (syntax-e #'i.expanded))) - (syntax/loc stx (unsafe-vector-set! v.expanded 'i.expanded val))] - [_:id - (syntax/loc stx vector-set!)] - [(_ e* ...) - (syntax/loc stx (vector-set! e* ...))])) - -(define-syntax (vector-map: stx) - (syntax-parse stx - [(_ f v:vector/length) - #:with f+ (gensym 'f) - #:with v+ (gensym 'v) - #:with v++ (syntax-property - (if (small-vector-size? (syntax-e #'v.length)) - (with-syntax ([(i* ...) (for/list ([i (in-range (syntax-e #'v.length))]) i)]) - (syntax/loc stx - (let ([f+ f] [v+ v.expanded]) - (vector (f+ (unsafe-vector-ref v+ 'i*)) ...)))) - (syntax/loc stx - (let ([f+ f] [v+ v.expanded]) - (build-vector 'v.length (lambda ([i : Integer]) - (f+ (vector-ref: v+ 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-syntax (vector-map!: stx) - (syntax-parse stx - [(_ f v:vector/length) - #:with f+ (gensym 'f) - #:with v+ (gensym 'v) - #:with v++ (syntax-property - #'(let ([f+ f] - [v+ v.expanded]) - (for ([i (in-range 'v.length)]) - (unsafe-vector-set! v+ i (f+ (unsafe-vector-ref v+ i)))) - v+) - 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-syntax (vector-append: stx) - (syntax-parse stx - [(_ v1:vector/length v2:vector/length) - #:with v1+ (gensym 'v1) - #:with v2+ (gensym 'v2) - (define l1 (syntax-e #'v1.length)) - (define l2 (syntax-e #'v2.length)) - (syntax-property - (if (and (small-vector-size? l1) - (small-vector-size? l2)) - (with-syntax ([(i1* ...) (for/list ([i (in-range l1)]) i)] - [(i2* ...) (for/list ([i (in-range l2)]) i)]) - (syntax/loc stx - (let ([v1+ v1.expanded] - [v2+ v2.expanded]) - (vector (vector-ref: v1+ i1*) ... - (vector-ref: v2+ i2*) ...)))) - (quasisyntax/loc stx - (let ([v1+ v1.expanded] - [v2+ v2.expanded]) - (build-vector - #,(+ l1 l2) - (lambda (i) - (if (< i '#,l1) - (unsafe-vector-ref v1+ i) - (unsafe-vector-ref v2+ i))))))) - vector-length-key - (+ l1 l2))] - [_:id - (syntax/loc stx vector-append)] - [(_ e* ...) - (syntax/loc stx (vector-append e* ...))])) - -(define-syntax (vector->list: stx) - (syntax-parse stx - [(_ v:vector/length) - #:with v+ (gensym 'v) - (define len (syntax-e #'v.length)) - (if (small-vector-size? len) - (with-syntax ([(i* ...) (for/list ([i (in-range len)]) i)]) - (syntax/loc stx - (let ([v+ v.expanded]) - (list (unsafe-vector-ref v+ i*) ...)))) - (syntax/loc stx - (let ([v+ v.expanded]) - (build-list 'v.length (lambda (i) (unsafe-vector-ref v+ i))))))] - [_:id - (syntax/loc stx vector->list)] - [(_ e* ...) - (syntax/loc stx (vector->list e* ...))])) - -(define-syntax (vector->immutable-vector: stx) - (syntax-parse stx - [(_ v:vector/length) - (syntax-property - (syntax/loc stx (vector->immutable-vector v.expanded)) - vector-length-key - (syntax-e #'v.length))] - [_:id - (syntax/loc stx vector->immutable-vector)] - [(_ e* ...) - (syntax/loc stx (vector->immutable-vector e* ...))])) - -(define-syntax (vector-fill!: stx) - (syntax-parse stx - [(_ v:vector/length val) - #:with v+ (gensym 'v) - (define len (syntax-e #'v.length)) - (syntax-property - (syntax/loc stx - (let ([v+ v.expanded]) - (for ([i (in-range 'v.length)]) - (unsafe-vector-set! v+ i val)))) - vector-length-key - (syntax-e #'v.length))] - [_:id - (syntax/loc stx vector->fill!)] - [(_ e* ...) - (syntax/loc stx (vector->fill! e* ...))])) - -(begin-for-syntax (define-syntax-rule (make-slice-op op-name left? take?) - (lambda (stx) - (syntax-parse stx - [(_ v:vector/length n:nat/expand) - #:with (lo hi) - (if 'take? - (if 'left? - (list 0 (syntax-e #'n.expanded)) - (list - (- (syntax-e #'v.length) (syntax-e #'n.expanded)) - (syntax-e #'v.length))) - (if 'left? - (list (syntax-e #'n.expanded) (syntax-e #'v.length)) - (list 0 (- (syntax-e #'v.length) (syntax-e #'n.expanded))))) - #:with n+ (gensym 'n) - #:with v+ (gensym 'v) - (unless (<= (syntax-e #'n.expanded) (syntax-e #'v.length)) - (vector-bounds-error 'op-name #'v - (if 'take? (if 'left? (syntax-e #'hi) (syntax-e #'lo)) - (if 'left? (syntax-e #'lo) (syntax-e #'hi))))) - (syntax-property - (syntax/loc stx - (let ([v+ v.expanded] - [n+ (-: 'hi 'lo)]) - (build-vector n+ (lambda ([i : Integer]) (unsafe-vector-ref v+ (+: i 'lo)))))) - vector-length-key - (syntax-e #'v.length))] - [(_ v n:int/expand) - (vector-bounds-error 'op-name #'v (syntax-e #'n.expanded))] - [_:id - (syntax/loc stx op-name)] - [(_ e* (... ...)) - (syntax/loc stx (op-name e* (... ...)))])))) - -(define-syntax vector-take: (make-slice-op vector-take #t #t)) -(define-syntax vector-take-right: (make-slice-op vector-take-right #f #t)) -(define-syntax vector-drop-right: (make-slice-op vector-drop-right #f #f)) -(define-syntax vector-drop: (make-slice-op vector-drop #t #f)) - -;; ----------------------------------------------------------------------------- - -(define-for-syntax (small-vector-size? n) - (< n 20)) - -;; Assume `stx` is creating a vector; get the length of the vector to-be-made -(define-for-syntax (parse-vector-length stx) - (cond - [(syntax-property stx vector-length-key) - => (lambda (x) x)] - [(identifier? stx) - (free-id-table-ref id+vector-length stx #f)] - [else - (syntax-parse stx #:literals (#%plain-app vector make-vector build-vector) - [(~or '#(e* ...) - #(e* ...) - ;; TODO #{} #[] #6{} ... - (#%plain-app vector e* ...) - (vector e* ...)) - (length (syntax->list #'(e* ...)))] - [(~or (make-vector n e* ...) - (#%plain-app make-vector n e* ...) - (build-vector n e* ...) - (#%plain-app build-vector n e* ...)) - (and (exact-nonnegative-integer? (syntax-e #'n)) (syntax-e #'n))] - [_ - #f])])) - diff --git a/vector/no-colon.rkt b/vector/no-colon.rkt new file mode 100644 index 0000000..1911069 --- /dev/null +++ b/vector/no-colon.rkt @@ -0,0 +1,19 @@ +#lang typed/racket/base +(provide (rename-out + (define-vector: define-vector) + (let-vector: let-vector) + (vector-length: vector-length) + (vector-ref: vector-ref) + (vector-set!: vector-set!) + (vector-map: vector-map) + (vector-map!: vector-map!) + (vector-append: vector-append) + (vector->list: vector->list) + (vector->immutable-vector: vector->immutable-vector) + (vector-fill!: vector-fill!) + (vector-take: vector-take) + (vector-take-right: vector-take-right) + (vector-drop: vector-drop) + (vector-drop-right: vector-drop-right) +)) +(require trivial/vector)