| 
									
										
										
										
											2009-04-02 10:09:09 -04:00
										 |  |  | ! Copyright (C) 2007, 2009 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2008-09-10 21:07:00 -04:00
										 |  |  | USING: accessors namespaces make sequences kernel math arrays io | 
					
						
							| 
									
										
										
										
											2009-04-02 10:09:09 -04:00
										 |  |  | ui.gadgets generic combinators fry sets ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: ui.traverse | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: node value children ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : traverse-step ( path gadget -- path' gadget' )
 | 
					
						
							| 
									
										
										
										
											2008-11-26 00:04:34 -05:00
										 |  |  |     [ unclip ] dip children>> ?nth ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:27 -04:00
										 |  |  | : make-node ( quot -- ) { } make node boa , ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : traverse-to-path ( topath gadget -- )
 | 
					
						
							|  |  |  |     dup not [ | 
					
						
							|  |  |  |         2drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         over empty? [ | 
					
						
							|  |  |  |             nip , | 
					
						
							|  |  |  |         ] [ | 
					
						
							|  |  |  |             [ | 
					
						
							| 
									
										
										
										
											2009-01-25 18:55:27 -05:00
										 |  |  |                 [ children>> swap first head-slice % ] | 
					
						
							|  |  |  |                 [ tuck traverse-step traverse-to-path ] | 
					
						
							|  |  |  |                 2bi
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |             ] make-node | 
					
						
							|  |  |  |         ] if
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : traverse-from-path ( frompath gadget -- )
 | 
					
						
							|  |  |  |     dup not [ | 
					
						
							|  |  |  |         2drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         over empty? [ | 
					
						
							|  |  |  |             nip , | 
					
						
							|  |  |  |         ] [ | 
					
						
							|  |  |  |             [ | 
					
						
							| 
									
										
										
										
											2009-01-25 18:55:27 -05:00
										 |  |  |                 [ traverse-step traverse-from-path ] | 
					
						
							|  |  |  |                 [ tuck children>> swap first 1+ tail-slice % ] 2bi
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |             ] make-node | 
					
						
							|  |  |  |         ] if
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : traverse-pre ( frompath gadget -- )
 | 
					
						
							|  |  |  |     traverse-step traverse-from-path ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (traverse-middle) ( frompath topath gadget -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-26 00:04:34 -05:00
										 |  |  |     [ first 1+ ] [ first ] [ children>> ] tri* <slice> % ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : traverse-post ( topath gadget -- )
 | 
					
						
							|  |  |  |     traverse-step traverse-to-path ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : traverse-middle ( frompath topath gadget -- )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         3dup nip traverse-pre | 
					
						
							|  |  |  |         3dup (traverse-middle) | 
					
						
							|  |  |  |         2dup traverse-post | 
					
						
							|  |  |  |         2nip
 | 
					
						
							|  |  |  |     ] make-node ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DEFER: (gadget-subtree) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : traverse-child ( frompath topath gadget -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-30 18:47:29 -05:00
										 |  |  |     [ 2nip ] 3keep
 | 
					
						
							|  |  |  |     [ [ rest-slice ] 2dip traverse-step (gadget-subtree) ] | 
					
						
							|  |  |  |     make-node ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (gadget-subtree) ( frompath topath gadget -- )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { [ dup not ] [ 3drop ] } | 
					
						
							|  |  |  |         { [ pick empty? pick empty? and ] [ 2nip , ] } | 
					
						
							| 
									
										
										
										
											2008-11-30 18:47:29 -05:00
										 |  |  |         { [ pick empty? ] [ traverse-to-path drop ] } | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         { [ over empty? ] [ nip traverse-from-path ] } | 
					
						
							|  |  |  |         { [ pick first pick first = ] [ traverse-child ] } | 
					
						
							| 
									
										
										
										
											2008-04-11 13:54:33 -04:00
										 |  |  |         [ traverse-middle ] | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : gadget-subtree ( frompath topath gadget -- seq )
 | 
					
						
							|  |  |  |     [ (gadget-subtree) ] { } make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: node gadget-text* | 
					
						
							| 
									
										
										
										
											2009-02-02 01:02:55 -05:00
										 |  |  |     [ children>> ] [ value>> ] bi gadget-seq-text ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : gadget-text-range ( frompath topath gadget -- str )
 | 
					
						
							|  |  |  |     gadget-subtree gadget-text ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : gadget-at-path ( parent path -- gadget )
 | 
					
						
							|  |  |  |     [ swap nth-gadget ] each ;
 | 
					
						
							| 
									
										
										
										
											2009-04-02 10:09:09 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | GENERIC# leaves* 1 ( tree assoc -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: node leaves* [ children>> ] dip leaves* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: array leaves* '[ _ leaves* ] each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: gadget leaves* conjoin ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : leaves ( tree -- assoc ) H{ } clone [ leaves* ] keep ;
 |