]> gitweb.factorcode.org Git - factor.git/blob - core/splitting/splitting.factor
65125eed467b552c16fb6d040af38b2d10f5d83b
[factor.git] / core / splitting / splitting.factor
1 ! Copyright (C) 2005, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays kernel make math sequences sets strings ;
4 IN: splitting
5
6 <PRIVATE
7
8 : ?chomp ( seq begin tester chopper -- newseq ? )
9     [ [ 2dup ] dip call ] dip
10     [ [ length ] dip call t ] curry
11     [ drop f ] if ; inline
12
13 PRIVATE>
14
15 : ?head ( seq begin -- newseq ? )
16     [ head? ] [ tail ] ?chomp ;
17
18 : ?head-slice ( seq begin -- newseq ? )
19     [ head? ] [ tail-slice ] ?chomp ;
20
21 : ?tail ( seq end -- newseq ? )
22     [ tail? ] [ head* ] ?chomp ;
23
24 : ?tail-slice ( seq end -- newseq ? )
25     [ tail? ] [ head-slice* ] ?chomp ;
26
27 <PRIVATE
28
29 : (split1) ( seq subseq quot -- before after )
30     [
31         swap [
32             [ drop length ] [ start dup ] 2bi
33             [ [ nip ] [ + ] 2bi t ]
34             [ 2drop f f f ]
35             if
36         ] keep swap
37     ] dip [ 2nip f ] if ; inline
38
39 PRIVATE>
40
41 : split1 ( seq subseq -- before after )
42     [ snip ] (split1) ;
43
44 : split1-slice ( seq subseq -- before-slice after-slice )
45     [ snip-slice ] (split1) ;
46
47 : split-subseq ( seq subseq -- seqs )
48     dup empty? [
49         drop 1array
50     ] [
51         [ dup ] swap [ split1-slice swap ] curry produce nip
52     ] if ;
53
54 : split1-when ( ... seq quot: ( ... elt -- ... ? ) -- ... before after )
55     dupd find drop [ swap [ dup 1 + ] dip snip ] [ f ] if* ; inline
56
57 : split1-last ( seq subseq -- before after )
58     [ <reversed> ] bi@ split1 [ reverse ] bi@
59     dup [ swap ] when ;
60
61 : split1-last-slice ( seq subseq -- before-slice after-slice )
62     [ <reversed> ] bi@ split1-slice [ <reversed> ] bi@
63     [ f ] [ swap ] if-empty ;
64
65 : replace ( seq old new -- new-seq )
66     pick [ [ split-subseq ] dip ] dip join-as ;
67
68 <PRIVATE
69
70 : (split) ( n seq quot: ( ... elt -- ... ? ) -- )
71     [ find-from drop ]
72     [ [ [ 3dup swapd subseq , ] dip [ drop 1 + ] 2dip (split) ] 3curry ]
73     [ drop [ swap [ tail ] unless-zero , ] 2curry ]
74     3tri if* ; inline recursive
75
76 : split, ( ... seq quot: ( ... elt -- ... ? ) -- ... ) [ 0 ] 2dip (split) ; inline
77
78 PRIVATE>
79
80 : split ( seq separators -- pieces )
81     [ [ member? ] curry split, ] { } make ; inline
82
83 : split-when ( ... seq quot: ( ... elt -- ... ? ) -- ... pieces )
84     [ split, ] { } make ; inline
85
86 <PRIVATE
87
88 : (split*) ( n seq quot: ( ... elt -- ... ? ) -- )
89     [ find-from ]
90     [ [ [ 1 + ] 3dip [ 3dup swapd subseq , ] dip [ drop ] 2dip (split*) ] 3curry ]
91     [ drop [ [ drop ] 2dip 2dup length < [ swap [ tail ] unless-zero , ] [ 2drop ] if ] 2curry ]
92     3tri if ; inline recursive
93
94 : split*, ( ... seq quot: ( ... elt -- ... ? ) -- ... ) [ 0 ] 2dip (split*) ; inline
95
96 PRIVATE>
97
98 : split* ( seq separators -- pieces )
99     [ [ member? ] curry split*, ] { } make ; inline
100
101 : split*-when ( ... seq quot: ( ... elt -- ... ? ) -- ... pieces )
102     [ split*, ] { } make ; inline
103
104 GENERIC: string-lines ( str -- seq )
105
106 M: string string-lines
107     dup [ "\r\n" member? ] any? [
108         "\n" split
109         [
110             but-last-slice [
111                 dup ?last CHAR: \r = [ but-last ] when
112                 [ CHAR: \r = ] split-when
113             ] map! drop
114         ] [
115             [ length 1 - ] keep
116             [ [ CHAR: \r = ] split-when ] change-nth
117         ]
118         [ concat ]
119         tri
120     ] [
121         1array
122     ] if ;