1 ! Copyright (C) 2005, 2006 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: arrays errors generic kernel kernel-internals math
5 sequences-internals strings vectors words ;
7 : first2 ( seq -- first second )
8 1 swap bounds-check nip first2-unsafe ;
10 : first3 ( seq -- first second third )
11 2 swap bounds-check nip first3-unsafe ;
13 : first4 ( seq -- first second third fourth )
14 3 swap bounds-check nip first4-unsafe ;
16 : index ( obj seq -- n )
17 [ = ] find-with drop ;
19 : index* ( obj i seq -- n )
20 [ = ] find-with* drop ;
22 : last-index ( obj seq -- n )
23 [ = ] find-last-with drop ;
25 : last-index* ( obj i seq -- n )
26 [ = ] find-last-with* drop ;
28 : member? ( obj seq -- ? )
29 [ = ] contains-with? ;
31 : memq? ( obj seq -- ? )
32 [ eq? ] contains-with? ;
34 : remove ( obj seq -- newseq )
35 [ = not ] subset-with ;
37 : (subst) ( newseq oldseq elt -- new/elt )
39 over -1 > [ drop swap nth ] [ 2nip ] if ;
41 : subst ( newseq oldseq seq -- )
42 [ >r 2dup r> (subst) ] inject 2drop ;
46 [ 3drop ] [ [ nth swap ] keep set-nth ] if ; inline
48 : (delete) ( elt store scan seq -- elt store scan seq )
51 [ nth pick = ] 2keep rot
52 [ >r >r 1+ r> r> ] unless >r 1+ r> (delete)
55 : delete ( elt seq -- ) 0 0 rot (delete) nip set-length drop ;
57 : push-new ( elt seq -- ) [ delete ] 2keep push ;
59 : prune ( seq -- newseq )
60 [ V{ } clone swap [ over push-new ] each ] keep like ;
62 : nappend ( dest src -- )
63 >r [ length ] keep r> copy-into ; inline
65 : ((append)) ( seq1 seq2 accum -- accum )
66 [ >r over length r> rot copy-into ] keep
67 [ 0 swap rot copy-into ] keep ; inline
69 : (3append) ( seq1 seq2 seq3 exemplar -- newseq )
71 >r pick length pick length pick length + + r> new
72 [ >r pick length pick length + r> rot copy-into ] keep
76 : 3append ( seq1 seq2 seq3 -- newseq )
77 pick (3append) ; inline
79 : (append) ( seq1 seq2 exemplar -- newseq )
81 >r over length over length + r> new ((append))
84 : append ( seq1 seq2 -- newseq )
85 over (append) ; inline
87 : add ( seq elt -- newseq ) 1array append ; inline
89 : add* ( seq elt -- newseq ) 1array swap dup (append) ; inline
91 : concat ( seq -- newseq )
93 [ 0 [ length + ] accumulate ] keep
94 rot over first new -rot
95 [ >r over r> copy-into ] 2each
98 : diff ( seq1 seq2 -- newseq )
99 [ swap member? not ] subset-with ;
101 : peek ( seq -- elt ) dup length 1- swap nth ;
103 : pop* ( seq -- ) dup length 1- swap set-length ;
106 dup length 1- swap [ nth ] 2keep set-length ;
108 : all-equal? ( seq -- ? ) [ = ] monotonic? ;
110 : all-eq? ( seq -- ? ) [ eq? ] monotonic? ;
112 : (mismatch) ( seq1 seq2 n -- i )
113 [ >r 2dup r> 2nth-unsafe = not ] find drop 2nip ; inline
115 : mismatch ( seq1 seq2 -- i )
116 2dup min-length (mismatch) ;
118 : flip ( matrix -- newmatrix )
120 dup first [ length [ <column> dup like ] map-with ] keep
124 : unpair ( assoc -- keys values )
125 flip dup empty? [ drop { } { } ] [ first2 ] if ;
127 : exchange ( m n seq -- )
128 pick over bounds-check 2drop 2dup bounds-check 2drop
131 : assoc ( key assoc -- value )
132 [ first = ] find-with nip second ;
134 : rassoc ( value assoc -- key )
135 [ second = ] find-with nip first ;
137 : last/first ( seq -- pair ) dup peek swap first 2array ;
139 : padding ( seq n elt -- newseq )
140 >r swap length [-] r> <array> ;
142 : pad-left ( seq n elt -- padded )
143 pick >r pick >r padding r> append r> like ;
145 : pad-right ( seq n elt -- padded )
146 pick >r padding r> swap append ;
148 : sequence= ( seq1 seq2 -- ? )
149 2dup [ length ] 2apply tuck number=
150 [ (mismatch) -1 number= ] [ 3drop f ] if ; inline
153 over array? [ sequence= ] [ 2drop f ] if ;
156 over quotation? [ sequence= ] [ 2drop f ] if ;
159 over sbuf? [ sequence= ] [ 2drop f ] if ;
162 over vector? [ sequence= ] [ 2drop f ] if ;
164 UNION: sequence array string sbuf vector quotation ;
167 dup empty? [ drop 0 ] [ first hashcode ] if ;
172 2dup mismatch dup -1 =
173 [ drop [ length ] 2apply - ] [ 2nth-unsafe <=> ] if ;
175 : depth ( -- n ) datastack length ;
178 : no-cond ( -- * ) <no-cond> throw ;
181 [ first call ] find nip dup [ second call ] [ no-cond ] if ;
184 os { "freebsd" "linux" "macosx" "solaris" } member? ;