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
|
2006-05-15 01:01:47 -04:00
|
|
|
USING: generic kernel kernel-internals math namespaces
|
2005-06-23 23:29:04 -04:00
|
|
|
strings vectors ;
|
|
|
|
|
|
2006-06-05 23:26:44 -04:00
|
|
|
: head-slice ( n seq -- slice ) 0 -rot <slice> ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-05 23:26:44 -04:00
|
|
|
: tail-slice ( n seq -- slice ) [ length ] keep <slice> ;
|
2005-08-07 18:11:20 -04:00
|
|
|
|
2005-08-25 15:27:38 -04:00
|
|
|
: (slice*) [ length swap - ] keep ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-05 23:26:44 -04:00
|
|
|
: head-slice* ( n seq -- slice ) (slice*) head-slice ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-05 23:26:44 -04:00
|
|
|
: tail-slice* ( n seq -- slice ) (slice*) tail-slice ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-05 23:26:44 -04:00
|
|
|
: subseq ( from to seq -- seq ) [ <slice> ] keep like ;
|
2005-08-07 18:11:20 -04:00
|
|
|
|
2006-03-21 00:44:19 -05:00
|
|
|
: head ( index seq -- seq ) [ head-slice ] keep like ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-05 23:26:44 -04:00
|
|
|
: head* ( n seq -- seq ) [ head-slice* ] keep like ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-03-21 00:44:19 -05:00
|
|
|
: tail ( index seq -- seq ) [ tail-slice ] keep like ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-05 23:26:44 -04:00
|
|
|
: tail* ( n seq -- seq ) [ tail-slice* ] keep like ;
|
2005-08-25 15:27:38 -04:00
|
|
|
|
2005-06-23 23:29:04 -04:00
|
|
|
: head? ( seq begin -- ? )
|
2005-09-16 02:39:33 -04:00
|
|
|
2dup [ length ] 2apply < [
|
2005-06-23 23:29:04 -04:00
|
|
|
2drop f
|
|
|
|
|
] [
|
|
|
|
|
dup length rot head-slice sequence=
|
2006-06-05 23:26:44 -04:00
|
|
|
] if ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2005-12-31 20:51:58 -05:00
|
|
|
: ?head ( seq begin -- seq ? )
|
2006-06-05 23:26:44 -04:00
|
|
|
2dup head? [ length swap tail t ] [ drop f ] if ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
|
|
|
|
: tail? ( seq end -- ? )
|
2005-09-16 02:39:33 -04:00
|
|
|
2dup [ length ] 2apply < [
|
2005-06-23 23:29:04 -04:00
|
|
|
2drop f
|
|
|
|
|
] [
|
2005-08-07 18:11:20 -04:00
|
|
|
dup length rot tail-slice* sequence=
|
2006-06-05 23:26:44 -04:00
|
|
|
] if ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
|
|
|
|
: ?tail ( seq end -- seq ? )
|
2006-06-05 23:26:44 -04:00
|
|
|
2dup tail? [ length swap head* t ] [ drop f ] if ;
|
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 ;
|
|
|
|
|
|
2006-06-04 03:46:06 -04:00
|
|
|
: remove-nth ( n seq -- seq )
|
2006-07-28 03:54:46 -04:00
|
|
|
f -rot dupd replace-slice ;
|
2006-05-19 21:08:42 -04:00
|
|
|
|
2005-12-31 20:51:58 -05:00
|
|
|
: (cut) ( n seq -- before after )
|
2006-06-05 23:26:44 -04:00
|
|
|
[ head ] 2keep tail-slice ;
|
2005-12-31 20:51:58 -05:00
|
|
|
|
|
|
|
|
: cut ( n seq -- before after )
|
2006-06-05 23:26:44 -04:00
|
|
|
[ head ] 2keep tail ;
|
2005-12-31 20:51:58 -05:00
|
|
|
|
2006-03-08 15:03:01 -05:00
|
|
|
: cut* ( seq1 seq2 -- seq seq )
|
2006-06-05 23:26:44 -04:00
|
|
|
[ head* ] 2keep tail* ;
|
2006-03-08 15:03:01 -05:00
|
|
|
|
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-06-05 23:26:44 -04:00
|
|
|
: group ( n seq -- seq ) [ (group) ] { } make ;
|
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
|
2006-06-05 23:26:44 -04:00
|
|
|
] if ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-05 23:26:44 -04:00
|
|
|
: start ( subseq seq -- n ) 0 start* ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-05 23:26:44 -04:00
|
|
|
: subseq? ( subseq seq -- ? ) start -1 > ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-11 22:44:22 -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
|
|
|
] [
|
2006-06-11 22:44:22 -04:00
|
|
|
[ swap length + over tail ] keep rot head swap
|
2006-06-05 23:26:44 -04:00
|
|
|
] if ;
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-11 22:44:22 -04:00
|
|
|
: split,, building get peek push ;
|
|
|
|
|
|
|
|
|
|
: split-next, V{ } clone , ;
|
|
|
|
|
|
|
|
|
|
: (split) ( separator elt -- | separator: elt -- ? )
|
|
|
|
|
[ swap call ] keep swap
|
|
|
|
|
[ drop split-next, ] [ split,, ] if ; inline
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-11 22:44:22 -04:00
|
|
|
: split* ( seq separator -- split | separator: elt -- ? )
|
|
|
|
|
over >r
|
2006-06-14 02:27:57 -04:00
|
|
|
[ split-next, swap [ (split) ] each-with ]
|
2006-06-11 22:44:22 -04:00
|
|
|
{ } make r> swap [ swap like ] map-with ; inline
|
2005-06-23 23:29:04 -04:00
|
|
|
|
2006-06-11 22:44:22 -04:00
|
|
|
: split ( seq separators -- split )
|
|
|
|
|
swap [ over member? ] split* nip ;
|
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
|
|
|
|
2006-05-18 22:20:23 -04:00
|
|
|
: unclip ( seq -- rest first ) 1 over tail swap first ;
|