factor/core/collections/slicing.factor

119 lines
2.9 KiB
Factor
Raw Permalink Normal View History

2005-06-23 23:29:04 -04:00
! Copyright (C) 2005 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
2005-06-23 23:29:04 -04:00
IN: sequences
2006-05-15 01:01:47 -04:00
USING: generic kernel kernel-internals math namespaces
2006-11-24 04:50:25 -05:00
strings vectors errors ;
2005-06-23 23:29:04 -04:00
: head-slice ( seq n -- slice ) 0 swap rot <slice> ;
2005-06-23 23:29:04 -04:00
: tail-slice ( seq n -- slice ) over length rot <slice> ;
: (slice*) >r dup length r> - ;
2005-06-23 23:29:04 -04:00
: head-slice* ( seq n -- slice ) (slice*) head-slice ;
2005-06-23 23:29:04 -04:00
: tail-slice* ( seq n -- slice ) (slice*) tail-slice ;
2005-06-23 23:29:04 -04:00
2006-08-16 21:55:53 -04:00
: subseq ( from to seq -- subseq ) [ <slice> ] keep like ;
2006-08-16 21:55:53 -04:00
: head ( seq n -- headseq ) dupd head-slice swap like ;
2005-06-23 23:29:04 -04:00
2006-08-16 21:55:53 -04:00
: head* ( seq n -- headseq ) dupd head-slice* swap like ;
2005-06-23 23:29:04 -04:00
2006-08-16 21:55:53 -04:00
: tail ( seq n -- tailseq ) dupd tail-slice swap like ;
2005-06-23 23:29:04 -04:00
2006-08-16 21:55:53 -04:00
: tail* ( seq n -- tailseq ) dupd tail-slice* swap like ;
2005-08-25 15:27:38 -04:00
2005-06-23 23:29:04 -04:00
: head? ( seq begin -- ? )
2dup [ length ] 2apply < [
2005-06-23 23:29:04 -04:00
2drop f
] [
[ length head-slice ] keep sequence=
] if ;
2005-06-23 23:29:04 -04:00
2006-08-16 21:55:53 -04:00
: ?head ( seq begin -- newseq ? )
2dup head? [ length tail t ] [ drop f ] if ;
2005-06-23 23:29:04 -04:00
2006-08-17 23:15:36 -04:00
: tail? ( seq end -- ? )
2dup [ length ] 2apply < [
2005-06-23 23:29:04 -04:00
2drop f
] [
[ length tail-slice* ] keep sequence=
] if ;
2005-06-23 23:29:04 -04:00
2006-08-16 21:55:53 -04:00
: ?tail ( seq end -- newseq ? )
2dup tail? [ length head* t ] [ drop f ] if ;
2005-06-23 23:29:04 -04:00
2006-08-16 21:55:53 -04:00
: replace-slice ( new m n seq -- replaced )
tuck swap tail-slice >r swap head-slice swap r> 3append ;
2005-10-01 01:44:49 -04:00
2006-08-16 21:55:53 -04:00
: remove-nth ( n seq -- newseq )
>r f swap dup 1+ r> replace-slice ;
2005-12-31 20:51:58 -05:00
: (cut) ( n seq -- before after )
swap [ head ] 2keep tail-slice ;
2005-12-31 20:51:58 -05:00
: cut ( n seq -- before after )
swap [ head ] 2keep tail ;
2005-12-31 20:51:58 -05:00
: cut* ( n seq -- before after )
swap [ head* ] 2keep tail* ;
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
2006-11-24 04:50:25 -05:00
: group ( seq n -- groups )
dup 0 <= [ "Invalid group count" throw ] when
[ swap (group) ] { } make ;
2005-06-23 23:29:04 -04:00
: start-step ( subseq seq n -- subseq slice )
pick length dupd + rot <slice> ;
2006-08-16 21:55:53 -04:00
: start* ( subseq seq i -- n )
2005-06-23 23:29:04 -04:00
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 ;
2005-06-23 23:29:04 -04:00
: start ( subseq seq -- n ) 0 start* ;
2005-06-23 23:29:04 -04:00
: subseq? ( subseq seq -- ? ) start -1 > ;
2005-06-23 23:29:04 -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
] [
[ >r over r> head -rot length ] keep + tail
] if ;
2005-06-23 23:29:04 -04:00
: split, building get peek push ;
: split-next, V{ } clone , ;
2006-08-16 21:55:53 -04:00
: (split) ( quot elt -- )
[ swap call ] keep swap
[ drop split-next, ] [ split, ] if ; inline
2005-06-23 23:29:04 -04:00
2006-08-16 21:55:53 -04:00
: split* ( seq quot -- pieces )
over >r
2006-06-14 02:27:57 -04:00
[ split-next, swap [ (split) ] each-with ]
{ } make r> swap [ swap like ] map-with ; inline
2005-06-23 23:29:04 -04:00
2006-08-16 21:55:53 -04:00
: split ( seq separators -- pieces )
swap [ over member? ] split* nip ;
2005-09-01 01:20:43 -04:00
2006-08-16 21:55:53 -04:00
: drop-prefix ( seq1 seq2 -- slice1 slice2 )
2005-10-09 21:27:14 -04:00
2dup mismatch dup -1 = [ drop 2dup min-length ] when
tuck tail-slice >r tail-slice r> ;
2005-10-25 21:52:26 -04:00
: unclip ( seq -- rest first ) dup 1 tail swap first ;