]> gitweb.factorcode.org Git - factor.git/blob - core/splitting/splitting.factor
0398cb66d66a9861b2ba43b2805e35b4bc9dafea
[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 : split1-when ( ... seq quot: ( ... elt -- ... ? ) -- ... before after )
48     dupd find drop [ swap [ dup 1 + ] dip snip ] [ f ] if* ; inline
49
50 : split1-last ( seq subseq -- before after )
51     [ <reversed> ] bi@ split1 [ reverse ] bi@
52     dup [ swap ] when ;
53
54 : split1-last-slice ( seq subseq -- before-slice after-slice )
55     [ <reversed> ] bi@ split1-slice [ <reversed> ] bi@
56     [ f ] [ swap ] if-empty ;
57
58 <PRIVATE
59
60 : (split) ( n seq quot: ( ... elt -- ... ? ) -- )
61     [ find-from drop ]
62     [ [ [ 3dup swapd subseq , ] dip [ drop 1 + ] 2dip (split) ] 3curry ]
63     [ drop [ swap [ tail ] unless-zero , ] 2curry ]
64     3tri if* ; inline recursive
65
66 : split, ( ... seq quot: ( ... elt -- ... ? ) -- ... ) [ 0 ] 2dip (split) ; inline
67
68 PRIVATE>
69
70 : split ( seq separators -- pieces )
71     [ [ member? ] curry split, ] { } make ; inline
72
73 : split-when ( ... seq quot: ( ... elt -- ... ? ) -- ... pieces )
74     [ split, ] { } make ; inline
75
76 <PRIVATE
77
78 : (split*) ( n seq quot: ( ... elt -- ... ? ) -- )
79     [ find-from ]
80     [ [ [ 1 + ] 3dip [ 3dup swapd subseq , ] dip [ drop ] 2dip (split*) ] 3curry ]
81     [ drop [ [ drop ] 2dip 2dup length < [ swap [ tail ] unless-zero , ] [ 2drop ] if ] 2curry ]
82     3tri if ; inline recursive
83
84 : split*, ( ... seq quot: ( ... elt -- ... ? ) -- ... ) [ 0 ] 2dip (split*) ; inline
85
86 PRIVATE>
87
88 : split* ( seq separators -- pieces )
89     [ [ member? ] curry split*, ] { } make ; inline
90
91 : split*-when ( ... seq quot: ( ... elt -- ... ? ) -- ... pieces )
92     [ split*, ] { } make ; inline
93
94 GENERIC: string-lines ( str -- seq )
95
96 M: string string-lines
97     dup [ "\r\n" member? ] any? [
98         "\n" split
99         [
100             but-last-slice [
101                 dup ?last CHAR: \r = [ but-last ] when
102                 [ CHAR: \r = ] split-when
103             ] map! drop
104         ] [
105             [ length 1 - ] keep
106             [ [ CHAR: \r = ] split-when ] change-nth
107         ]
108         [ concat ]
109         tri
110     ] [
111         1array
112     ] if ;