| 
									
										
										
										
											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-07-30 05:12:17 -04:00
										 |  |  | summary ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | IN: dlists | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: dlist front back length ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 11:01:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | : <dlist> ( -- obj )
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |     dlist new
 | 
					
						
							| 
									
										
										
										
											2008-06-10 19:32:44 -04:00
										 |  |  |         0 >>length ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-19 15:06:20 -04:00
										 |  |  | M: dlist deque-length length>> ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:43:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | <PRIVATE
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | TUPLE: dlist-node obj prev next ;
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | C: <dlist-node> dlist-node | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-10 19:32:44 -04:00
										 |  |  | M: dlist-node node-value obj>> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | : inc-length ( dlist -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  |     [ 1+ ] change-length drop ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : dec-length ( dlist -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  |     [ 1- ] change-length drop ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : set-prev-when ( dlist-node dlist-node/f -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  |     [ (>>prev) ] [ drop ] if* ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : set-next-when ( dlist-node dlist-node/f -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  |     [ (>>next) ] [ drop ] if* ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : set-next-prev ( dlist-node -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  |     dup next>> set-prev-when ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : normalize-front ( dlist -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  |     dup back>> [ f >>front ] unless drop ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : normalize-back ( dlist -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  |     dup front>> [ f >>back ] unless drop ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : set-back-to-front ( dlist -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  |     dup back>> [ dup front>> >>back ] unless drop ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : set-front-to-back ( dlist -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:14:07 -04:00
										 |  |  |     dup front>> [ dup back>> >>front ] unless drop ;
 | 
					
						
							| 
									
										
										
										
											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-03-20 21:14:07 -04:00
										 |  |  |         [ drop t ] [ >r next>> r> (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 ? )
 | 
					
						
							|  |  |  |     >r front>> r> (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 | 
					
						
							|  |  |  |     dup next>> swap prev>> set-next-when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:41:23 -05:00
										 |  |  |     [ set-back-to-front ] keep
 | 
					
						
							|  |  |  |     inc-length ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-01-31 01:52:06 -05:00
										 |  |  |     [ set-front-to-back ] keep
 | 
					
						
							|  |  |  |     inc-length ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 -- )
 | 
					
						
							|  |  |  |     dup front>> [ empty-dlist ] unless
 | 
					
						
							| 
									
										
										
										
											2008-05-25 21:43:17 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-06-10 19:32:44 -04:00
										 |  |  |         dup front>> | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							|  |  |  |     [ normalize-back ] keep
 | 
					
						
							|  |  |  |     dec-length ;
 | 
					
						
							| 
									
										
										
										
											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 -- )
 | 
					
						
							|  |  |  |     dup back>> [ empty-dlist ] unless
 | 
					
						
							| 
									
										
										
										
											2008-05-25 21:43:17 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-06-10 19:32:44 -04:00
										 |  |  |         dup back>> | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							|  |  |  |     [ normalize-front ] keep
 | 
					
						
							|  |  |  |     dec-length ;
 | 
					
						
							| 
									
										
										
										
											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* ] } | 
					
						
							|  |  |  |         [ dec-length 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 | 
					
						
							|  |  |  |     0 >>length | 
					
						
							|  |  |  |     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-02-12 12:58:47 -05:00
										 |  |  | : 1dlist ( obj -- dlist ) <dlist> [ push-front ] keep ;
 | 
					
						
							| 
									
										
										
										
											2008-06-10 19:32:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-19 15:06:20 -04:00
										 |  |  | INSTANCE: dlist deque |