2008-03-20 21:14:07 -04:00
|
|
|
! Copyright (C) 2007, 2008 Mackenzie Straight, Doug Coleman,
|
|
|
|
! Slava Pestov.
|
2007-11-05 02:41:23 -05:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2008-08-19 15:06:20 -04:00
|
|
|
USING: combinators kernel math sequences accessors deques
|
2008-11-16 06:53:25 -05:00
|
|
|
search-deques summary hashtables ;
|
2007-11-05 02:41:23 -05:00
|
|
|
IN: dlists
|
|
|
|
|
2008-11-16 06:53:25 -05:00
|
|
|
<PRIVATE
|
2007-11-05 11:01:11 -05:00
|
|
|
|
2008-11-16 06:53:25 -05:00
|
|
|
MIXIN: ?dlist-node
|
2007-11-05 02:41:23 -05:00
|
|
|
|
2008-11-16 06:53:25 -05:00
|
|
|
INSTANCE: f ?dlist-node
|
2007-11-05 02:43:29 -05:00
|
|
|
|
2008-11-16 06:53:25 -05:00
|
|
|
TUPLE: dlist-node obj { prev ?dlist-node } { next ?dlist-node } ;
|
2008-03-20 21:14:07 -04:00
|
|
|
|
2008-11-16 06:53:25 -05:00
|
|
|
INSTANCE: dlist-node ?dlist-node
|
2008-03-20 21:14:07 -04:00
|
|
|
|
2007-11-05 02:41:23 -05:00
|
|
|
C: <dlist-node> dlist-node
|
|
|
|
|
2008-11-16 06:53:25 -05:00
|
|
|
PRIVATE>
|
2008-06-10 19:32:44 -04:00
|
|
|
|
2008-11-16 06:53:25 -05:00
|
|
|
TUPLE: dlist
|
|
|
|
{ front ?dlist-node }
|
|
|
|
{ back ?dlist-node } ;
|
2007-11-05 02:41:23 -05:00
|
|
|
|
2008-11-16 08:04:51 -05:00
|
|
|
: <dlist> ( -- list )
|
2008-11-16 06:53:25 -05:00
|
|
|
dlist new ; inline
|
|
|
|
|
|
|
|
: <hashed-dlist> ( -- search-deque )
|
|
|
|
20 <hashtable> <dlist> <search-deque> ;
|
|
|
|
|
|
|
|
M: dlist deque-empty? front>> not ;
|
|
|
|
|
|
|
|
M: dlist-node node-value obj>> ;
|
2007-11-05 02:41:23 -05:00
|
|
|
|
|
|
|
: set-prev-when ( dlist-node dlist-node/f -- )
|
2008-11-16 06:53:25 -05:00
|
|
|
[ (>>prev) ] [ drop ] if* ; inline
|
2007-11-05 02:41:23 -05:00
|
|
|
|
|
|
|
: set-next-when ( dlist-node dlist-node/f -- )
|
2008-11-16 06:53:25 -05:00
|
|
|
[ (>>next) ] [ drop ] if* ; inline
|
2007-11-05 02:41:23 -05:00
|
|
|
|
|
|
|
: set-next-prev ( dlist-node -- )
|
2008-11-16 06:53:25 -05:00
|
|
|
dup next>> set-prev-when ; inline
|
2007-11-05 02:41:23 -05:00
|
|
|
|
|
|
|
: normalize-front ( dlist -- )
|
2008-11-16 06:53:25 -05:00
|
|
|
dup back>> [ f >>front ] unless drop ; inline
|
2007-11-05 02:41:23 -05:00
|
|
|
|
|
|
|
: normalize-back ( dlist -- )
|
2008-11-16 06:53:25 -05:00
|
|
|
dup front>> [ f >>back ] unless drop ; inline
|
2007-11-05 02:41:23 -05:00
|
|
|
|
|
|
|
: set-back-to-front ( dlist -- )
|
2008-11-16 06:53:25 -05:00
|
|
|
dup back>> [ dup front>> >>back ] unless drop ; inline
|
2007-11-05 02:41:23 -05:00
|
|
|
|
|
|
|
: set-front-to-back ( dlist -- )
|
2008-11-16 06:53:25 -05:00
|
|
|
dup front>> [ dup back>> >>front ] unless drop ; inline
|
2007-11-05 02:43:29 -05:00
|
|
|
|
2008-07-18 20:22:59 -04:00
|
|
|
: (dlist-find-node) ( dlist-node quot: ( node -- ? ) -- node/f ? )
|
2008-03-20 21:14:07 -04:00
|
|
|
over [
|
2008-05-25 19:28:07 -04:00
|
|
|
[ call ] 2keep rot
|
2008-11-29 14:29:19 -05:00
|
|
|
[ drop t ] [ [ next>> ] dip (dlist-find-node) ] if
|
2008-07-18 20:22:59 -04:00
|
|
|
] [ 2drop f f ] if ; inline recursive
|
2007-11-05 02:43:29 -05:00
|
|
|
|
2008-03-20 21:14:07 -04:00
|
|
|
: dlist-find-node ( dlist quot -- node/f ? )
|
2008-11-29 14:29:19 -05:00
|
|
|
[ front>> ] dip (dlist-find-node) ; inline
|
2007-11-05 02:43:29 -05:00
|
|
|
|
2008-03-20 21:14:07 -04:00
|
|
|
: dlist-each-node ( dlist quot -- )
|
2008-05-25 19:28:07 -04:00
|
|
|
[ f ] compose dlist-find-node 2drop ; inline
|
2007-11-05 02:43:29 -05:00
|
|
|
|
2008-06-10 19:32:44 -04:00
|
|
|
: unlink-node ( dlist-node -- )
|
|
|
|
dup prev>> over next>> set-prev-when
|
2008-11-16 06:53:25 -05:00
|
|
|
dup next>> swap prev>> set-next-when ; inline
|
2008-06-10 19:32:44 -04:00
|
|
|
|
2007-11-05 02:41:23 -05:00
|
|
|
PRIVATE>
|
|
|
|
|
2008-06-10 19:32:44 -04:00
|
|
|
M: dlist push-front* ( obj dlist -- dlist-node )
|
2008-03-20 21:14:07 -04:00
|
|
|
[ front>> f swap <dlist-node> dup dup set-next-prev ] keep
|
|
|
|
[ (>>front) ] keep
|
2008-11-16 06:53:25 -05:00
|
|
|
set-back-to-front ;
|
2007-11-05 02:41:23 -05:00
|
|
|
|
2008-06-10 19:32:44 -04:00
|
|
|
M: dlist push-back* ( obj dlist -- dlist-node )
|
2008-03-20 21:14:07 -04:00
|
|
|
[ back>> f <dlist-node> ] keep
|
|
|
|
[ back>> set-next-when ] 2keep
|
|
|
|
[ (>>back) ] 2keep
|
2008-11-16 06:53:25 -05:00
|
|
|
set-front-to-back ;
|
2008-01-31 01:52:06 -05:00
|
|
|
|
2008-05-25 21:43:17 -04:00
|
|
|
ERROR: empty-dlist ;
|
|
|
|
|
2008-07-30 05:12:17 -04:00
|
|
|
M: empty-dlist summary ( dlist -- )
|
|
|
|
drop "Empty dlist" ;
|
|
|
|
|
2008-06-10 19:32:44 -04:00
|
|
|
M: dlist peek-front ( dlist -- obj )
|
|
|
|
front>> [ obj>> ] [ empty-dlist ] if* ;
|
2008-01-31 01:52:06 -05:00
|
|
|
|
2008-06-10 19:32:44 -04:00
|
|
|
M: dlist pop-front* ( dlist -- )
|
2008-05-25 21:43:17 -04:00
|
|
|
[
|
2008-11-16 06:53:25 -05:00
|
|
|
dup front>> [ empty-dlist ] unless*
|
2008-03-20 21:14:07 -04:00
|
|
|
dup next>>
|
|
|
|
f rot (>>next)
|
2007-11-05 02:41:23 -05:00
|
|
|
f over set-prev-when
|
2008-03-20 21:14:07 -04:00
|
|
|
swap (>>front)
|
2008-06-10 19:32:44 -04:00
|
|
|
] keep
|
2008-11-16 06:53:25 -05:00
|
|
|
normalize-back ;
|
2007-11-05 02:41:23 -05:00
|
|
|
|
2008-06-10 19:32:44 -04:00
|
|
|
M: dlist peek-back ( dlist -- obj )
|
|
|
|
back>> [ obj>> ] [ empty-dlist ] if* ;
|
2007-11-05 02:41:23 -05:00
|
|
|
|
2008-06-10 19:32:44 -04:00
|
|
|
M: dlist pop-back* ( dlist -- )
|
2008-05-25 21:43:17 -04:00
|
|
|
[
|
2008-11-16 06:53:25 -05:00
|
|
|
dup back>> [ empty-dlist ] unless*
|
2008-03-20 21:14:07 -04:00
|
|
|
dup prev>>
|
|
|
|
f rot (>>prev)
|
2008-01-23 05:31:30 -05:00
|
|
|
f over set-next-when
|
2008-03-20 21:14:07 -04:00
|
|
|
swap (>>back)
|
2008-06-10 19:32:44 -04:00
|
|
|
] keep
|
2008-11-16 06:53:25 -05:00
|
|
|
normalize-front ;
|
2007-11-05 02:41:23 -05:00
|
|
|
|
2008-03-20 21:14:07 -04:00
|
|
|
: dlist-find ( dlist quot -- obj/f ? )
|
2008-05-25 19:28:07 -04:00
|
|
|
[ obj>> ] prepose
|
2008-03-20 21:14:07 -04:00
|
|
|
dlist-find-node [ obj>> t ] [ drop f f ] if ; inline
|
2007-11-05 02:41:23 -05:00
|
|
|
|
2008-03-20 21:14:07 -04:00
|
|
|
: dlist-contains? ( dlist quot -- ? )
|
2007-11-15 17:21:45 -05:00
|
|
|
dlist-find nip ; inline
|
2007-11-05 02:41:23 -05:00
|
|
|
|
2008-08-19 15:06:20 -04:00
|
|
|
M: dlist deque-member? ( value dlist -- ? )
|
2008-07-28 18:55:41 -04:00
|
|
|
[ = ] with dlist-contains? ;
|
2007-11-16 00:17:34 -05:00
|
|
|
|
2008-06-10 19:32:44 -04:00
|
|
|
M: dlist delete-node ( dlist-node dlist -- )
|
2007-11-05 02:41:23 -05:00
|
|
|
{
|
2008-06-10 19:32:44 -04:00
|
|
|
{ [ 2dup front>> eq? ] [ nip pop-front* ] }
|
|
|
|
{ [ 2dup back>> eq? ] [ nip pop-back* ] }
|
2008-11-16 06:53:25 -05:00
|
|
|
[ drop unlink-node ]
|
2007-11-05 02:41:23 -05:00
|
|
|
} cond ;
|
|
|
|
|
2008-03-20 21:14:07 -04:00
|
|
|
: delete-node-if* ( dlist quot -- obj/f ? )
|
|
|
|
dupd dlist-find-node [
|
|
|
|
dup [
|
2008-06-10 19:32:44 -04:00
|
|
|
[ swap delete-node ] keep obj>> t
|
2008-03-20 21:14:07 -04:00
|
|
|
] [
|
|
|
|
2drop f f
|
|
|
|
] if
|
2007-11-05 02:41:23 -05:00
|
|
|
] [
|
2007-11-05 02:43:29 -05:00
|
|
|
2drop f f
|
2007-11-15 17:21:45 -05:00
|
|
|
] if ; inline
|
2007-11-05 02:41:23 -05:00
|
|
|
|
2008-03-20 21:14:07 -04:00
|
|
|
: delete-node-if ( dlist quot -- obj/f )
|
2008-06-10 19:32:44 -04:00
|
|
|
[ obj>> ] prepose delete-node-if* drop ; inline
|
2007-11-15 21:44:10 -05:00
|
|
|
|
2008-08-19 15:06:20 -04:00
|
|
|
M: dlist clear-deque ( dlist -- )
|
2008-03-20 21:14:07 -04:00
|
|
|
f >>front
|
|
|
|
f >>back
|
|
|
|
drop ;
|
2008-02-06 20:23:39 -05:00
|
|
|
|
2007-11-05 02:41:23 -05:00
|
|
|
: dlist-each ( dlist quot -- )
|
2008-04-26 00:12:44 -04:00
|
|
|
[ obj>> ] prepose dlist-each-node ; inline
|
2007-11-05 11:01:11 -05:00
|
|
|
|
2008-11-11 11:56:58 -05:00
|
|
|
: dlist>seq ( dlist -- seq )
|
2008-11-29 21:15:04 -05:00
|
|
|
[ drop t ] pusher [ dlist-each ] dip ;
|
2008-11-11 11:56:58 -05:00
|
|
|
|
2008-02-12 12:58:47 -05:00
|
|
|
: 1dlist ( obj -- dlist ) <dlist> [ push-front ] keep ;
|
2008-06-10 19:32:44 -04:00
|
|
|
|
2008-11-11 11:56:58 -05:00
|
|
|
M: dlist clone
|
|
|
|
<dlist> [
|
|
|
|
[ push-back ] curry dlist-each
|
|
|
|
] keep ;
|
|
|
|
|
2008-08-19 15:06:20 -04:00
|
|
|
INSTANCE: dlist deque
|