| 
									
										
										
										
											2010-02-23 06:16:55 -05:00
										 |  |  | ! Copyright (C) 2006, 2010 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 words kernel sequences namespaces make assocs | 
					
						
							| 
									
										
										
										
											2008-06-28 03:36:20 -04:00
										 |  |  | hashtables definitions kernel.private classes classes.private | 
					
						
							| 
									
										
										
										
											2008-06-12 06:49:46 -04:00
										 |  |  | classes.algebra quotations arrays vocabs effects combinators | 
					
						
							| 
									
										
										
										
											2009-03-13 20:39:32 -04:00
										 |  |  | sets ;
 | 
					
						
							| 
									
										
										
										
											2010-02-26 16:01:01 -05:00
										 |  |  | FROM: namespaces => set ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: generic | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | ! Method combination protocol | 
					
						
							| 
									
										
										
										
											2008-04-02 22:27:49 -04:00
										 |  |  | GENERIC: perform-combination ( word combination -- )
 | 
					
						
							| 
									
										
										
										
											2007-10-09 17:41:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | GENERIC: make-default-method ( generic combination -- method )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 19:23:19 -04:00
										 |  |  | PREDICATE: generic < word | 
					
						
							|  |  |  |     "combination" word-prop >boolean ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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-04-02 19:50:21 -04:00
										 |  |  |     [ { "unannotated-def" } reset-props ] | 
					
						
							|  |  |  |     [ dup "combination" word-prop perform-combination ] | 
					
						
							|  |  |  |     bi ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-01 02:08:24 -05:00
										 |  |  | PREDICATE: method < word | 
					
						
							|  |  |  |     "method-generic" word-prop >boolean ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : method ( class generic -- method/f )
 | 
					
						
							|  |  |  |     "methods" word-prop at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-21 18:42:20 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interesting-class? ( class1 class2 -- ? )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ! Case 1: no intersection. Discard and keep going | 
					
						
							|  |  |  |         { [ 2dup classes-intersect? not ] [ 2drop t ] } | 
					
						
							|  |  |  |         ! Case 2: class1 contained in class2. Add to | 
					
						
							|  |  |  |         ! interesting set and keep going. | 
					
						
							|  |  |  |         { [ 2dup class<= ] [ nip , t ] } | 
					
						
							|  |  |  |         ! Case 3: class1 and class2 are incomparable. Give up | 
					
						
							|  |  |  |         [ 2drop f ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : interesting-classes ( class classes -- interesting/f )
 | 
					
						
							|  |  |  |     [ [ interesting-class? ] with all? ] { } make and ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : method-classes ( generic -- classes )
 | 
					
						
							|  |  |  |     "methods" word-prop keys ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : order ( generic -- seq )
 | 
					
						
							| 
									
										
										
										
											2009-09-21 18:42:20 -04:00
										 |  |  |     method-classes sort-classes ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : nearest-class ( class generic -- class/f )
 | 
					
						
							|  |  |  |     method-classes interesting-classes smallest-class ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-21 18:42:20 -04:00
										 |  |  | : method-for-class ( class generic -- method/f )
 | 
					
						
							|  |  |  |     [ nip ] [ nearest-class ] 2bi dup [ swap method ] [ 2drop f ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-04-18 17:51:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-29 22:37:57 -04:00
										 |  |  | GENERIC: effective-method ( generic -- method )
 | 
					
						
							| 
									
										
										
										
											2008-04-03 18:33:06 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-13 00:01:14 -04:00
										 |  |  | \ effective-method t "no-compile" set-word-prop | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-02 22:27:49 -04:00
										 |  |  | : next-method-class ( class generic -- class/f )
 | 
					
						
							| 
									
										
										
										
											2009-09-21 18:42:20 -04:00
										 |  |  |     method-classes [ class< ] with filter smallest-class ;
 | 
					
						
							| 
									
										
										
										
											2008-04-02 22:27:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-29 22:31:58 -04:00
										 |  |  | : next-method ( class generic -- method/f )
 | 
					
						
							| 
									
										
										
										
											2008-04-02 22:27:49 -04:00
										 |  |  |     [ next-method-class ] keep method ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-29 03:12:44 -04:00
										 |  |  | GENERIC: next-method-quot* ( class generic combination -- quot )
 | 
					
						
							| 
									
										
										
										
											2008-04-05 21:07:30 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-22 20:57:25 -05:00
										 |  |  | : next-method-quot ( method -- quot )
 | 
					
						
							| 
									
										
										
										
											2008-10-01 09:20:49 -04:00
										 |  |  |     next-method-quot-cache get [ | 
					
						
							| 
									
										
										
										
											2008-11-22 20:57:25 -05:00
										 |  |  |         [ "method-class" word-prop ] | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             "method-generic" word-prop | 
					
						
							|  |  |  |             dup "combination" word-prop | 
					
						
							|  |  |  |         ] bi next-method-quot* | 
					
						
							|  |  |  |     ] cache ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-28 02:08:16 -05:00
										 |  |  | ERROR: no-next-method method ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-22 20:57:25 -05:00
										 |  |  | : (call-next-method) ( method -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-28 02:08:16 -05:00
										 |  |  |     dup next-method-quot [ call ] [ no-next-method ] ?if ;
 | 
					
						
							| 
									
										
										
										
											2008-04-02 22:27:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | TUPLE: check-method class generic ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check-method ( class generic -- class generic )
 | 
					
						
							| 
									
										
										
										
											2008-08-31 02:34:00 -04:00
										 |  |  |     2dup [ class? ] [ generic? ] bi* and [ | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |         \ check-method boa throw
 | 
					
						
							| 
									
										
										
										
											2008-03-16 03:43:00 -04:00
										 |  |  |     ] unless ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-07 00:33:30 -05:00
										 |  |  | : remake-generic ( generic -- )
 | 
					
						
							| 
									
										
										
										
											2009-03-13 20:39:32 -04:00
										 |  |  |     dup outdated-generics get set-in-unit ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : remake-generics ( -- )
 | 
					
						
							|  |  |  |     outdated-generics get keys [ generic? ] filter [ make-generic ] each ;
 | 
					
						
							| 
									
										
										
										
											2009-03-07 00:33:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-20 10:23:20 -05:00
										 |  |  | GENERIC: update-generic ( class generic -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  | : with-methods ( class generic quot -- )
 | 
					
						
							| 
									
										
										
										
											2010-01-20 10:23:20 -05:00
										 |  |  |     [ "methods" word-prop ] prepose [ update-generic ] 2bi ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-24 07:24:52 -04:00
										 |  |  | : method-word-name ( class generic -- string )
 | 
					
						
							| 
									
										
										
										
											2008-12-03 20:12:48 -05:00
										 |  |  |     [ name>> ] bi@ "=>" glue ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-23 06:16:55 -05:00
										 |  |  | M: method parent-word | 
					
						
							|  |  |  |     "method-generic" word-prop ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 20:38:31 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-01 02:08:24 -05:00
										 |  |  | M: method crossref? | 
					
						
							| 
									
										
										
										
											2008-06-11 03:58:38 -04:00
										 |  |  |     "forgotten" word-prop not ;
 | 
					
						
							| 
									
										
										
										
											2008-04-02 19:50:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-16 03:43:00 -04:00
										 |  |  | : method-word-props ( class generic -- assoc )
 | 
					
						
							| 
									
										
										
										
											2008-03-04 23:13:30 -05:00
										 |  |  |     [ | 
					
						
							|  |  |  |         "method-generic" set
 | 
					
						
							|  |  |  |         "method-class" set
 | 
					
						
							|  |  |  |     ] H{ } make-assoc ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-16 03:43:00 -04:00
										 |  |  | : <method> ( class generic -- method )
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  |     check-method | 
					
						
							| 
									
										
										
										
											2009-09-24 07:24:52 -04:00
										 |  |  |     [ method-word-name f <word> ] [ method-word-props ] 2bi
 | 
					
						
							|  |  |  |     >>props ;
 | 
					
						
							| 
									
										
										
										
											2008-03-16 03:43:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-12 06:49:46 -04:00
										 |  |  | : with-implementors ( class generic quot -- )
 | 
					
						
							|  |  |  |     [ swap implementors-map get at ] dip call ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-16 03:43:00 -04:00
										 |  |  | : reveal-method ( method class generic -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-12 06:49:46 -04:00
										 |  |  |     [ [ conjoin ] with-implementors ] | 
					
						
							|  |  |  |     [ [ set-at ] with-methods ] | 
					
						
							|  |  |  |     2bi ;
 | 
					
						
							| 
									
										
										
										
											2008-03-16 03:43:00 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : create-method ( class generic -- method )
 | 
					
						
							| 
									
										
										
										
											2009-03-07 01:42:43 -05:00
										 |  |  |     2dup method dup [ 2nip dup reset-generic ] [ | 
					
						
							| 
									
										
										
										
											2008-10-01 09:20:49 -04:00
										 |  |  |         drop
 | 
					
						
							|  |  |  |         [ <method> dup ] 2keep
 | 
					
						
							|  |  |  |         reveal-method | 
					
						
							|  |  |  |         reset-caches | 
					
						
							| 
									
										
										
										
											2008-02-16 19:50:16 -05:00
										 |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-01 05:32:26 -04:00
										 |  |  | PREDICATE: default-method < word "default" word-prop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-16 03:43:00 -04:00
										 |  |  | : <default-method> ( generic combination -- method )
 | 
					
						
							| 
									
										
										
										
											2008-06-11 03:58:38 -04:00
										 |  |  |     [ drop object bootstrap-word swap <method> ] [ make-default-method ] 2bi
 | 
					
						
							|  |  |  |     [ define ] [ drop t "default" set-word-prop ] [ drop ] 2tri ;
 | 
					
						
							| 
									
										
										
										
											2008-03-16 03:43:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | : define-default-method ( generic combination -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-16 03:43:00 -04:00
										 |  |  |     dupd <default-method> "default-method" set-word-prop ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! Definition protocol | 
					
						
							| 
									
										
										
										
											2010-02-01 02:08:24 -05:00
										 |  |  | M: method definer | 
					
						
							| 
									
										
										
										
											2008-02-23 23:29:29 -05:00
										 |  |  |     drop \ M: \ ; ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-01 02:08:24 -05:00
										 |  |  | M: method forget* | 
					
						
							| 
									
										
										
										
											2008-03-18 22:43:29 -04:00
										 |  |  |     dup "forgotten" word-prop [ drop ] [ | 
					
						
							| 
									
										
										
										
											2008-04-02 19:50:21 -04:00
										 |  |  |         [ | 
					
						
							| 
									
										
										
										
											2008-09-01 05:32:26 -04:00
										 |  |  |             dup default-method? [ drop ] [ | 
					
						
							| 
									
										
										
										
											2008-06-11 21:46:53 -04:00
										 |  |  |                 [ | 
					
						
							|  |  |  |                     [ "method-class" word-prop ] | 
					
						
							|  |  |  |                     [ "method-generic" word-prop ] bi
 | 
					
						
							|  |  |  |                     2dup method | 
					
						
							|  |  |  |                 ] keep eq?
 | 
					
						
							| 
									
										
										
										
											2008-06-12 06:49:46 -04:00
										 |  |  |                 [ | 
					
						
							|  |  |  |                     [ [ delete-at ] with-methods ] | 
					
						
							| 
									
										
										
										
											2008-10-01 09:38:50 -04:00
										 |  |  |                     [ [ delete-at ] with-implementors ] 2bi
 | 
					
						
							|  |  |  |                     reset-caches | 
					
						
							| 
									
										
										
										
											2008-06-12 06:49:46 -04:00
										 |  |  |                 ] [ 2drop ] if
 | 
					
						
							| 
									
										
										
										
											2008-06-11 03:58:38 -04:00
										 |  |  |             ] if
 | 
					
						
							| 
									
										
										
										
											2008-04-02 19:50:21 -04:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2008-06-11 21:46:53 -04:00
										 |  |  |         [ call-next-method ] bi
 | 
					
						
							| 
									
										
										
										
											2008-03-18 22:43:29 -04:00
										 |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-22 19:00:26 -04:00
										 |  |  | : define-generic ( word combination effect -- )
 | 
					
						
							|  |  |  |     [ nip swap set-stack-effect ] | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         drop
 | 
					
						
							|  |  |  |         2dup [ "combination" word-prop ] dip = [ 2drop ] [ | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2009-04-28 18:56:15 -04:00
										 |  |  |                 [ drop reset-generic ] | 
					
						
							| 
									
										
										
										
											2009-03-22 19:00:26 -04:00
										 |  |  |                 [ "combination" set-word-prop ] | 
					
						
							|  |  |  |                 [ drop H{ } clone "methods" set-word-prop ] | 
					
						
							|  |  |  |                 [ define-default-method ] | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             2cleave
 | 
					
						
							|  |  |  |         ] if
 | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2009-03-22 21:16:31 -04:00
										 |  |  |     [ 2drop remake-generic ] 3tri ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 20:43:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-05 00:30:59 -05:00
										 |  |  | M: generic subwords | 
					
						
							| 
									
										
										
										
											2008-04-02 19:50:21 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         [ "default-method" word-prop , ] | 
					
						
							|  |  |  |         [ "methods" word-prop values % ] | 
					
						
							|  |  |  |         [ "engines" word-prop % ] | 
					
						
							|  |  |  |         tri
 | 
					
						
							|  |  |  |     ] { } make ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 20:43:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-06 05:16:39 -04:00
										 |  |  | M: class forget-methods | 
					
						
							|  |  |  |     [ implementors ] [ [ swap method ] curry ] bi map forget-all ;
 |