factor/library/collections/sequences-epilogue.factor

201 lines
5.1 KiB
Factor
Raw Normal View History

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.
! 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
M: object thaw clone ;
2005-04-19 20:28:01 -04:00
M: object freeze drop ;
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) ;
M: general-list >list ( list -- list ) ;
2005-04-02 02:39:33 -05:00
: 2nth ( s s n -- x x ) tuck swap nth >r swap nth r> ;
! Combinators
2005-04-11 23:05:05 -04:00
GENERIC: (seq-each) ( quot seq -- ) inline
M: object (seq-each) ( quot seq -- )
dup length [ [ swap nth swap call ] 3keep ] repeat 2drop ;
2005-04-11 23:05:05 -04:00
M: general-list (seq-each) ( quot seq -- )
swap each ;
: seq-each ( seq quot -- ) swap (seq-each) ; inline
2005-04-02 02:39:33 -05:00
: seq-each-with ( obj seq quot -- )
swap [ with ] seq-each 2drop ; inline
2005-04-11 23:05:05 -04:00
GENERIC: (tree-each) ( quot obj -- ) inline
2005-04-11 23:05:05 -04:00
M: object (tree-each) swap call ;
2005-04-11 23:05:05 -04:00
M: cons (tree-each) [ car (tree-each) ] 2keep cdr (tree-each) ;
2005-04-11 23:05:05 -04:00
M: f (tree-each) swap call ;
2005-04-24 20:57:37 -04:00
M: sequence (tree-each) [ (tree-each) ] seq-each-with ;
2005-04-11 23:05:05 -04:00
: tree-each swap (tree-each) ; inline
2005-04-11 23:05:05 -04:00
: tree-each-with ( obj vector quot -- )
swap [ with ] tree-each 2drop ; inline
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
] [
[ 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 -- )
swap [ thaw ] keep >r dup >r swap call r> r> freeze ; inline
2005-04-17 21:59:11 -04:00
: seq-map ( seq quot -- seq | quot: elt -- elt )
swap [ swap nmap ] immutable ; inline
2005-04-30 02:01:04 -04:00
: seq-map-with ( obj list quot -- list )
swap [ with rot ] seq-map 2nip ; inline
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
: seq-2map ( seq1 seq2 quot -- seq | quot: elt1 elt2 -- elt3 )
2005-04-30 02:01:04 -04:00
swap [ swap 2nmap ] immutable ; inline
2005-04-11 23:05:05 -04:00
! Operations
2005-04-11 23:05:05 -04:00
: index* ( obj i seq -- n )
#! The index of the object in the sequence, starting from i.
2005-05-05 16:51:38 -04:00
2dup length >= [
3drop -1
] [
3dup nth = [ drop nip ] [ >r 1 + r> index* ] ifte
] 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.
0 swap index* ;
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 ;
: nappend ( s1 s2 -- )
2005-04-06 21:41:49 -04:00
#! Destructively append s2 to s1.
[ over push ] seq-each drop ;
: append ( s1 s2 -- s1+s2 )
2005-04-17 21:59:11 -04:00
#! Return a new sequence of the same type as s1.
swap [ swap nappend ] immutable ;
: 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 ;
: concat ( seq -- seq )
#! Append together a sequence of sequences.
dup empty? [
unswons [ swap [ nappend ] seq-each-with ] immutable
] unless ;
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].
[ (exchange) ] 3keep swap (exchange) set-nth set-nth ;
2005-04-16 00:23:27 -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 ;
: nreverse ( seq -- )
#! Destructively reverse seq.
dup length 2 /i [ 2dup (nreverse) ] repeat drop ;
M: object reverse ( seq -- seq ) [ nreverse ] immutable ;
! Equality testing
2005-04-11 23:05:05 -04:00
: length= ( seq seq -- ? ) length swap length number= ;
: (sequence=) ( seq seq i -- ? )
2005-04-14 01:32:06 -04:00
over length over number= [
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.
over general-list? over general-list? or [
swap >list swap >list =
] [
2dup length= [ 0 (sequence=) ] [ 2drop f ] ifte
] ifte ;
2005-04-11 23:05:05 -04:00
M: sequence = ( obj seq -- ? )
2dup eq? [
2drop t
] [
over type over type eq? [
sequence=
2005-04-11 23:05:05 -04:00
] [
2drop f
] ifte
] ifte ;
2005-04-09 18:30:46 -04:00
2005-04-17 21:59:11 -04:00
! A repeated sequence is the same element n times.
2005-04-19 20:28:01 -04:00
TUPLE: repeated length object ;
2005-04-17 21:59:11 -04:00
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 ;