factor/extra/cursors/cursors.factor

154 lines
4.6 KiB
Factor
Raw Normal View History

2009-05-30 13:13:17 -04:00
! Copyright (C) 2009 Slava Pestov, Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
2009-06-10 17:59:14 -04:00
USING: accessors arrays generalizations kernel math sequences
2009-06-22 12:55:42 -04:00
sequences.private fry ;
2009-05-30 13:13:17 -04:00
IN: cursors
GENERIC: cursor-done? ( cursor -- ? )
GENERIC: cursor-get-unsafe ( cursor -- obj )
GENERIC: cursor-advance ( cursor -- )
GENERIC: cursor-valid? ( cursor -- ? )
GENERIC: cursor-write ( obj cursor -- )
ERROR: cursor-ended cursor ;
: cursor-get ( cursor -- obj )
2009-05-31 09:53:42 -04:00
dup cursor-done?
[ cursor-ended ] [ cursor-get-unsafe ] if ; inline
2009-05-30 13:13:17 -04:00
2009-05-31 09:53:42 -04:00
: find-done? ( cursor quot -- ? )
over cursor-done?
[ 2drop t ] [ [ cursor-get-unsafe ] dip call ] if ; inline
2009-05-30 13:13:17 -04:00
2009-05-31 09:53:42 -04:00
: cursor-until ( cursor quot -- )
[ find-done? not ]
[ drop cursor-advance ] bi-curry bi-curry while ; inline
2009-05-30 13:13:17 -04:00
: cursor-each ( cursor quot -- )
2009-05-31 09:53:42 -04:00
[ f ] compose cursor-until ; inline
2009-05-30 13:13:17 -04:00
: cursor-find ( cursor quot -- obj ? )
2009-05-31 09:53:42 -04:00
[ cursor-until ] [ drop ] 2bi
dup cursor-done? [ drop f f ] [ cursor-get t ] if ; inline
2009-05-30 13:13:17 -04:00
: cursor-any? ( cursor quot -- ? )
2009-05-31 09:53:42 -04:00
cursor-find nip ; inline
2009-05-30 13:13:17 -04:00
: cursor-all? ( cursor quot -- ? )
2009-05-31 09:53:42 -04:00
[ not ] compose cursor-any? not ; inline
2009-05-30 13:13:17 -04:00
: cursor-map-quot ( quot to -- quot' )
2009-05-31 09:53:42 -04:00
[ [ call ] dip cursor-write ] 2curry ; inline
2009-05-30 13:13:17 -04:00
: cursor-map ( from to quot -- )
2009-06-10 17:59:14 -04:00
swap cursor-map-quot cursor-each ; inline
2009-05-30 13:13:17 -04:00
: cursor-write-if ( obj quot to -- )
[ over [ call ] dip ] dip
[ cursor-write ] 2curry when ; inline
: cursor-filter-quot ( quot to -- quot' )
2009-05-31 09:53:42 -04:00
[ cursor-write-if ] 2curry ; inline
2009-05-30 13:13:17 -04:00
: cursor-filter ( from to quot -- )
2009-05-31 09:53:42 -04:00
swap cursor-filter-quot cursor-each ; inline
2009-05-30 13:13:17 -04:00
TUPLE: from-sequence { seq sequence } { n integer } ;
: >from-sequence< ( from-sequence -- n seq )
[ n>> ] [ seq>> ] bi ; inline
M: from-sequence cursor-done? ( cursor -- ? )
>from-sequence< length >= ;
M: from-sequence cursor-valid?
2009-05-31 09:53:42 -04:00
>from-sequence< bounds-check? not ;
2009-05-30 13:13:17 -04:00
M: from-sequence cursor-get-unsafe
2009-05-31 09:53:42 -04:00
>from-sequence< nth-unsafe ;
2009-05-30 13:13:17 -04:00
M: from-sequence cursor-advance
[ 1 + ] change-n drop ;
2009-05-30 13:13:17 -04:00
: >input ( seq -- cursor )
2009-05-31 09:53:42 -04:00
0 from-sequence boa ; inline
2009-05-30 13:13:17 -04:00
: iterate ( seq quot iterator -- )
2009-05-31 09:53:42 -04:00
[ >input ] 2dip call ; inline
2009-05-30 13:13:17 -04:00
: each ( seq quot -- ) [ cursor-each ] iterate ; inline
: find ( seq quot -- ? ) [ cursor-find ] iterate ; inline
: any? ( seq quot -- ? ) [ cursor-any? ] iterate ; inline
: all? ( seq quot -- ? ) [ cursor-all? ] iterate ; inline
TUPLE: to-sequence { seq sequence } { exemplar sequence } ;
M: to-sequence cursor-write
2009-05-31 09:53:42 -04:00
seq>> push ;
2009-05-30 13:13:17 -04:00
: freeze ( cursor -- seq )
2009-05-31 09:53:42 -04:00
[ seq>> ] [ exemplar>> ] bi like ; inline
2009-05-30 13:13:17 -04:00
: >output ( seq -- cursor )
2009-05-31 09:53:42 -04:00
[ [ length ] keep new-resizable ] keep
to-sequence boa ; inline
2009-05-30 13:13:17 -04:00
: transform ( seq quot transformer -- newseq )
2009-05-31 09:53:42 -04:00
[ [ >input ] [ >output ] bi ] 2dip
[ call ]
[ 2drop freeze ] 3bi ; inline
2009-05-30 13:13:17 -04:00
: map ( seq quot -- ) [ cursor-map ] transform ; inline
: filter ( seq quot -- newseq ) [ cursor-filter ] transform ; inline
2009-06-10 17:59:14 -04:00
: find-done2? ( cursor cursor quot -- ? )
2over [ cursor-done? ] either?
[ 3drop t ] [ [ [ cursor-get-unsafe ] bi@ ] dip call ] if ; inline
: cursor-until2 ( cursor cursor quot -- )
[ find-done2? not ]
[ drop [ cursor-advance ] bi@ ] bi-curry bi-curry bi-curry while ; inline
: cursor-each2 ( cursor cursor quot -- )
[ f ] compose cursor-until2 ; inline
: cursor-map2 ( from to quot -- )
swap cursor-map-quot cursor-each2 ; inline
: iterate2 ( seq1 seq2 quot iterator -- )
[ [ >input ] bi@ ] 2dip call ; inline
: transform2 ( seq1 seq2 quot transformer -- newseq )
[ over >output [ [ >input ] [ >input ] bi* ] dip ] 2dip
[ call ]
[ 2drop nip freeze ] 4 nbi ; inline
: 2each ( seq1 seq2 quot -- ) [ cursor-each2 ] iterate2 ; inline
: 2map ( seq1 seq2 quot -- ) [ cursor-map2 ] transform2 ; inline
: find-done3? ( cursor1 cursor2 cursor3 quot -- ? )
2009-06-22 12:55:42 -04:00
[ 3 ndrop t ] swap '[ [ cursor-get-unsafe ] tri@ @ ]
[ 3 ndup 3 narray [ cursor-done? ] any? ] 2dip if ; inline
2009-06-10 17:59:14 -04:00
: cursor-until3 ( cursor cursor quot -- )
[ find-done3? not ]
2009-06-22 12:55:42 -04:00
[ drop [ cursor-advance ] tri@ ]
bi-curry bi-curry bi-curry bi-curry while ; inline
2009-06-10 17:59:14 -04:00
: cursor-each3 ( cursor cursor quot -- )
[ f ] compose cursor-until3 ; inline
: cursor-map3 ( from to quot -- )
swap cursor-map-quot cursor-each3 ; inline
: iterate3 ( seq1 seq2 seq3 quot iterator -- )
[ [ >input ] tri@ ] 2dip call ; inline
: transform3 ( seq1 seq2 seq3 quot transformer -- newseq )
[ pick >output [ [ >input ] [ >input ] [ >input ] tri* ] dip ] 2dip
[ call ]
[ 2drop 2nip freeze ] 5 nbi ; inline
: 3each ( seq1 seq2 seq3 quot -- ) [ cursor-each3 ] iterate3 ; inline
: 3map ( seq1 seq2 seq3 quot -- ) [ cursor-map3 ] transform3 ; inline