factor/library/collections/slicing.factor

117 lines
3.0 KiB
Factor
Raw Normal View History

2005-06-23 23:29:04 -04:00
! Copyright (C) 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
IN: sequences
USING: generic kernel kernel-internals lists math namespaces
strings vectors ;
2005-08-25 15:27:38 -04:00
: head-slice ( n seq -- slice ) 0 -rot <slice> ; flushable
2005-06-23 23:29:04 -04:00
2005-08-25 15:27:38 -04:00
: tail-slice ( n seq -- slice ) [ length ] keep <slice> ; flushable
2005-08-25 15:27:38 -04:00
: (slice*) [ length swap - ] keep ;
2005-06-23 23:29:04 -04:00
2005-08-25 15:27:38 -04:00
: head-slice* ( n seq -- slice ) (slice*) head-slice ; flushable
2005-06-23 23:29:04 -04:00
2005-08-25 15:27:38 -04:00
: tail-slice* ( n seq -- slice ) (slice*) tail-slice ; flushable
2005-06-23 23:29:04 -04:00
2005-08-25 15:27:38 -04:00
: subseq ( from to seq -- seq ) [ <slice> ] keep like ; flushable
: head ( index seq -- seq ) [ head-slice ] keep like ;
2005-06-23 23:29:04 -04:00
2005-08-25 15:27:38 -04:00
: head* ( n seq -- seq ) [ head-slice* ] keep like ; flushable
2005-06-23 23:29:04 -04:00
: tail ( index seq -- seq ) [ tail-slice ] keep like ;
2005-06-23 23:29:04 -04:00
2005-08-25 15:27:38 -04:00
: tail* ( n seq -- seq ) [ tail-slice* ] keep like ; flushable
2005-06-23 23:29:04 -04:00
: head? ( seq begin -- ? )
2dup [ length ] 2apply < [
2005-06-23 23:29:04 -04:00
2drop f
] [
dup length rot head-slice sequence=
2005-09-24 15:21:17 -04:00
] if ; flushable
2005-06-23 23:29:04 -04:00
2005-12-31 20:51:58 -05:00
: ?head ( seq begin -- seq ? )
2005-09-24 15:21:17 -04:00
2dup head? [ length swap tail t ] [ drop f ] if ; flushable
2005-06-23 23:29:04 -04:00
: tail? ( seq end -- ? )
2dup [ length ] 2apply < [
2005-06-23 23:29:04 -04:00
2drop f
] [
dup length rot tail-slice* sequence=
2005-09-24 15:21:17 -04:00
] if ; flushable
2005-06-23 23:29:04 -04:00
: ?tail ( seq end -- seq ? )
2005-09-24 15:21:17 -04:00
2dup tail? [ length swap head* t ] [ drop f ] if ; flushable
2005-06-23 23:29:04 -04:00
2005-10-01 01:44:49 -04:00
: replace-slice ( new from to seq -- seq )
tuck >r >r head-slice r> r> tail-slice swapd append3 ;
flushable
2005-12-31 20:51:58 -05:00
: (cut) ( n seq -- before after )
[ head ] 2keep tail-slice ; flushable
: cut ( n seq -- before after )
[ (cut) ] keep like ; flushable
: cut* ( seq1 seq2 -- seq seq )
[ head* ] 2keep tail* ; flushable
2005-08-29 01:57:21 -04:00
: (group) ( n seq -- )
2dup length >= [
2005-11-19 04:09:30 -05:00
dup empty? [ 2drop ] [ dup like , drop ] if
2005-06-23 23:29:04 -04:00
] [
2005-12-31 20:51:58 -05:00
dupd (cut) >r , r> (group)
2005-09-24 15:21:17 -04:00
] if ;
2005-06-23 23:29:04 -04:00
: group ( n seq -- seq ) [ (group) ] { } make ; flushable
2005-06-23 23:29:04 -04:00
: start-step ( subseq seq n -- subseq slice )
pick length dupd + rot <slice> ;
: start* ( subseq seq n -- n )
pick length pick length pick - > [
3drop -1
] [
2dup >r >r start-step dupd sequence= [
r> 2drop r>
] [
2005-09-16 22:47:28 -04:00
r> r> 1+ start*
2005-09-24 15:21:17 -04:00
] if
] if ; flushable
2005-06-23 23:29:04 -04:00
2005-12-31 20:51:58 -05:00
: start ( subseq seq -- n ) 0 start* ; flushable
2005-06-23 23:29:04 -04:00
: subseq? ( subseq seq -- ? ) start -1 > ; flushable
2005-06-23 23:29:04 -04:00
2005-08-29 01:57:21 -04:00
: (split1) ( seq subseq -- before after )
2005-06-23 23:29:04 -04:00
dup pick start dup -1 = [
2005-08-29 01:57:21 -04:00
2drop dup like f
2005-06-23 23:29:04 -04:00
] [
2005-08-29 01:57:21 -04:00
[ swap length + over tail-slice ] keep rot head swap
2005-09-24 15:21:17 -04:00
] if ; flushable
2005-06-23 23:29:04 -04:00
2005-08-29 01:57:21 -04:00
: split1 ( seq subseq -- before after )
(split1) dup like ; flushable
2005-06-23 23:29:04 -04:00
2005-08-29 01:57:21 -04:00
: (split) ( seq subseq -- )
2005-09-24 15:21:17 -04:00
tuck (split1) >r , r> dup [ swap (split) ] [ 2drop ] if ;
2005-06-23 23:29:04 -04:00
2005-12-28 20:25:17 -05:00
: split ( seq subseq -- seq ) [ (split) ] { } make ; flushable
2005-09-01 01:20:43 -04:00
2005-10-09 21:27:14 -04:00
: drop-prefix ( seq1 seq2 -- seq1 seq2 )
2dup mismatch dup -1 = [ drop 2dup min-length ] when
tuck swap tail-slice >r swap tail-slice r> ;
2005-10-25 21:52:26 -04:00
2005-11-19 04:09:30 -05:00
: unpair ( seq -- firsts seconds )
2 swap group flip
dup empty? [ drop { } { } ] [ first2 ] if ;
2005-11-19 04:09:30 -05:00
2005-12-31 20:51:58 -05:00
: concat ( seq -- seq )
dup empty? [ [ [ % ] each ] over first make ] unless ;
flushable
: join ( seq glue -- seq )
[ swap [ % ] [ dup % ] interleave drop ] over make ;
flushable