2005-04-02 02:39:33 -05: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 strings
|
|
|
|
|
vectors ;
|
|
|
|
|
|
|
|
|
|
! This is loaded once everything else is available.
|
2005-04-12 13:35:27 -04:00
|
|
|
|
|
|
|
|
! Note that the sequence union does not include lists, or user
|
|
|
|
|
! defined tuples that respond to the sequence protocol.
|
|
|
|
|
UNION: sequence array string sbuf vector ;
|
2005-04-02 02:39:33 -05:00
|
|
|
|
2005-04-25 19:54:21 -04:00
|
|
|
M: object thaw clone ;
|
2005-06-12 03:38:57 -04:00
|
|
|
|
|
|
|
|
M: object like drop ;
|
2005-04-19 20:28:01 -04:00
|
|
|
|
2005-04-25 19:54:21 -04:00
|
|
|
M: object empty? ( seq -- ? ) length 0 = ;
|
2005-04-19 20:28:01 -04:00
|
|
|
|
2005-04-03 16:55:56 -04:00
|
|
|
: (>list) ( n i seq -- list )
|
2005-04-02 02:39:33 -05:00
|
|
|
pick pick <= [
|
|
|
|
|
3drop [ ]
|
|
|
|
|
] [
|
|
|
|
|
2dup nth >r >r 1 + r> (>list) r> swons
|
|
|
|
|
] ifte ;
|
|
|
|
|
|
2005-04-03 16:55:56 -04:00
|
|
|
M: object >list ( seq -- list ) dup length 0 rot (>list) ;
|
2005-04-02 02:39:33 -05:00
|
|
|
|
2005-04-15 23:00:22 -04:00
|
|
|
: 2nth ( s s n -- x x ) tuck swap nth >r swap nth r> ;
|
|
|
|
|
|
|
|
|
|
! Combinators
|
2005-05-14 17:18:45 -04:00
|
|
|
M: object each ( quot seq -- )
|
|
|
|
|
swap dup length [
|
|
|
|
|
[ swap nth swap call ] 3keep
|
|
|
|
|
] repeat 2drop ;
|
2005-04-11 23:05:05 -04:00
|
|
|
|
2005-05-14 17:18:45 -04:00
|
|
|
M: object tree-each call ;
|
2005-04-11 23:05:05 -04:00
|
|
|
|
2005-05-14 17:18:45 -04:00
|
|
|
M: sequence tree-each swap [ swap tree-each ] each-with ;
|
2005-04-02 02:39:33 -05:00
|
|
|
|
2005-04-17 21:59:11 -04:00
|
|
|
: change-nth ( seq i quot -- )
|
|
|
|
|
pick pick >r >r >r swap nth r> call r> r> swap set-nth ;
|
2005-04-30 17:17:10 -04:00
|
|
|
inline
|
2005-04-17 21:59:11 -04:00
|
|
|
|
|
|
|
|
: (nmap) ( seq i quot -- )
|
|
|
|
|
pick length pick <= [
|
|
|
|
|
3drop
|
|
|
|
|
] [
|
2005-05-05 15:31:57 -04:00
|
|
|
[ change-nth ] 3keep >r 1 + r> (nmap)
|
2005-04-17 21:59:11 -04:00
|
|
|
] ifte ; inline
|
|
|
|
|
|
|
|
|
|
: nmap ( seq quot -- | quot: elt -- elt )
|
|
|
|
|
#! Destructive on seq.
|
|
|
|
|
0 swap (nmap) ; inline
|
|
|
|
|
|
|
|
|
|
: immutable ( seq quot -- seq | quot: seq -- )
|
2005-06-12 03:38:57 -04:00
|
|
|
swap [ thaw ] keep >r dup >r swap call r> r> like ; inline
|
2005-04-17 21:59:11 -04:00
|
|
|
|
2005-05-14 17:18:45 -04:00
|
|
|
M: object map ( seq quot -- seq | quot: elt -- elt )
|
|
|
|
|
swap [ swap nmap ] immutable ;
|
2005-04-30 02:01:04 -04:00
|
|
|
|
2005-04-17 21:59:11 -04:00
|
|
|
: (2nmap) ( seq1 seq2 i quot -- elt3 )
|
2005-04-11 23:05:05 -04:00
|
|
|
pick pick >r >r >r 2nth r> call r> r> swap set-nth ; inline
|
|
|
|
|
|
2005-04-17 21:59:11 -04:00
|
|
|
: 2nmap ( seq1 seq2 quot -- | quot: elt1 elt2 -- elt3 )
|
2005-04-11 23:05:05 -04:00
|
|
|
#! Destructive on seq2.
|
|
|
|
|
over length [
|
2005-04-17 21:59:11 -04:00
|
|
|
[ >r 3dup r> swap (2nmap) ] keep
|
2005-04-11 23:05:05 -04:00
|
|
|
] repeat 3drop ; inline
|
|
|
|
|
|
2005-05-14 17:18:45 -04:00
|
|
|
M: object 2map ( seq1 seq2 quot -- seq | quot: elt1 elt2 -- elt3 )
|
|
|
|
|
swap [ swap 2nmap ] immutable ;
|
2005-04-11 23:05:05 -04:00
|
|
|
|
2005-04-15 23:00:22 -04:00
|
|
|
! Operations
|
2005-05-18 16:26:22 -04:00
|
|
|
: index* ( obj seq i -- n )
|
2005-04-11 23:05:05 -04:00
|
|
|
#! The index of the object in the sequence, starting from i.
|
2005-05-18 16:26:22 -04:00
|
|
|
over length over <= [
|
2005-05-05 16:51:38 -04:00
|
|
|
3drop -1
|
|
|
|
|
] [
|
2005-05-18 16:26:22 -04:00
|
|
|
3dup swap nth = [ 2nip ] [ 1 + index* ] ifte
|
2005-05-05 16:51:38 -04:00
|
|
|
] ifte ;
|
2005-04-06 21:41:49 -04:00
|
|
|
|
2005-04-11 23:05:05 -04:00
|
|
|
: index ( obj seq -- n )
|
|
|
|
|
#! The index of the object in the sequence.
|
2005-05-18 16:26:22 -04:00
|
|
|
0 index* ;
|
2005-04-11 23:05:05 -04:00
|
|
|
|
2005-05-22 02:35:38 -04:00
|
|
|
M: object contains? ( obj seq -- ? )
|
|
|
|
|
#! Tests for membership using =.
|
|
|
|
|
index -1 > ;
|
2005-05-05 22:30:58 -04:00
|
|
|
|
2005-04-06 21:41:49 -04:00
|
|
|
: push ( element sequence -- )
|
|
|
|
|
#! Push a value on the end of a sequence.
|
|
|
|
|
dup length swap set-nth ;
|
|
|
|
|
|
2005-04-15 23:00:22 -04:00
|
|
|
: nappend ( s1 s2 -- )
|
2005-04-06 21:41:49 -04:00
|
|
|
#! Destructively append s2 to s1.
|
2005-05-14 17:18:45 -04:00
|
|
|
[ over push ] each drop ;
|
2005-04-06 21:41:49 -04:00
|
|
|
|
2005-04-25 19:54:21 -04:00
|
|
|
: append ( s1 s2 -- s1+s2 )
|
2005-06-23 15:53:54 -04:00
|
|
|
#! Outputs a new sequence of the same type as s1.
|
2005-04-17 21:59:11 -04:00
|
|
|
swap [ swap nappend ] immutable ;
|
2005-06-23 15:53:54 -04:00
|
|
|
|
|
|
|
|
: add ( seq elt -- seq )
|
|
|
|
|
#! Outputs a new sequence of the same type as seq.
|
|
|
|
|
unit append ;
|
2005-04-17 21:59:11 -04:00
|
|
|
|
2005-04-25 19:54:21 -04:00
|
|
|
: append3 ( s1 s2 s3 -- s1+s2+s3 )
|
2005-04-17 21:59:11 -04:00
|
|
|
#! Return a new sequence of the same type as s1.
|
|
|
|
|
rot [ [ rot nappend ] keep swap nappend ] immutable ;
|
|
|
|
|
|
2005-05-24 19:59:21 -04:00
|
|
|
M: f concat ;
|
|
|
|
|
|
|
|
|
|
M: cons concat
|
|
|
|
|
unswons [ swap [ nappend ] each-with ] immutable ;
|
|
|
|
|
|
|
|
|
|
M: object concat
|
|
|
|
|
>list concat ;
|
2005-04-25 19:54:21 -04:00
|
|
|
|
2005-04-26 00:35:55 -04:00
|
|
|
M: object peek ( sequence -- element )
|
2005-04-06 21:41:49 -04:00
|
|
|
#! Get value at end of sequence.
|
|
|
|
|
dup length 1 - swap nth ;
|
|
|
|
|
|
|
|
|
|
: pop ( sequence -- element )
|
|
|
|
|
#! Get value at end of sequence and remove it.
|
|
|
|
|
dup peek >r dup length 1 - swap set-length r> ;
|
|
|
|
|
|
|
|
|
|
: >pop> ( stack -- stack ) dup pop drop ;
|
|
|
|
|
|
2005-04-16 00:23:27 -04:00
|
|
|
: (exchange) ( seq i j -- seq[i] j seq )
|
|
|
|
|
pick >r >r swap nth r> r> ;
|
|
|
|
|
|
|
|
|
|
: exchange ( seq i j -- )
|
|
|
|
|
#! Exchange seq[i] and seq[j].
|
2005-05-05 15:31:57 -04:00
|
|
|
[ (exchange) ] 3keep swap (exchange) set-nth set-nth ;
|
2005-04-16 00:23:27 -04:00
|
|
|
|
2005-04-15 23:00:22 -04:00
|
|
|
: (nreverse) ( seq i -- )
|
|
|
|
|
#! Swap seq[i] with seq[length-i-1].
|
2005-04-16 00:23:27 -04:00
|
|
|
over length over - 1 - exchange ;
|
2005-04-15 23:00:22 -04:00
|
|
|
|
|
|
|
|
: nreverse ( seq -- )
|
|
|
|
|
#! Destructively reverse seq.
|
|
|
|
|
dup length 2 /i [ 2dup (nreverse) ] repeat drop ;
|
|
|
|
|
|
2005-04-25 19:54:21 -04:00
|
|
|
M: object reverse ( seq -- seq ) [ nreverse ] immutable ;
|
|
|
|
|
|
2005-04-15 23:00:22 -04:00
|
|
|
! Equality testing
|
2005-04-11 23:05:05 -04:00
|
|
|
: length= ( seq seq -- ? ) length swap length number= ;
|
|
|
|
|
|
2005-04-12 13:35:27 -04:00
|
|
|
: (sequence=) ( seq seq i -- ? )
|
2005-04-14 01:32:06 -04:00
|
|
|
over length over number= [
|
2005-04-12 13:35:27 -04:00
|
|
|
3drop t
|
|
|
|
|
] [
|
|
|
|
|
3dup 2nth = [
|
|
|
|
|
1 + (sequence=)
|
|
|
|
|
] [
|
|
|
|
|
3drop f
|
|
|
|
|
] ifte
|
|
|
|
|
] ifte ;
|
|
|
|
|
|
|
|
|
|
: sequence= ( seq seq -- ? )
|
|
|
|
|
#! Check if two sequences have the same length and elements,
|
|
|
|
|
#! but not necessarily the same class.
|
2005-05-05 15:31:57 -04:00
|
|
|
over general-list? over general-list? or [
|
|
|
|
|
swap >list swap >list =
|
|
|
|
|
] [
|
|
|
|
|
2dup length= [ 0 (sequence=) ] [ 2drop f ] ifte
|
|
|
|
|
] ifte ;
|
2005-04-12 13:35:27 -04:00
|
|
|
|
2005-04-11 23:05:05 -04:00
|
|
|
M: sequence = ( obj seq -- ? )
|
|
|
|
|
2dup eq? [
|
|
|
|
|
2drop t
|
|
|
|
|
] [
|
|
|
|
|
over type over type eq? [
|
2005-04-12 13:35:27 -04:00
|
|
|
sequence=
|
2005-04-11 23:05:05 -04:00
|
|
|
] [
|
|
|
|
|
2drop f
|
|
|
|
|
] ifte
|
|
|
|
|
] ifte ;
|
2005-04-09 18:30:46 -04:00
|
|
|
|
2005-05-19 15:16:25 -04:00
|
|
|
! A repeated sequence is the same element n times.
|
|
|
|
|
TUPLE: repeated length object ;
|
|
|
|
|
M: repeated length repeated-length ;
|
|
|
|
|
M: repeated nth nip repeated-object ;
|
|
|
|
|
|
2005-04-06 21:41:49 -04:00
|
|
|
IN: kernel
|
|
|
|
|
|
|
|
|
|
: depth ( -- n )
|
|
|
|
|
#! Push the number of elements on the datastack.
|
|
|
|
|
datastack length ;
|