factor/basis/cords/cords.factor

71 lines
1.7 KiB
Factor

! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs sequences sorting binary-search math
math.order arrays combinators kernel ;
IN: cords
<PRIVATE
TUPLE: simple-cord first second ;
M: simple-cord length
[ first>> length ] [ second>> length ] bi + ;
M: simple-cord virtual-seq first>> ;
M: simple-cord virtual@
2dup first>> length <
[ first>> ] [ [ first>> length - ] [ second>> ] bi ] if ;
TUPLE: multi-cord count seqs ;
M: multi-cord length count>> ;
M: multi-cord virtual@
dupd
seqs>> [ first <=> ] with search nip
[ first - ] [ second ] bi ;
M: multi-cord virtual-seq
seqs>> [ f ] [ first second ] if-empty ;
: <cord> ( seqs -- cord )
dup length 2 = [
first2 simple-cord boa
] [
[ 0 [ length + ] accumulate ] keep zip multi-cord boa
] if ;
PRIVATE>
UNION: cord simple-cord multi-cord ;
INSTANCE: cord virtual-sequence
INSTANCE: multi-cord virtual-sequence
: cord-append ( seq1 seq2 -- cord )
{
{ [ over empty? ] [ nip ] }
{ [ dup empty? ] [ drop ] }
{ [ 2dup [ cord? ] both? ] [ [ seqs>> values ] bi@ append <cord> ] }
{ [ over cord? ] [ [ seqs>> values ] dip suffix <cord> ] }
{ [ dup cord? ] [ seqs>> values swap prefix <cord> ] }
[ 2array <cord> ]
} cond ;
: cord-concat ( seqs -- cord )
{
{ [ dup empty? ] [ drop f ] }
{ [ dup length 1 = ] [ first ] }
[
[
{
{ [ dup cord? ] [ seqs>> values ] }
{ [ dup empty? ] [ drop { } ] }
[ 1array ]
} cond
] map concat <cord>
]
} cond ;