| 
									
										
										
										
											2008-02-04 20:38:31 -05:00
										 |  |  | ! Copyright (C) 2006, 2008 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | USING: words kernel sequences namespaces assocs hashtables | 
					
						
							|  |  |  | definitions kernel.private classes classes.private | 
					
						
							| 
									
										
										
										
											2008-02-04 20:38:31 -05:00
										 |  |  | quotations arrays vocabs effects ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: generic | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | ! Method combination protocol | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | GENERIC: perform-combination ( word combination -- quot )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-09 17:41:35 -04:00
										 |  |  | M: object perform-combination | 
					
						
							|  |  |  |     #! We delay the invalid method combination error for a | 
					
						
							|  |  |  |     #! reason. If we call forget-vocab on a vocabulary which | 
					
						
							|  |  |  |     #! defines a method combination, a generic using this | 
					
						
							|  |  |  |     #! method combination, and a method on the generic, and the | 
					
						
							|  |  |  |     #! method combination is forgotten first, then forgetting | 
					
						
							|  |  |  |     #! the method will throw an error. We don't want that. | 
					
						
							| 
									
										
										
										
											2007-10-14 21:13:42 -04:00
										 |  |  |     nip [ "Invalid method combination" throw ] curry [ ] like ;
 | 
					
						
							| 
									
										
										
										
											2007-10-09 17:41:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | GENERIC: method-prologue ( class combination -- quot )
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | M: object method-prologue 2drop [ ] ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | GENERIC: make-default-method ( generic combination -- method )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PREDICATE: word generic "combination" word-prop >boolean ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: generic definer drop f f ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: generic definition drop f ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | : make-generic ( word -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-16 16:55:25 -05:00
										 |  |  |     dup { "unannotated-def" } reset-props | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  |     dup dup "combination" word-prop perform-combination define ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | TUPLE: method word def specializer generic loc ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : method ( class generic -- method/f )
 | 
					
						
							|  |  |  |     "methods" word-prop at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PREDICATE: pair method-spec | 
					
						
							|  |  |  |     first2 generic? swap class? and ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : order ( generic -- seq )
 | 
					
						
							|  |  |  |     "methods" word-prop keys sort-classes ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : methods ( word -- assoc )
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  |     "methods" word-prop | 
					
						
							|  |  |  |     [ keys sort-classes ] keep
 | 
					
						
							|  |  |  |     [ dupd at method-word ] curry { } map>assoc ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | TUPLE: check-method class generic ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check-method ( class generic -- class generic )
 | 
					
						
							|  |  |  |     over class? over generic? and [ | 
					
						
							|  |  |  |         \ check-method construct-boa throw
 | 
					
						
							|  |  |  |     ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : with-methods ( word quot -- )
 | 
					
						
							| 
									
										
										
										
											2007-12-26 20:20:49 -05:00
										 |  |  |     swap [ "methods" word-prop swap call ] keep make-generic ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | : method-word-name ( class word -- string )
 | 
					
						
							|  |  |  |     word-name "/" rot word-name 3append ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : make-method-def ( quot word combination -- quot )
 | 
					
						
							|  |  |  |     "combination" word-prop method-prologue swap append ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 20:38:31 -05:00
										 |  |  | PREDICATE: word method-body "method" word-prop >boolean ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: method-body stack-effect | 
					
						
							|  |  |  |     "method" word-prop method-generic stack-effect ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | : <method-word> ( quot class generic -- word )
 | 
					
						
							|  |  |  |     [ make-method-def ] 2keep
 | 
					
						
							| 
									
										
										
										
											2008-02-04 20:38:31 -05:00
										 |  |  |     method-word-name f <word> | 
					
						
							| 
									
										
										
										
											2008-02-05 00:30:59 -05:00
										 |  |  |     dup rot define | 
					
						
							|  |  |  |     dup xref ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : <method> ( quot class generic -- method )
 | 
					
						
							|  |  |  |     check-method | 
					
						
							| 
									
										
										
										
											2008-02-04 20:38:31 -05:00
										 |  |  |     [ <method-word> ] 3keep f \ method construct-boa | 
					
						
							|  |  |  |     dup method-word over "method" set-word-prop ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-17 01:37:54 -05:00
										 |  |  | : redefine-method ( quot class generic -- )
 | 
					
						
							|  |  |  |     [ method set-method-def ] 3keep
 | 
					
						
							|  |  |  |     [ make-method-def ] 2keep
 | 
					
						
							|  |  |  |     method method-word swap define ;
 | 
					
						
							| 
									
										
										
										
											2008-02-16 19:50:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | : define-method ( quot class generic -- )
 | 
					
						
							|  |  |  |     >r bootstrap-word r> | 
					
						
							| 
									
										
										
										
											2008-02-17 01:37:54 -05:00
										 |  |  |     2dup method [ | 
					
						
							|  |  |  |         redefine-method | 
					
						
							| 
									
										
										
										
											2008-02-16 19:50:16 -05:00
										 |  |  |     ] [ | 
					
						
							|  |  |  |         [ <method> ] 2keep
 | 
					
						
							|  |  |  |         [ set-at ] with-methods | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | : define-default-method ( generic combination -- )
 | 
					
						
							|  |  |  |     dupd make-default-method object bootstrap-word pick <method> | 
					
						
							|  |  |  |     "default-method" set-word-prop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! Definition protocol | 
					
						
							|  |  |  | M: method-spec where | 
					
						
							| 
									
										
										
										
											2008-02-23 23:29:29 -05:00
										 |  |  |     dup first2 method [ method-word ] [ second ] ?if where ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-23 23:29:29 -05:00
										 |  |  | M: method-spec set-where | 
					
						
							|  |  |  |     first2 method method-word set-where ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-23 23:29:29 -05:00
										 |  |  | M: method-spec definer | 
					
						
							|  |  |  |     drop \ M: \ ; ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-03 15:19:07 -05:00
										 |  |  | M: method-spec definition | 
					
						
							|  |  |  |     first2 method dup [ method-def ] when ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-11 03:32:25 -05:00
										 |  |  | : forget-method ( class generic -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-06 13:09:42 -05:00
										 |  |  |     check-method | 
					
						
							|  |  |  |     [ delete-at* ] with-methods | 
					
						
							| 
									
										
										
										
											2008-02-23 23:48:45 -05:00
										 |  |  |     [ method-word forget-word ] [ drop ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-01-11 03:32:25 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-23 23:29:29 -05:00
										 |  |  | M: method-spec forget* | 
					
						
							|  |  |  |     first2 forget-method ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: method-body definer | 
					
						
							|  |  |  |     drop \ M: \ ; ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: method-body definition | 
					
						
							|  |  |  |     "method" word-prop method-def ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: method-body forget* | 
					
						
							|  |  |  |     "method" word-prop | 
					
						
							|  |  |  |     { method-specializer method-generic } get-slots | 
					
						
							|  |  |  |     forget-method ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : implementors* ( classes -- words )
 | 
					
						
							|  |  |  |     all-words [ | 
					
						
							|  |  |  |         "methods" word-prop keys
 | 
					
						
							|  |  |  |         swap [ key? ] curry contains? | 
					
						
							| 
									
										
										
										
											2008-01-09 17:36:30 -05:00
										 |  |  |     ] with subset ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : implementors ( class -- seq )
 | 
					
						
							|  |  |  |     dup associate implementors* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : forget-methods ( class -- )
 | 
					
						
							| 
									
										
										
										
											2007-10-09 17:35:09 -04:00
										 |  |  |     [ implementors ] keep [ swap 2array ] curry map forget-all ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-09 16:51:55 -05:00
										 |  |  | M: class forget* ( class -- )
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     dup forget-methods | 
					
						
							|  |  |  |     dup uncache-class | 
					
						
							|  |  |  |     forget-word ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-31 01:49:18 -05:00
										 |  |  | M: assoc update-methods ( assoc -- )
 | 
					
						
							|  |  |  |     implementors* [ make-generic ] each ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : define-generic ( word combination -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-04 20:38:31 -05:00
										 |  |  |     over "combination" word-prop over = [ | 
					
						
							|  |  |  |         2drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         2dup "combination" set-word-prop | 
					
						
							|  |  |  |         over H{ } clone "methods" set-word-prop | 
					
						
							|  |  |  |         dupd define-default-method | 
					
						
							|  |  |  |         make-generic | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 20:43:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-05 00:30:59 -05:00
										 |  |  | GENERIC: subwords ( word -- seq )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: word subwords drop f ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: generic subwords | 
					
						
							| 
									
										
										
										
											2008-02-04 20:43:10 -05:00
										 |  |  |     dup "methods" word-prop values
 | 
					
						
							|  |  |  |     swap "default-method" word-prop add | 
					
						
							|  |  |  |     [ method-word ] map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-06 13:09:42 -05:00
										 |  |  | M: generic forget-word | 
					
						
							|  |  |  |     dup subwords [ forget-word ] each (forget-word) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 20:43:10 -05:00
										 |  |  | : xref-generics ( -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-05 00:30:59 -05:00
										 |  |  |     all-words [ subwords [ xref ] each ] each ;
 |