| 
									
										
										
										
											2008-01-01 14:54:14 -05:00
										 |  |  | ! Copyright (C) 2004, 2008 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2008-01-01 14:54:14 -05:00
										 |  |  | USING: inference.dataflow inference.state arrays generic io | 
					
						
							|  |  |  | io.streams.string kernel math namespaces parser prettyprint | 
					
						
							|  |  |  | sequences strings vectors words quotations effects classes | 
					
						
							| 
									
										
										
										
											2008-04-02 01:28:07 -04:00
										 |  |  | continuations debugger assocs combinators compiler.errors | 
					
						
							| 
									
										
										
										
											2008-04-26 00:12:44 -04:00
										 |  |  | generic.standard.engines.tuple accessors math.order ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: inference.backend | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : recursive-label ( word -- label/f )
 | 
					
						
							|  |  |  |     recursive-state get at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-02 01:28:07 -04:00
										 |  |  | GENERIC: inline? ( word -- ? )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: method-body inline? | 
					
						
							|  |  |  |     "method-generic" word-prop inline? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  | M: engine-word inline? | 
					
						
							| 
									
										
										
										
											2008-04-02 01:28:07 -04:00
										 |  |  |     "tuple-dispatch-generic" word-prop inline? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: word inline? | 
					
						
							|  |  |  |     "inline" word-prop ;
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : local-recursive-state ( -- assoc )
 | 
					
						
							|  |  |  |     recursive-state get dup keys
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  |     [ dup word? [ inline? ] when not ] find drop
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     [ head-slice ] when* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : inline-recursive-label ( word -- label/f )
 | 
					
						
							|  |  |  |     local-recursive-state at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : recursive-quotation? ( quot -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-01-09 17:36:30 -05:00
										 |  |  |     local-recursive-state [ first eq? ] with contains? ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  | TUPLE: inference-error error type rstate ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  | M: inference-error compiler-error-type type>> ;
 | 
					
						
							| 
									
										
										
										
											2007-12-28 22:51:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-05 21:07:30 -04:00
										 |  |  | M: inference-error error-help error>> error-help ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-10 21:32:48 -05:00
										 |  |  | : (inference-error) ( ... class type -- * )
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |     >r boa r> | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  |     recursive-state get
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:09 -04:00
										 |  |  |     \ inference-error boa throw ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : inference-error ( ... class -- * )
 | 
					
						
							| 
									
										
										
										
											2008-02-10 21:32:48 -05:00
										 |  |  |     +error+ (inference-error) ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : inference-warning ( ... class -- * )
 | 
					
						
							| 
									
										
										
										
											2008-02-10 21:32:48 -05:00
										 |  |  |     +warning+ (inference-error) ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | TUPLE: literal-expected ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: object value-literal \ literal-expected inference-warning ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : pop-literal ( -- rstate obj )
 | 
					
						
							|  |  |  |     1 #drop node, | 
					
						
							|  |  |  |     pop-d dup value-literal >r value-recursion r> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : value-vector ( n -- vector ) [ drop <computed> ] V{ } map-as ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : add-inputs ( seq stack -- n stack )
 | 
					
						
							| 
									
										
										
										
											2008-04-27 19:57:46 -04:00
										 |  |  |     tuck [ length ] bi@ - dup 0 >
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     [ dup value-vector [ swapd push-all ] keep ] | 
					
						
							|  |  |  |     [ drop 0 swap ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : ensure-values ( seq -- )
 | 
					
						
							|  |  |  |     meta-d [ add-inputs ] change d-in [ + ] change ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : current-effect ( -- effect )
 | 
					
						
							|  |  |  |     d-in get meta-d get length <effect> | 
					
						
							|  |  |  |     terminated? get over set-effect-terminated? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  | : init-inference ( -- )
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     terminated? off
 | 
					
						
							|  |  |  |     V{ } clone meta-d set
 | 
					
						
							|  |  |  |     V{ } clone meta-r set
 | 
					
						
							|  |  |  |     0 d-in set
 | 
					
						
							|  |  |  |     dataflow-graph off
 | 
					
						
							|  |  |  |     current-node off ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: apply-object ( obj -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : apply-literal ( obj -- )
 | 
					
						
							|  |  |  |     <value> push-d #push 1 0 pick node-outputs node, ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: object apply-object apply-literal ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-12 04:25:16 -05:00
										 |  |  | M: wrapper apply-object | 
					
						
							|  |  |  |     wrapped dup +called+ depends-on apply-literal ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : terminate ( -- )
 | 
					
						
							|  |  |  |     terminated? on #terminate node, ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  | : infer-quot ( quot rstate -- )
 | 
					
						
							|  |  |  |     recursive-state get >r | 
					
						
							|  |  |  |     recursive-state set
 | 
					
						
							|  |  |  |     [ apply-object terminated? get not ] all? drop
 | 
					
						
							|  |  |  |     r> recursive-state set ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  | : infer-quot-recursive ( quot word label -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-31 20:18:05 -04:00
										 |  |  |     recursive-state get -rot 2array prefix infer-quot ;
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : time-bomb ( error -- )
 | 
					
						
							|  |  |  |     [ throw ] curry recursive-state get infer-quot ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : bad-call ( -- )
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  |     "call must be given a callable" time-bomb ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: recursive-quotation-error quot ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : infer-quot-value ( value -- )
 | 
					
						
							|  |  |  |     dup recursive-quotation? [ | 
					
						
							|  |  |  |         value-literal recursive-quotation-error inference-error | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         dup value-literal callable? [ | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  |             dup value-literal | 
					
						
							|  |  |  |             over value-recursion | 
					
						
							| 
									
										
										
										
											2008-03-31 20:18:05 -04:00
										 |  |  |             rot f 2array prefix infer-quot | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         ] [ | 
					
						
							|  |  |  |             drop bad-call | 
					
						
							|  |  |  |         ] if
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: too-many->r ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check->r ( -- )
 | 
					
						
							|  |  |  |     meta-r get empty? terminated? get or
 | 
					
						
							|  |  |  |     [ \ too-many->r inference-error ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: too-many-r> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  | : check-r> ( n -- )
 | 
					
						
							|  |  |  |     meta-r get length >
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     [ \ too-many-r> inference-error ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  | : infer->r ( n -- )
 | 
					
						
							|  |  |  |     dup ensure-values | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     #>r | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  |     over 0 pick node-inputs | 
					
						
							|  |  |  |     over [ drop pop-d ] map reverse [ push-r ] each
 | 
					
						
							|  |  |  |     0 pick pick node-outputs | 
					
						
							|  |  |  |     node, | 
					
						
							|  |  |  |     drop ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  | : infer-r> ( n -- )
 | 
					
						
							|  |  |  |     dup check-r> | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     #r> | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  |     0 pick pick node-inputs | 
					
						
							|  |  |  |     over [ drop pop-r ] map reverse [ push-d ] each
 | 
					
						
							|  |  |  |     over 0 pick node-outputs | 
					
						
							|  |  |  |     node, | 
					
						
							|  |  |  |     drop ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : undo-infer ( -- )
 | 
					
						
							|  |  |  |     recorded get [ f "inferred-effect" set-word-prop ] each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (consume-values) ( n -- )
 | 
					
						
							|  |  |  |     meta-d get [ length swap - ] keep set-length ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : consume-values ( seq node -- )
 | 
					
						
							|  |  |  |     >r length r> | 
					
						
							|  |  |  |     over ensure-values | 
					
						
							|  |  |  |     over 0 rot node-inputs | 
					
						
							|  |  |  |     (consume-values) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : produce-values ( seq node -- )
 | 
					
						
							|  |  |  |     >r value-vector dup r> set-node-out-d | 
					
						
							|  |  |  |     meta-d get push-all ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : if-inline ( word true false -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  |     >r >r dup inline? r> r> if ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : consume/produce ( effect node -- )
 | 
					
						
							|  |  |  |     over effect-in over consume-values | 
					
						
							|  |  |  |     over effect-out over produce-values | 
					
						
							|  |  |  |     node, | 
					
						
							|  |  |  |     effect-terminated? [ terminate ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: constructor ( value -- word/f )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: infer-uncurry ( value -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: curried infer-uncurry | 
					
						
							|  |  |  |     drop pop-d dup curried-obj push-d curried-quot push-d ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: curried constructor | 
					
						
							|  |  |  |     drop \ curry ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: composed infer-uncurry | 
					
						
							|  |  |  |     drop pop-d dup composed-quot1 push-d composed-quot2 push-d ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: composed constructor | 
					
						
							|  |  |  |     drop \ compose ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: object infer-uncurry drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: object constructor drop f ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : reify-curry ( value -- )
 | 
					
						
							|  |  |  |     dup infer-uncurry | 
					
						
							|  |  |  |     constructor [ | 
					
						
							|  |  |  |         peek-d reify-curry | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  |         1 infer->r | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         peek-d reify-curry | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  |         1 infer-r> | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         2 1 <effect> swap #call consume/produce | 
					
						
							|  |  |  |     ] when* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : reify-curries ( n -- )
 | 
					
						
							|  |  |  |     meta-d get reverse [ | 
					
						
							|  |  |  |         dup special? [ | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  |             over infer->r | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |             dup reify-curry | 
					
						
							| 
									
										
										
										
											2008-04-17 04:05:36 -04:00
										 |  |  |             over infer-r> | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         ] when 2drop
 | 
					
						
							|  |  |  |     ] 2each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : reify-all ( -- )
 | 
					
						
							|  |  |  |     meta-d get length reify-curries ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  | : end-infer ( -- )
 | 
					
						
							|  |  |  |     check->r | 
					
						
							|  |  |  |     reify-all | 
					
						
							|  |  |  |     f #return node, ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : unify-lengths ( seq -- newseq )
 | 
					
						
							|  |  |  |     dup empty? [ | 
					
						
							|  |  |  |         dup [ length ] map supremum
 | 
					
						
							|  |  |  |         [ swap add-inputs nip ] curry map
 | 
					
						
							|  |  |  |     ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DEFER: unify-values | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unify-curries ( seq -- value )
 | 
					
						
							|  |  |  |     dup [ curried-obj ] map unify-values | 
					
						
							|  |  |  |     swap [ curried-quot ] map unify-values | 
					
						
							|  |  |  |     <curried> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unify-composed ( seq -- value )
 | 
					
						
							|  |  |  |     dup [ composed-quot1 ] map unify-values | 
					
						
							|  |  |  |     swap [ composed-quot2 ] map unify-values | 
					
						
							|  |  |  |     <composed> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: cannot-unify-specials ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : cannot-unify-specials ( -- * )
 | 
					
						
							|  |  |  |     \ cannot-unify-specials inference-warning ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unify-values ( seq -- value )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { [ dup all-eq? ] [ first ] } | 
					
						
							|  |  |  |         { [ dup [ curried? ] all? ] [ unify-curries ] } | 
					
						
							|  |  |  |         { [ dup [ composed? ] all? ] [ unify-composed ] } | 
					
						
							|  |  |  |         { [ dup [ special? ] contains? ] [ cannot-unify-specials ] } | 
					
						
							| 
									
										
										
										
											2008-04-11 13:53:22 -04:00
										 |  |  |         [ drop <computed> ] | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unify-stacks ( seq -- stack )
 | 
					
						
							|  |  |  |     flip [ unify-values ] V{ } map-as ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : balanced? ( in out -- ? )
 | 
					
						
							|  |  |  |     [ dup [ length - ] [ 2drop f ] if ] 2map
 | 
					
						
							| 
									
										
										
										
											2008-05-14 00:36:55 -04:00
										 |  |  |     sift all-equal? ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | TUPLE: unbalanced-branches-error quots in out ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unbalanced-branches-error ( quots in out -- * )
 | 
					
						
							|  |  |  |     \ unbalanced-branches-error inference-error ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unify-inputs ( max-d-in d-in meta-d -- meta-d )
 | 
					
						
							|  |  |  |     dup [ | 
					
						
							|  |  |  |         [ >r - r> length + ] keep add-inputs nip
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         2nip
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unify-effect ( quots in out -- newin newout )
 | 
					
						
							|  |  |  |     #! in is a sequence of integers, out is a sequence of | 
					
						
							|  |  |  |     #! stacks. | 
					
						
							|  |  |  |     2dup balanced? [ | 
					
						
							|  |  |  |         over supremum -rot
 | 
					
						
							|  |  |  |         [ >r dupd r> unify-inputs ] 2map
 | 
					
						
							| 
									
										
										
										
											2008-05-14 00:36:55 -04:00
										 |  |  |         sift unify-stacks | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         rot drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         unbalanced-branches-error | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : active-variable ( seq symbol -- seq )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         swap terminated? over at [ 2drop f ] [ at ] if
 | 
					
						
							|  |  |  |     ] curry map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : branch-variable ( seq symbol -- seq )
 | 
					
						
							|  |  |  |     [ swap at ] curry map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : datastack-effect ( seq -- )
 | 
					
						
							|  |  |  |     dup quotation branch-variable | 
					
						
							|  |  |  |     over d-in branch-variable | 
					
						
							|  |  |  |     rot meta-d active-variable | 
					
						
							|  |  |  |     unify-effect meta-d set d-in set ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : retainstack-effect ( seq -- )
 | 
					
						
							|  |  |  |     dup quotation branch-variable | 
					
						
							|  |  |  |     over length 0 <repetition>
 | 
					
						
							|  |  |  |     rot meta-r active-variable | 
					
						
							|  |  |  |     unify-effect meta-r set drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unify-effects ( seq -- )
 | 
					
						
							|  |  |  |     dup datastack-effect | 
					
						
							|  |  |  |     dup retainstack-effect | 
					
						
							|  |  |  |     [ terminated? swap at ] all? terminated? set ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unify-dataflow ( effects -- nodes )
 | 
					
						
							|  |  |  |     dataflow-graph branch-variable ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : copy-inference ( -- )
 | 
					
						
							|  |  |  |     meta-d [ clone ] change
 | 
					
						
							|  |  |  |     meta-r [ clone ] change
 | 
					
						
							|  |  |  |     d-in [ ] change
 | 
					
						
							|  |  |  |     dataflow-graph off
 | 
					
						
							|  |  |  |     current-node off ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : infer-branch ( last value -- namespace )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         copy-inference | 
					
						
							|  |  |  |         dup value-literal quotation set
 | 
					
						
							|  |  |  |         infer-quot-value | 
					
						
							|  |  |  |         terminated? get [ drop ] [ call node, ] if
 | 
					
						
							|  |  |  |     ] H{ } make-assoc ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (infer-branches) ( last branches -- list )
 | 
					
						
							| 
									
										
										
										
											2008-01-09 17:36:30 -05:00
										 |  |  |     [ infer-branch ] with map
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     dup unify-effects unify-dataflow ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : infer-branches ( last branches node -- )
 | 
					
						
							|  |  |  |     #! last is a quotation which provides a #return or a #values | 
					
						
							|  |  |  |     1 reify-curries | 
					
						
							|  |  |  |     call dup node, | 
					
						
							|  |  |  |     pop-d drop
 | 
					
						
							|  |  |  |     >r (infer-branches) r> set-node-children | 
					
						
							|  |  |  |     #merge node, ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : make-call-node ( word effect -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-04 17:20:07 -05:00
										 |  |  |     swap dup inline? | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     over dup recursive-label eq? not and [ | 
					
						
							|  |  |  |         meta-d get clone -rot
 | 
					
						
							|  |  |  |         recursive-label #call-label [ consume/produce ] keep
 | 
					
						
							|  |  |  |         set-node-in-d | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         over effect-in length reify-curries | 
					
						
							|  |  |  |         #call consume/produce | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: no-effect word ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : no-effect ( word -- * ) \ no-effect inference-warning ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: effect-error word effect ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : effect-error ( word effect -- * )
 | 
					
						
							|  |  |  |     \ effect-error inference-error ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check-effect ( word effect -- )
 | 
					
						
							| 
									
										
										
										
											2008-04-05 21:07:30 -04:00
										 |  |  |     dup pick stack-effect effect<= | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     [ 2drop ] [ effect-error ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  | : finish-word ( word -- )
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     current-effect | 
					
						
							|  |  |  |     2dup check-effect | 
					
						
							|  |  |  |     over recorded get push
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  |     "inferred-effect" set-word-prop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | : infer-word ( word -- effect )
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  |         [ | 
					
						
							|  |  |  |             init-inference | 
					
						
							|  |  |  |             dependencies off
 | 
					
						
							|  |  |  |             dup word-def over dup infer-quot-recursive | 
					
						
							| 
									
										
										
										
											2008-02-10 02:34:26 -05:00
										 |  |  |             end-infer | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  |             finish-word | 
					
						
							|  |  |  |             current-effect | 
					
						
							|  |  |  |         ] with-scope
 | 
					
						
							|  |  |  |     ] [ ] [ t "no-effect" set-word-prop ] cleanup ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : custom-infer ( word -- )
 | 
					
						
							|  |  |  |     #! Customized inference behavior | 
					
						
							| 
									
										
										
										
											2008-01-12 04:25:16 -05:00
										 |  |  |     dup +inlined+ depends-on | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     "infer" word-prop call ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : cached-infer ( word -- )
 | 
					
						
							|  |  |  |     dup "inferred-effect" word-prop make-call-node ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : apply-word ( word -- )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { [ dup "infer" word-prop ] [ custom-infer ] } | 
					
						
							|  |  |  |         { [ dup "no-effect" word-prop ] [ no-effect ] } | 
					
						
							|  |  |  |         { [ dup "inferred-effect" word-prop ] [ cached-infer ] } | 
					
						
							| 
									
										
										
										
											2008-04-11 13:53:22 -04:00
										 |  |  |         [ dup infer-word make-call-node ] | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: recursive-declare-error word ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : declared-infer ( word -- )
 | 
					
						
							|  |  |  |     dup stack-effect [ | 
					
						
							|  |  |  |         make-call-node | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         \ recursive-declare-error inference-error | 
					
						
							|  |  |  |     ] if* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-19 03:11:55 -04:00
										 |  |  | GENERIC: collect-label-info* ( label node -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: node collect-label-info* 2drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (collect-label-info) ( label node vector -- )
 | 
					
						
							|  |  |  |     >r tuck [ param>> ] bi@ eq? r> [ push ] curry [ drop ] if ;
 | 
					
						
							|  |  |  |     inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: #call-label collect-label-info* | 
					
						
							|  |  |  |     over calls>> (collect-label-info) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: #return collect-label-info* | 
					
						
							|  |  |  |     over returns>> (collect-label-info) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : collect-label-info ( #label -- )
 | 
					
						
							|  |  |  |     V{ } clone >>calls | 
					
						
							|  |  |  |     V{ } clone >>returns | 
					
						
							|  |  |  |     dup [ collect-label-info* ] with each-node ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  | : nest-node ( -- ) #entry node, ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : unnest-node ( new-node -- new-node )
 | 
					
						
							|  |  |  |     dup node-param #return node, | 
					
						
							|  |  |  |     dataflow-graph get 1array over set-node-children ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-30 15:23:48 -05:00
										 |  |  | : inlined-block? "inlined-block" word-prop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : <inlined-block> gensym dup t "inlined-block" set-word-prop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-19 03:11:55 -04:00
										 |  |  | : inline-block ( word -- #label data )
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         copy-inference nest-node | 
					
						
							| 
									
										
										
										
											2008-01-30 15:23:48 -05:00
										 |  |  |         dup word-def swap <inlined-block> | 
					
						
							| 
									
										
										
										
											2007-09-27 04:50:24 -04:00
										 |  |  |         [ infer-quot-recursive ] 2keep
 | 
					
						
							|  |  |  |         #label unnest-node | 
					
						
							| 
									
										
										
										
											2008-04-19 03:11:55 -04:00
										 |  |  |         dup collect-label-info | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  |     ] H{ } make-assoc ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-19 03:11:55 -04:00
										 |  |  | : join-values ( #label -- )
 | 
					
						
							|  |  |  |     calls>> [ node-in-d ] map meta-d get suffix
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  |     unify-lengths unify-stacks | 
					
						
							|  |  |  |     meta-d [ length tail* ] change ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : splice-node ( node -- )
 | 
					
						
							|  |  |  |     dup node-successor [ | 
					
						
							|  |  |  |         dup node, penultimate-node f over set-node-successor | 
					
						
							|  |  |  |         dup current-node set
 | 
					
						
							|  |  |  |     ] when drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : apply-infer ( hash -- )
 | 
					
						
							|  |  |  |     { meta-d meta-r d-in terminated? } | 
					
						
							|  |  |  |     [ swap [ at ] curry map ] keep
 | 
					
						
							|  |  |  |     [ set ] 2each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-01 14:54:14 -05:00
										 |  |  | : inline-word ( word -- )
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  |     dup inline-block over recursive-label? [ | 
					
						
							|  |  |  |         flatten-meta-d >r | 
					
						
							|  |  |  |         drop join-values inline-block apply-infer | 
					
						
							|  |  |  |         r> over set-node-in-d | 
					
						
							|  |  |  |         dup node, | 
					
						
							| 
									
										
										
										
											2008-04-19 03:11:55 -04:00
										 |  |  |         calls>> [ | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  |             [ flatten-curries ] modify-values | 
					
						
							|  |  |  |         ] each
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         apply-infer node-child node-successor splice-node drop
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | M: word apply-object | 
					
						
							| 
									
										
										
										
											2008-01-12 04:25:16 -05:00
										 |  |  |     [ | 
					
						
							|  |  |  |         dup +inlined+ depends-on | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         dup inline-recursive-label | 
					
						
							| 
									
										
										
										
											2008-01-01 14:54:14 -05:00
										 |  |  |         [ declared-infer ] [ inline-word ] if
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-01-12 04:25:16 -05:00
										 |  |  |         dup +called+ depends-on | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         dup recursive-label | 
					
						
							|  |  |  |         [ declared-infer ] [ apply-word ] if
 | 
					
						
							|  |  |  |     ] if-inline ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-27 04:00:54 -04:00
										 |  |  | : with-infer ( quot -- effect dataflow )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             V{ } clone recorded set
 | 
					
						
							|  |  |  |             init-inference | 
					
						
							|  |  |  |             call
 | 
					
						
							|  |  |  |             end-infer | 
					
						
							|  |  |  |             current-effect | 
					
						
							|  |  |  |             dataflow-graph get
 | 
					
						
							|  |  |  |         ] [ ] [ undo-infer ] cleanup
 | 
					
						
							|  |  |  |     ] with-scope ;
 |