| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  | ! Copyright (C) 2004, 2009 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | USING: classes classes.union words kernel sequences | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  | definitions combinators arrays assocs generic accessors ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: classes.mixin | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 19:23:19 -04:00
										 |  |  | PREDICATE: mixin-class < union-class "mixin" word-prop ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: mixin-class reset-class | 
					
						
							| 
									
										
										
										
											2008-06-25 04:25:08 -04:00
										 |  |  |     [ call-next-method ] [ { "mixin" } reset-props ] bi ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-02 03:51:38 -04:00
										 |  |  | M: mixin-class rank-class drop 3 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : redefine-mixin-class ( class members -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     [ (define-union-class) ] | 
					
						
							|  |  |  |     [ drop t "mixin" set-word-prop ] | 
					
						
							|  |  |  |     2bi ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : define-mixin-class ( class -- )
 | 
					
						
							|  |  |  |     dup mixin-class? [ | 
					
						
							|  |  |  |         drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-08-28 23:28:34 -04:00
										 |  |  |         [ { } redefine-mixin-class ] | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  |         [ H{ } clone "instances" set-word-prop ] | 
					
						
							| 
									
										
										
										
											2008-08-28 23:28:34 -04:00
										 |  |  |         [ update-classes ] | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  |         tri
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 10:33:32 -05:00
										 |  |  | TUPLE: check-mixin-class class ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : check-mixin-class ( mixin -- mixin )
 | 
					
						
							|  |  |  |     dup mixin-class? [ | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |         \ check-mixin-class boa throw
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  |     ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : if-mixin-member? ( class mixin true false -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     [ check-mixin-class 2dup members memq? ] 2dip if ; inline
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : change-mixin-class ( class mixin quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     [ [ members swap bootstrap-word ] dip call ] [ drop ] 2bi
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  |     swap redefine-mixin-class ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-30 03:31:27 -04:00
										 |  |  | : update-classes/new ( mixin -- )
 | 
					
						
							|  |  |  |     class-usages | 
					
						
							|  |  |  |     [ [ update-class ] each ] | 
					
						
							| 
									
										
										
										
											2008-11-03 04:51:28 -05:00
										 |  |  |     [ implementors [ remake-generic ] each ] bi ;
 | 
					
						
							| 
									
										
										
										
											2008-08-30 03:31:27 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  | : (add-mixin-instance) ( class mixin -- )
 | 
					
						
							|  |  |  |     [ [ suffix ] change-mixin-class ] | 
					
						
							|  |  |  |     [ [ f ] 2dip "instances" word-prop set-at ] | 
					
						
							|  |  |  |     2bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-28 18:56:15 -04:00
										 |  |  | GENERIC# add-mixin-instance 1 ( class mixin -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: class add-mixin-instance | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     #! Note: we call update-classes on the new member, not the | 
					
						
							|  |  |  |     #! mixin. This ensures that we only have to update the | 
					
						
							|  |  |  |     #! methods whose specializer intersects the new member, not | 
					
						
							|  |  |  |     #! the entire mixin (since the other mixin members are not | 
					
						
							|  |  |  |     #! affected at all). Also, all usages of the mixin will get | 
					
						
							|  |  |  |     #! updated by transitivity; the mixins usages appear in | 
					
						
							|  |  |  |     #! class-usages of the member, now that it's been added. | 
					
						
							|  |  |  |     [ 2drop ] [ | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  |         [ (add-mixin-instance) ] 2keep
 | 
					
						
							|  |  |  |         [ nip ] [ [ new-class? ] either? ] 2bi
 | 
					
						
							|  |  |  |         [ update-classes/new ] [ update-classes ] if
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     ] if-mixin-member? ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  | : (remove-mixin-instance) ( class mixin -- )
 | 
					
						
							|  |  |  |     [ [ swap remove ] change-mixin-class ] | 
					
						
							|  |  |  |     [ "instances" word-prop delete-at ] | 
					
						
							|  |  |  |     2bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | : remove-mixin-instance ( class mixin -- )
 | 
					
						
							| 
									
										
										
										
											2008-09-03 18:24:06 -04:00
										 |  |  |     #! The order of the three clauses is important here. The last | 
					
						
							|  |  |  |     #! one must come after the other two so that the entries it | 
					
						
							|  |  |  |     #! adds to changed-generics are not overwritten. | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  |         [ (remove-mixin-instance) ] | 
					
						
							| 
									
										
										
										
											2008-08-31 02:34:00 -04:00
										 |  |  |         [ nip update-classes ] | 
					
						
							| 
									
										
										
										
											2008-09-03 18:24:06 -04:00
										 |  |  |         [ class-usages update-methods ] | 
					
						
							| 
									
										
										
										
											2008-08-31 02:34:00 -04:00
										 |  |  |         2tri
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  |     ] [ 2drop ] if-mixin-member? ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-04 02:32:11 -04:00
										 |  |  | M: mixin-class class-forgotten remove-mixin-instance ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | ! Definition protocol implementation ensures that removing an | 
					
						
							|  |  |  | ! INSTANCE: declaration from a source file updates the mixin. | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  | TUPLE: mixin-instance class mixin ;
 | 
					
						
							| 
									
										
										
										
											2008-01-05 19:37:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  | C: <mixin-instance> mixin-instance | 
					
						
							| 
									
										
										
										
											2008-01-05 21:06:01 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  | : >mixin-instance< ( mixin-instance -- class mixin )
 | 
					
						
							|  |  |  |     [ class>> ] [ mixin>> ] bi ; inline
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  | M: mixin-instance where >mixin-instance< "instances" word-prop at ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  | M: mixin-instance set-where >mixin-instance< "instances" word-prop set-at ;
 | 
					
						
							| 
									
										
										
										
											2008-01-04 21:10:49 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: mixin-instance definer drop \ INSTANCE: f ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: mixin-instance definition drop f ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-09 16:51:55 -05:00
										 |  |  | M: mixin-instance forget* | 
					
						
							| 
									
										
										
										
											2009-03-16 01:04:34 -04:00
										 |  |  |     >mixin-instance< | 
					
						
							| 
									
										
										
										
											2008-08-31 08:55:34 -04:00
										 |  |  |     dup mixin-class? [ remove-mixin-instance ] [ 2drop ] if ;
 |