Add immutable-hashtable for R6RS
This commit is contained in:
parent
5793281d41
commit
2f1981e068
|
@ -0,0 +1,173 @@
|
||||||
|
(library (lassik immutable-hashtable)
|
||||||
|
(export make-eq-hashtable
|
||||||
|
make-eqv-hashtable
|
||||||
|
make-hashtable
|
||||||
|
|
||||||
|
hashtable-contains?
|
||||||
|
hashtable-entries
|
||||||
|
hashtable-equivalence-function
|
||||||
|
hashtable-hash-function
|
||||||
|
hashtable-keys
|
||||||
|
hashtable-mutable?
|
||||||
|
hashtable-ref
|
||||||
|
hashtable-size
|
||||||
|
hashtable?
|
||||||
|
immutable-hashtable?
|
||||||
|
|
||||||
|
equal-hash
|
||||||
|
string-ci-hash
|
||||||
|
string-hash
|
||||||
|
symbol-hash
|
||||||
|
|
||||||
|
hashtable-delete
|
||||||
|
hashtable-set
|
||||||
|
hashtable-update)
|
||||||
|
(import (rnrs base)
|
||||||
|
(rename (except (rnrs hashtables)
|
||||||
|
make-hashtable
|
||||||
|
make-eq-hashtable
|
||||||
|
make-eqv-hashtable)
|
||||||
|
(hashtable?
|
||||||
|
rnrs-hashtable?)
|
||||||
|
(hashtable-mutable?
|
||||||
|
rnrs-hashtable-mutable?)
|
||||||
|
(hashtable-size
|
||||||
|
rnrs-hashtable-size)
|
||||||
|
(hashtable-contains?
|
||||||
|
rnrs-hashtable-contains?)
|
||||||
|
(hashtable-entries
|
||||||
|
rnrs-hashtable-entries)
|
||||||
|
(hashtable-equivalence-function
|
||||||
|
rnrs-hashtable-equivalence-function)
|
||||||
|
(hashtable-hash-function
|
||||||
|
rnrs-hashtable-hash-function)
|
||||||
|
(hashtable-keys
|
||||||
|
rnrs-hashtable-keys)
|
||||||
|
(hashtable-ref
|
||||||
|
rnrs-hashtable-ref)))
|
||||||
|
(begin
|
||||||
|
|
||||||
|
;; From SRFI 1.
|
||||||
|
(define (append-reverse list1 list2)
|
||||||
|
(append (reverse list1) list2))
|
||||||
|
|
||||||
|
;; From R7RS.
|
||||||
|
(define (assoc key alist equivalent?)
|
||||||
|
(cond ((null? alist) #f)
|
||||||
|
((equivalent? key (caar alist)) (car alist))
|
||||||
|
(else (assoc key (cdr alist) equivalent?))))
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (immutable-hashtable? obj)
|
||||||
|
(and (vector? obj) (eq? 'immutable-hashtable (vector-ref obj 0))))
|
||||||
|
|
||||||
|
(define (hashtable? obj)
|
||||||
|
(or (rnrs-hashtable? obj)
|
||||||
|
(immutable-hashtable? obj)))
|
||||||
|
|
||||||
|
(define (hashtable-mutable? table)
|
||||||
|
(if (rnrs-hashtable? table)
|
||||||
|
(rnrs-hashtable-mutable? table)
|
||||||
|
#f))
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (make-hashtable* hash equivalent? alist)
|
||||||
|
(vector 'immutable-hashtable hash equivalent? alist))
|
||||||
|
|
||||||
|
(define (make-hashtable hash equivalent?)
|
||||||
|
(make-hashtable* hash equivalent? '()))
|
||||||
|
|
||||||
|
(define (make-eq-hashtable)
|
||||||
|
(make-hashtable #f eq?))
|
||||||
|
|
||||||
|
(define (make-eqv-hashtable)
|
||||||
|
(make-hashtable #f eqv?))
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (hashtable-hash-function table)
|
||||||
|
(if (rnrs-hashtable? table)
|
||||||
|
(rnrs-hashtable-hash-function table)
|
||||||
|
(vector-ref table 1)))
|
||||||
|
|
||||||
|
(define (hashtable-equivalence-function table)
|
||||||
|
(if (rnrs-hashtable? table)
|
||||||
|
(rnrs-hashtable-equivalence-function table)
|
||||||
|
(vector-ref table 2)))
|
||||||
|
|
||||||
|
(define (hashtable-alist table)
|
||||||
|
(vector-ref table 3))
|
||||||
|
|
||||||
|
(define (hashtable-assoc table key)
|
||||||
|
(assoc key
|
||||||
|
(hashtable-alist table)
|
||||||
|
(hashtable-equivalence-function table)))
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (hashtable-contains? table key)
|
||||||
|
(if (rnrs-hashtable? table)
|
||||||
|
(rnrs-hashtable-contains? table key)
|
||||||
|
(not (not (hashtable-assoc table key)))))
|
||||||
|
|
||||||
|
(define (hashtable-keys table)
|
||||||
|
(if (rnrs-hashtable? table)
|
||||||
|
(rnrs-hashtable-keys table)
|
||||||
|
(list->vector (map car (hashtable-alist table)))))
|
||||||
|
|
||||||
|
(define (hashtable-entries table)
|
||||||
|
(if (rnrs-hashtable? table)
|
||||||
|
(rnrs-hashtable-entries table)
|
||||||
|
(values (list->vector (map car (hashtable-alist table)))
|
||||||
|
(list->vector (map cdr (hashtable-alist table))))))
|
||||||
|
|
||||||
|
(define (hashtable-ref table key default)
|
||||||
|
(if (rnrs-hashtable? table)
|
||||||
|
(rnrs-hashtable-ref table key default)
|
||||||
|
(let ((entry (hashtable-assoc table key)))
|
||||||
|
(if entry (cdr entry) default))))
|
||||||
|
|
||||||
|
(define (hashtable-size table)
|
||||||
|
(if (rnrs-hashtable? table)
|
||||||
|
(rnrs-hashtable-size table)
|
||||||
|
(length (hashtable-alist table))))
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (hashtable-delete table key)
|
||||||
|
(let ((equivalent? (hashtable-equivalence-function table)))
|
||||||
|
(make-hashtable*
|
||||||
|
(hashtable-hash-function table)
|
||||||
|
equivalent?
|
||||||
|
(let loop ((old-alist (hashtable-alist table))
|
||||||
|
(new-alist '()))
|
||||||
|
(if (null? old-alist) (reverse new-alist)
|
||||||
|
(loop (cdr old-alist)
|
||||||
|
(if (equivalent? key (caar old-alist))
|
||||||
|
new-alist
|
||||||
|
(cons (car old-alist) new-alist))))))))
|
||||||
|
|
||||||
|
(define (hashtable-update table key update default)
|
||||||
|
(let ((equivalent? (hashtable-equivalence-function table)))
|
||||||
|
(make-hashtable*
|
||||||
|
(hashtable-hash-function table)
|
||||||
|
equivalent?
|
||||||
|
(let loop ((old-alist (hashtable-alist table))
|
||||||
|
(new-alist '()))
|
||||||
|
(cond ((null? old-alist)
|
||||||
|
(reverse (cons (cons key (update default))
|
||||||
|
new-alist)))
|
||||||
|
((equivalent? key (caar old-alist))
|
||||||
|
(append-reverse (cons (cons (caar old-alist)
|
||||||
|
(update (cdar old-alist)))
|
||||||
|
new-alist)
|
||||||
|
(cdr old-alist)))
|
||||||
|
(else
|
||||||
|
(loop (cdr old-alist)
|
||||||
|
(cons (car old-alist)
|
||||||
|
new-alist))))))))
|
||||||
|
|
||||||
|
(define (hashtable-set table key value)
|
||||||
|
(hashtable-update table key (lambda (_) value) #f))))
|
Loading…
Reference in New Issue