[list] implemented some functions, need tests
This commit is contained in:
parent
d2dd015415
commit
316ab9cf32
|
@ -14,6 +14,9 @@
|
||||||
(only-in trivial/private/format
|
(only-in trivial/private/format
|
||||||
format-define
|
format-define
|
||||||
format-let)
|
format-let)
|
||||||
|
(only-in trivial/private/list
|
||||||
|
lst-define
|
||||||
|
lst-let)
|
||||||
(only-in trivial/private/math
|
(only-in trivial/private/math
|
||||||
num-define
|
num-define
|
||||||
num-let)
|
num-let)
|
||||||
|
@ -31,6 +34,7 @@
|
||||||
(lambda (stx)
|
(lambda (stx)
|
||||||
(or (format-define stx)
|
(or (format-define stx)
|
||||||
(num-define stx)
|
(num-define stx)
|
||||||
|
(lst-define stx)
|
||||||
(rx-define stx)
|
(rx-define stx)
|
||||||
(fun-define stx)
|
(fun-define stx)
|
||||||
(vec-define stx)))))
|
(vec-define stx)))))
|
||||||
|
@ -40,5 +44,6 @@
|
||||||
(or (format-let stx)
|
(or (format-let stx)
|
||||||
(fun-let stx)
|
(fun-let stx)
|
||||||
(num-let stx)
|
(num-let stx)
|
||||||
|
(lst-let stx)
|
||||||
(rx-let stx)
|
(rx-let stx)
|
||||||
(vec-let stx)))))
|
(vec-let stx)))))
|
||||||
|
|
43
trivial/list.rkt
Normal file
43
trivial/list.rkt
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#lang typed/racket/base
|
||||||
|
|
||||||
|
(provide
|
||||||
|
set!
|
||||||
|
(all-from-out racket/list)
|
||||||
|
|
||||||
|
define-list:
|
||||||
|
let-list:
|
||||||
|
pair?:
|
||||||
|
null?:
|
||||||
|
cons:
|
||||||
|
car:
|
||||||
|
cdr:
|
||||||
|
list?:
|
||||||
|
length:
|
||||||
|
list-ref:
|
||||||
|
list-tail:
|
||||||
|
append:
|
||||||
|
reverse:
|
||||||
|
map:
|
||||||
|
)
|
||||||
|
|
||||||
|
;; -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(require
|
||||||
|
racket/list
|
||||||
|
trivial/private/set-bang
|
||||||
|
(only-in trivial/private/list
|
||||||
|
define-list:
|
||||||
|
let-list:
|
||||||
|
pair?:
|
||||||
|
null?:
|
||||||
|
cons:
|
||||||
|
car:
|
||||||
|
cdr:
|
||||||
|
list?:
|
||||||
|
length:
|
||||||
|
list-ref:
|
||||||
|
list-tail:
|
||||||
|
append:
|
||||||
|
reverse:
|
||||||
|
map:
|
||||||
|
))
|
19
trivial/list/no-colon.rkt
Normal file
19
trivial/list/no-colon.rkt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#lang typed/racket/base
|
||||||
|
(provide (rename-out
|
||||||
|
(define-list: define-list)
|
||||||
|
(let-list: let-list)
|
||||||
|
(pair?: pair?)
|
||||||
|
(null?: null?)
|
||||||
|
(cons: cons)
|
||||||
|
(car: car)
|
||||||
|
(cdr: cdr)
|
||||||
|
(list?: list?)
|
||||||
|
(length: length)
|
||||||
|
(list-ref: list-ref)
|
||||||
|
(list-tail: list-tail)
|
||||||
|
(append: append)
|
||||||
|
(reverse: reverse)
|
||||||
|
(map: map)
|
||||||
|
))
|
||||||
|
(require trivial/list)
|
||||||
|
|
198
trivial/private/list.rkt
Normal file
198
trivial/private/list.rkt
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
#lang typed/racket/base
|
||||||
|
|
||||||
|
(provide
|
||||||
|
define-list:
|
||||||
|
let-list:
|
||||||
|
pair?:
|
||||||
|
null?:
|
||||||
|
cons:
|
||||||
|
car:
|
||||||
|
cdr:
|
||||||
|
list?:
|
||||||
|
length:
|
||||||
|
list-ref:
|
||||||
|
list-tail:
|
||||||
|
append:
|
||||||
|
reverse:
|
||||||
|
map:
|
||||||
|
;andmap:
|
||||||
|
;ormap:
|
||||||
|
;for-each:
|
||||||
|
;foldl:
|
||||||
|
;foldr:
|
||||||
|
;filter:
|
||||||
|
;remove:
|
||||||
|
;remq:
|
||||||
|
;remv:
|
||||||
|
;remove*:
|
||||||
|
;remq*:
|
||||||
|
;remv*:
|
||||||
|
;sort:
|
||||||
|
;member:
|
||||||
|
|
||||||
|
;; --- private
|
||||||
|
(for-syntax
|
||||||
|
lst-define
|
||||||
|
lst-let
|
||||||
|
parse-list-length
|
||||||
|
lst-length-key ;; TODO generic "data structure length" key?
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
;; -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(require
|
||||||
|
trivial/private/math
|
||||||
|
typed/racket/unsafe
|
||||||
|
racket/list
|
||||||
|
(for-syntax
|
||||||
|
trivial/private/common
|
||||||
|
trivial/private/sequence
|
||||||
|
typed/racket/base
|
||||||
|
syntax/parse))
|
||||||
|
|
||||||
|
(unsafe-require/typed racket/unsafe/ops
|
||||||
|
(unsafe-car (All (A) (-> (Listof A) A)))
|
||||||
|
(unsafe-cdr (All (A) (-> (Listof A) (Listof A))))
|
||||||
|
(unsafe-cons-list (All (A) (-> A (Listof A) (Listof A))))
|
||||||
|
(unsafe-list-ref (All (A) (-> (Listof A) Integer A)))
|
||||||
|
(unsafe-list-tail (All (A) (-> (Listof A) Integer (Listof A)))))
|
||||||
|
|
||||||
|
;; =============================================================================
|
||||||
|
|
||||||
|
(begin-for-syntax
|
||||||
|
(define (parse-list-length stx)
|
||||||
|
(syntax-parse stx #:literals (#%plain-app cons list list* make-list build-list null)
|
||||||
|
[(~or '(e* ...)
|
||||||
|
(list e* ...)
|
||||||
|
(#%plain-app list e* ...))
|
||||||
|
(length (syntax-e #'(e* ...)))]
|
||||||
|
[(~or (make-list n e* ...)
|
||||||
|
(#%plain-app make-list n e* ...)
|
||||||
|
(build-list n e* ...)
|
||||||
|
(#%plain-app build-list n e* ...))
|
||||||
|
#:with n-stx (stx->num #'n)
|
||||||
|
#:when (syntax-e #'n-stx)
|
||||||
|
(syntax-e #'n-stx)]
|
||||||
|
[(~or (cons e es)
|
||||||
|
(#%plain-app cons e es))
|
||||||
|
#:with n+ (parse-list-length #'es)
|
||||||
|
#:when (syntax-e #'n+)
|
||||||
|
(+ 1 (syntax-e #'n+))]
|
||||||
|
[(~or (list* e* ... es)
|
||||||
|
(#%plain-app list* e* ... es))
|
||||||
|
#:with n+ (parse-list-length #'es)
|
||||||
|
#:when (syntax-e #'n+)
|
||||||
|
(+ (length (syntax-e #'(e* ...))) (syntax-e #'n+))]
|
||||||
|
[(~or (null)
|
||||||
|
(#%plain-app null))
|
||||||
|
0]
|
||||||
|
[+ #f]))
|
||||||
|
|
||||||
|
(define-values (lst-length-key lst? lst-define lst-let)
|
||||||
|
(make-value-property 'list:length parse-list-length))
|
||||||
|
(define-syntax-class/predicate list/length lst?)
|
||||||
|
)
|
||||||
|
|
||||||
|
;; -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(define-syntax define-list: (make-keyword-alias 'define lst-define))
|
||||||
|
(define-syntax let-list: (make-keyword-alias 'let lst-let))
|
||||||
|
|
||||||
|
(define-syntax pair?: (make-alias #'pair?
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l:list/length)
|
||||||
|
(quasisyntax/loc stx '#,(not (zero? (syntax-e #'l.evidence))))]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax null?: (make-alias #'null?
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l:list/length)
|
||||||
|
(quasisyntax/loc stx '#,(zero? (syntax-e #'l.evidence)))]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax cons: (make-alias #'cons
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ x l:list/length)
|
||||||
|
#:with l+ (syntax-property
|
||||||
|
(syntax/loc stx (unsafe-cons-list x l.expanded))
|
||||||
|
lst-length-key (+ 1 (syntax-e #'l.evidence)))
|
||||||
|
(syntax/loc stx l+)]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax car: (make-alias #'car
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l:list/length)
|
||||||
|
(when (zero? (syntax-e #'l.evidence))
|
||||||
|
(bounds-error 'car: #'l 0))
|
||||||
|
(syntax/loc stx (unsafe-car l.expanded))]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax cdr: (make-alias #'cdr
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l:list/length)
|
||||||
|
(when (zero? (syntax-e #'l.evidence))
|
||||||
|
(bounds-error 'cdr: #'l 0))
|
||||||
|
(syntax/loc stx (unsafe-cdr l.expanded))]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax list?: (make-alias #'list?
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l:list/length)
|
||||||
|
(syntax/loc stx '#t)]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax length: (make-alias #'length
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l:list/length)
|
||||||
|
(syntax/loc stx 'l.evidence)]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax list-ref: (make-alias #'list-ref
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l:list/length e)
|
||||||
|
#:with i-stx (stx->num #'e)
|
||||||
|
#:when (syntax-e #'i-stx)
|
||||||
|
(let ([i (syntax-e #'i-stx)])
|
||||||
|
(unless (< i (syntax-e #'l.evidence))
|
||||||
|
(bounds-error 'list-ref: #'l i))
|
||||||
|
(syntax/loc stx (unsafe-list-ref l.expanded 'i-stx)))]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax list-tail: (make-alias #'list-tail
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l:list/length e)
|
||||||
|
#:with i-stx (stx->num #'e)
|
||||||
|
#:when (syntax-e #'i-stx)
|
||||||
|
(let ([i (syntax-e #'i-stx)])
|
||||||
|
(unless (< i (syntax-e #'l.evidence))
|
||||||
|
(bounds-error 'list-tail: #'l i))
|
||||||
|
(syntax/loc stx (unsafe-list-tail l.expanded 'i-stx)))]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax append: (make-alias #'append
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l1:list/length l2:list/length)
|
||||||
|
#:with l+ (syntax-property (syntax/loc stx (append l1.expanded l2.expanded))
|
||||||
|
lst-length-key (+ (syntax-e #'l1.evidence) (syntax-e #'l2.evidence)))
|
||||||
|
(quasisyntax/loc stx l+)]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax reverse: (make-alias #'reverse
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ l:list/length)
|
||||||
|
#:with l+ (syntax-property (syntax/loc stx (reverse l.expanded))
|
||||||
|
lst-length-key (syntax-e #'l.evidence))
|
||||||
|
(quasisyntax/loc stx l+)]
|
||||||
|
[_ #f]))))
|
||||||
|
|
||||||
|
(define-syntax map: (make-alias #'map
|
||||||
|
(lambda (stx) (syntax-parse stx
|
||||||
|
[(_ f l:list/length l*:list/length ...)
|
||||||
|
#:with l+ (syntax-property
|
||||||
|
(syntax/loc stx (map f l.expanded l*.expanded ...))
|
||||||
|
lst-length-key
|
||||||
|
(syntax-e #'l.evidence))
|
||||||
|
(syntax/loc stx l+)]
|
||||||
|
[_ #f]))))
|
||||||
|
|
20
trivial/private/sequence.rkt
Normal file
20
trivial/private/sequence.rkt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(provide
|
||||||
|
small-sequence-size?
|
||||||
|
bounds-error
|
||||||
|
)
|
||||||
|
|
||||||
|
;; =============================================================================
|
||||||
|
|
||||||
|
(define (small-sequence-size? n)
|
||||||
|
(< n 20))
|
||||||
|
|
||||||
|
(define (bounds-error sym v-stx i)
|
||||||
|
(raise-syntax-error
|
||||||
|
sym
|
||||||
|
"Index out-of-bounds"
|
||||||
|
(syntax->datum v-stx)
|
||||||
|
i
|
||||||
|
(list v-stx)))
|
||||||
|
|
|
@ -37,23 +37,13 @@
|
||||||
racket/vector
|
racket/vector
|
||||||
(for-syntax
|
(for-syntax
|
||||||
trivial/private/common
|
trivial/private/common
|
||||||
|
trivial/private/sequence
|
||||||
typed/racket/base
|
typed/racket/base
|
||||||
syntax/parse))
|
syntax/parse))
|
||||||
|
|
||||||
;; =============================================================================
|
;; =============================================================================
|
||||||
|
|
||||||
(begin-for-syntax
|
(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)
|
(define (parse-vector-length stx)
|
||||||
(syntax-parse stx #:literals (#%plain-app vector make-vector build-vector)
|
(syntax-parse stx #:literals (#%plain-app vector make-vector build-vector)
|
||||||
[(~or '#(e* ...)
|
[(~or '#(e* ...)
|
||||||
|
@ -95,7 +85,7 @@
|
||||||
#:when (syntax-e #'i-stx)
|
#:when (syntax-e #'i-stx)
|
||||||
(let ([i (syntax-e #'i-stx)])
|
(let ([i (syntax-e #'i-stx)])
|
||||||
(unless (< i (syntax-e #'v.evidence))
|
(unless (< i (syntax-e #'v.evidence))
|
||||||
(vector-bounds-error 'vector-ref: #'v i))
|
(bounds-error 'vector-ref: #'v i))
|
||||||
(syntax/loc stx (unsafe-vector-ref v.expanded 'i-stx)))]
|
(syntax/loc stx (unsafe-vector-ref v.expanded 'i-stx)))]
|
||||||
[_ #f]))))
|
[_ #f]))))
|
||||||
|
|
||||||
|
@ -106,7 +96,7 @@
|
||||||
#:when (syntax-e #'i-stx)
|
#:when (syntax-e #'i-stx)
|
||||||
(let ([i (syntax-e #'i-stx)])
|
(let ([i (syntax-e #'i-stx)])
|
||||||
(unless (< i (syntax-e #'v.evidence))
|
(unless (< i (syntax-e #'v.evidence))
|
||||||
(vector-bounds-error 'vector-set!: #'v i))
|
(bounds-error 'vector-set!: #'v i))
|
||||||
(syntax/loc stx (unsafe-vector-set! v.expanded 'i-stx val)))]
|
(syntax/loc stx (unsafe-vector-set! v.expanded 'i-stx val)))]
|
||||||
[_ #f]))))
|
[_ #f]))))
|
||||||
|
|
||||||
|
@ -116,7 +106,7 @@
|
||||||
#:with f+ (gensym 'f)
|
#:with f+ (gensym 'f)
|
||||||
#:with v+ (gensym 'v)
|
#:with v+ (gensym 'v)
|
||||||
#:with v++ (syntax-property
|
#:with v++ (syntax-property
|
||||||
(if (small-vector-size? (syntax-e #'v.evidence))
|
(if (small-sequence-size? (syntax-e #'v.evidence))
|
||||||
(with-syntax ([(i* ...) (for/list ([i (in-range (syntax-e #'v.evidence))]) i)])
|
(with-syntax ([(i* ...) (for/list ([i (in-range (syntax-e #'v.evidence))]) i)])
|
||||||
(syntax/loc stx
|
(syntax/loc stx
|
||||||
(let ([f+ f] [v+ v.expanded])
|
(let ([f+ f] [v+ v.expanded])
|
||||||
|
@ -154,8 +144,8 @@
|
||||||
(define l1 (syntax-e #'v1.evidence))
|
(define l1 (syntax-e #'v1.evidence))
|
||||||
(define l2 (syntax-e #'v2.evidence))
|
(define l2 (syntax-e #'v2.evidence))
|
||||||
(syntax-property
|
(syntax-property
|
||||||
(if (and (small-vector-size? l1)
|
(if (and (small-sequence-size? l1)
|
||||||
(small-vector-size? l2))
|
(small-sequence-size? l2))
|
||||||
(with-syntax ([(i1* ...) (for/list ([i (in-range l1)]) i)]
|
(with-syntax ([(i1* ...) (for/list ([i (in-range l1)]) i)]
|
||||||
[(i2* ...) (for/list ([i (in-range l2)]) i)])
|
[(i2* ...) (for/list ([i (in-range l2)]) i)])
|
||||||
(syntax/loc stx
|
(syntax/loc stx
|
||||||
|
@ -181,7 +171,7 @@
|
||||||
[(_ v:vector/length)
|
[(_ v:vector/length)
|
||||||
#:with v+ (gensym 'v)
|
#:with v+ (gensym 'v)
|
||||||
(define len (syntax-e #'v.evidence))
|
(define len (syntax-e #'v.evidence))
|
||||||
(if (small-vector-size? len)
|
(if (small-sequence-size? len)
|
||||||
(with-syntax ([(i* ...) (for/list ([i (in-range len)]) i)])
|
(with-syntax ([(i* ...) (for/list ([i (in-range len)]) i)])
|
||||||
(syntax/loc stx
|
(syntax/loc stx
|
||||||
(let ([v+ v.expanded])
|
(let ([v+ v.expanded])
|
||||||
|
@ -233,7 +223,7 @@
|
||||||
#:with n+ (gensym 'n)
|
#:with n+ (gensym 'n)
|
||||||
#:with v+ (gensym 'v)
|
#:with v+ (gensym 'v)
|
||||||
(unless (<= (syntax-e #'n-stx) (syntax-e #'v.evidence))
|
(unless (<= (syntax-e #'n-stx) (syntax-e #'v.evidence))
|
||||||
(vector-bounds-error (syntax-e #'op-name) #'v
|
(bounds-error (syntax-e #'op-name) #'v
|
||||||
(if 'take? (if 'left? (syntax-e #'hi) (syntax-e #'lo))
|
(if 'take? (if 'left? (syntax-e #'hi) (syntax-e #'lo))
|
||||||
(if 'left? (syntax-e #'lo) (syntax-e #'hi)))))
|
(if 'left? (syntax-e #'lo) (syntax-e #'hi)))))
|
||||||
(syntax-property
|
(syntax-property
|
||||||
|
@ -244,7 +234,7 @@
|
||||||
vector-length-key
|
vector-length-key
|
||||||
(syntax-e #'v.evidence))]
|
(syntax-e #'v.evidence))]
|
||||||
[(op-name v n:int/expand)
|
[(op-name v n:int/expand)
|
||||||
(vector-bounds-error (syntax-e #'op-name) #'v (stx->num #'n.expanded))]
|
(bounds-error (syntax-e #'op-name) #'v (stx->num #'n.expanded))]
|
||||||
[_ #f]))))
|
[_ #f]))))
|
||||||
|
|
||||||
(define-syntax vector-take:
|
(define-syntax vector-take:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user