1 ! Copyright (C) 2007, 2008 Daniel Ehrenberg, Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: sequences kernel strings math fry ;
6 ! All traversal goes in postorder
8 GENERIC: branch? ( object -- ? )
10 M: sequence branch? drop t ;
11 M: integer branch? drop f ;
12 M: string branch? drop f ;
13 M: object branch? drop f ;
15 : deep-each ( ... obj quot: ( ... elt -- ... ) -- ... )
16 [ call ] 2keep over branch?
17 [ '[ _ deep-each ] each ] [ 2drop ] if ; inline recursive
19 : deep-map ( ... obj quot: ( ... elt -- ... elt' ) -- ... newobj )
20 [ call ] keep over branch?
21 [ '[ _ deep-map ] map ] [ drop ] if ; inline recursive
23 : deep-filter-as ( ... obj quot: ( ... elt -- ... ? ) exemplar -- ... seq )
24 [ selector [ deep-each ] dip ] dip [ like ] when* ; inline recursive
26 : deep-filter ( ... obj quot: ( ... elt -- ... ? ) -- ... seq )
27 over dup branch? [ drop f ] unless deep-filter-as ; inline
29 : (deep-find) ( ... obj quot: ( ... elt -- ... ? ) -- ... elt ? )
30 [ call ] 2keep rot [ drop t ] [
32 [ f ] 2dip '[ nip _ (deep-find) ] any?
34 ] if ; inline recursive
36 : deep-find ( ... obj quot: ( ... elt -- ... ? ) -- ... elt ) (deep-find) drop ; inline
38 : deep-any? ( ... obj quot: ( ... elt -- ... ? ) -- ... ? ) (deep-find) nip ; inline
40 : deep-all? ( ... obj quot: ( ... elt -- ... ? ) -- ... ? )
41 '[ @ not ] deep-any? not ; inline
43 : deep-member? ( obj seq -- ? )
45 _ swap dup branch? [ member? ] [ 2drop f ] if
46 ] deep-find >boolean ;
48 : deep-subseq? ( subseq seq -- ? )
50 _ swap dup branch? [ subseq? ] [ 2drop f ] if
51 ] deep-find >boolean ;
53 : deep-map! ( ... obj quot: ( ... elt -- ... elt' ) -- ... obj )
55 '[ _ [ call ] keep over [ deep-map! drop ] dip ] map!
56 ] [ drop ] if ; inline recursive
58 : flatten ( obj -- seq )
59 [ branch? not ] deep-filter ;
61 : flatten-as ( obj exemplar -- seq )
62 [ branch? not ] swap deep-filter-as ;