1 ! Copyright (C) 2006, 2007 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: arrays sequences sequences.private math.private
5 kernel kernel.private math assocs quotations vectors ;
9 : dispatch ( n array -- ) array-nth (call) ;
15 : no-cond ( -- * ) \ no-cond construct-empty throw ;
18 [ first call ] find nip dup [ second call ] [ no-cond ] if ;
22 : no-case ( -- * ) \ no-case construct-empty throw ;
24 : case ( obj assoc -- )
25 [ dup array? [ dupd first = ] [ quotation? ] if ] find nip
27 { [ dup array? ] [ nip second call ] }
28 { [ dup quotation? ] [ call ] }
29 { [ dup not ] [ no-case ] }
32 : with-datastack ( stack quot -- newstack )
34 >r >array set-datastack r> call
35 datastack r> swap add set-datastack 2nip ; inline
37 : recursive-hashcode ( n obj quot -- code )
38 pick 0 <= [ 3drop 0 ] [ rot 1- -rot call ] if ; inline
42 0 -rot [ hashcode* bitxor ] curry* each
43 ] recursive-hashcode ;
45 : alist>quot ( default assoc -- quot )
46 [ rot \ if 3array append [ ] like ] assoc-each ;
48 : cond>quot ( assoc -- quot )
49 reverse [ no-cond ] swap alist>quot ;
51 : case>quot ( default assoc -- quot )
52 [ >r [ dupd = ] curry r> \ drop add* ] assoc-map
55 : (distribute-buckets) ( buckets pair keys -- )
57 drop [ swap push-new ] curry each
60 >r 2dup r> hashcode pick length rem rot nth push-new
64 : <buckets> ( initial length -- array )
65 next-power-of-2 swap [ nip clone ] curry map ;
67 : distribute-buckets ( assoc initial quot -- buckets )
68 swap rot [ length <buckets> ] keep
69 [ >r 2dup r> dup first roll call (distribute-buckets) ] each
72 : hash-case-table ( default assoc -- array )
73 V{ } [ 1array ] distribute-buckets
74 [ case>quot ] curry* map ;
76 : hash-dispatch-quot ( table -- quot )
77 [ length 1- [ fixnum-bitand ] curry ] keep
78 [ dispatch ] curry append ;
80 : hash-case>quot ( default assoc -- quot )
84 hash-case-table hash-dispatch-quot
85 [ dup hashcode >fixnum ] swap append