| 
									
										
										
										
											2009-04-20 19:44:45 -04:00
										 |  |  | ! Copyright (C) 2004, 2009 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2009-04-24 21:43:01 -04:00
										 |  |  | USING: fry arrays generic io io.streams.string kernel math namespaces | 
					
						
							|  |  |  | parser sequences strings vectors words quotations effects classes | 
					
						
							|  |  |  | continuations assocs combinators compiler.errors accessors math.order | 
					
						
							| 
									
										
										
										
											2010-03-08 00:37:24 -05:00
										 |  |  | definitions locals sets hints macros stack-checker.state | 
					
						
							| 
									
										
										
										
											2008-12-08 15:58:00 -05:00
										 |  |  | stack-checker.visitor stack-checker.errors stack-checker.values | 
					
						
							| 
									
										
										
										
											2009-11-08 21:34:46 -05:00
										 |  |  | stack-checker.recursive-state stack-checker.dependencies summary ;
 | 
					
						
							| 
									
										
										
										
											2010-03-07 19:45:33 -05:00
										 |  |  | FROM: sequences.private => from-end ;
 | 
					
						
							| 
									
										
										
										
											2010-02-26 16:01:01 -05:00
										 |  |  | FROM: namespaces => set ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | IN: stack-checker.backend | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  | : push-d ( obj -- ) meta-d push ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 01:17:24 -05:00
										 |  |  | : introduce-values ( values -- )
 | 
					
						
							|  |  |  |     [ [ [ input-parameter ] dip set-known ] each ] | 
					
						
							|  |  |  |     [ length input-count +@ ] | 
					
						
							|  |  |  |     [ #introduce, ] | 
					
						
							|  |  |  |     tri ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-07 19:45:33 -05:00
										 |  |  | : update-inner-d ( new -- )
 | 
					
						
							|  |  |  |     inner-d-index get min inner-d-index set ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | : pop-d  ( -- obj )
 | 
					
						
							| 
									
										
										
										
											2010-03-07 19:45:33 -05:00
										 |  |  |     meta-d | 
					
						
							|  |  |  |     [ <value> dup 1array introduce-values ] | 
					
						
							|  |  |  |     [ pop meta-d length update-inner-d ] if-empty ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : peek-d ( -- obj ) pop-d dup push-d ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-11 20:51:26 -05:00
										 |  |  | : make-values ( n -- values )
 | 
					
						
							|  |  |  |     [ <value> ] replicate ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-11 20:51:26 -05:00
										 |  |  | : ensure-d ( n -- values )
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  |     meta-d 2dup length > [ | 
					
						
							| 
									
										
										
										
											2008-11-11 20:51:26 -05:00
										 |  |  |         2dup
 | 
					
						
							|  |  |  |         [ nip >array ] [ length - make-values ] [ nip delete-all ] 2tri
 | 
					
						
							| 
									
										
										
										
											2009-11-09 01:17:24 -05:00
										 |  |  |         [ introduce-values ] [ meta-d push-all ] bi
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  |         meta-d push-all
 | 
					
						
							| 
									
										
										
										
											2010-03-07 19:45:33 -05:00
										 |  |  |     ] when
 | 
					
						
							|  |  |  |     swap from-end [ tail ] [ update-inner-d ] bi ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-11 20:51:26 -05:00
										 |  |  | : shorten-by ( n seq -- )
 | 
					
						
							|  |  |  |     [ length swap - ] keep shorten ; inline
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-07 23:44:50 -05:00
										 |  |  | : shorten-d ( n -- )
 | 
					
						
							|  |  |  |     meta-d shorten-by meta-d length update-inner-d ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-11 20:51:26 -05:00
										 |  |  | : consume-d ( n -- seq )
 | 
					
						
							| 
									
										
										
										
											2010-03-07 23:44:50 -05:00
										 |  |  |     [ ensure-d ] [ shorten-d ] bi ;
 | 
					
						
							| 
									
										
										
										
											2008-11-11 20:51:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  | : output-d ( values -- ) meta-d push-all ;
 | 
					
						
							| 
									
										
										
										
											2008-07-27 21:25:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | : produce-d ( n -- values )
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  |     make-values dup meta-d push-all ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  | : push-r ( obj -- ) meta-r push ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  | : pop-r ( -- obj )
 | 
					
						
							|  |  |  |     meta-r dup empty?
 | 
					
						
							| 
									
										
										
										
											2009-02-26 02:25:13 -05:00
										 |  |  |     [ too-many-r> ] [ pop ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-11 20:51:26 -05:00
										 |  |  | : consume-r ( n -- seq )
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  |     meta-r 2dup length >
 | 
					
						
							| 
									
										
										
										
											2009-02-26 02:25:13 -05:00
										 |  |  |     [ too-many-r> ] when
 | 
					
						
							| 
									
										
										
										
											2008-11-11 20:51:26 -05:00
										 |  |  |     [ swap tail* ] [ shorten-by ] 2bi ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  | : output-r ( seq -- ) meta-r push-all ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : push-literal ( obj -- )
 | 
					
						
							|  |  |  |     literals get push ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : pop-literal ( -- rstate obj )
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  |     literals get [ | 
					
						
							|  |  |  |         pop-d | 
					
						
							|  |  |  |         [ 1array #drop, ] | 
					
						
							|  |  |  |         [ literal [ recursion>> ] [ value>> ] bi ] bi
 | 
					
						
							|  |  |  |     ] [ pop recursive-state get swap ] if-empty ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  | : literals-available? ( n -- literals ? )
 | 
					
						
							|  |  |  |     literals get 2dup length <=
 | 
					
						
							|  |  |  |     [ [ swap tail* ] [ shorten-by ] 2bi t ] [ 2drop f f ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  | GENERIC: apply-object ( obj -- )
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: wrapper apply-object | 
					
						
							|  |  |  |     wrapped>> | 
					
						
							| 
									
										
										
										
											2010-01-29 04:29:55 -05:00
										 |  |  |     [ dup word? [ depends-on-effect ] [ drop ] if ] | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |     [ push-literal ] | 
					
						
							|  |  |  |     bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: object apply-object push-literal ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : terminate ( -- )
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  |     terminated? on meta-d clone meta-r clone #terminate, ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check->r ( -- )
 | 
					
						
							| 
									
										
										
										
											2009-02-26 02:25:13 -05:00
										 |  |  |     meta-r empty? [ too-many->r ] unless ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-03 04:06:11 -05:00
										 |  |  | : infer-quot-here ( quot -- )
 | 
					
						
							| 
									
										
										
										
											2009-04-22 22:03:53 -04:00
										 |  |  |     meta-r [ | 
					
						
							|  |  |  |         V{ } clone \ meta-r set
 | 
					
						
							|  |  |  |         [ apply-object terminated? get not ] all?
 | 
					
						
							|  |  |  |         [ commit-literals check->r ] [ literals get delete-all ] if
 | 
					
						
							|  |  |  |     ] dip \ meta-r set ;
 | 
					
						
							| 
									
										
										
										
											2008-11-03 04:06:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | : infer-quot ( quot rstate -- )
 | 
					
						
							|  |  |  |     recursive-state get [ | 
					
						
							|  |  |  |         recursive-state set
 | 
					
						
							| 
									
										
										
										
											2008-11-03 04:06:11 -05:00
										 |  |  |         infer-quot-here | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |     ] dip recursive-state set ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : time-bomb ( error -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-03 04:06:11 -05:00
										 |  |  |     '[ _ throw ] infer-quot-here ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-11 23:40:29 -04:00
										 |  |  | ERROR: bad-call obj ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: bad-call summary | 
					
						
							|  |  |  |     drop "call must be given a callable" ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : infer-literal-quot ( literal -- )
 | 
					
						
							|  |  |  |     dup recursive-quotation? [ | 
					
						
							| 
									
										
										
										
											2009-02-26 02:25:13 -05:00
										 |  |  |         value>> recursive-quotation-error | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |     ] [ | 
					
						
							|  |  |  |         dup value>> callable? [ | 
					
						
							|  |  |  |             [ value>> ] | 
					
						
							| 
									
										
										
										
											2008-11-12 20:08:40 -05:00
										 |  |  |             [ [ recursion>> ] keep add-local-quotation ] | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |             bi infer-quot | 
					
						
							|  |  |  |         ] [ | 
					
						
							| 
									
										
										
										
											2009-08-11 23:40:29 -04:00
										 |  |  |             value>> \ bad-call boa time-bomb | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |         ] if
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : infer->r ( n -- )
 | 
					
						
							| 
									
										
										
										
											2009-04-22 22:03:53 -04:00
										 |  |  |     consume-d dup copy-values [ nip output-r ] [ #>r, ] 2bi ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : infer-r> ( n -- )
 | 
					
						
							| 
									
										
										
										
											2009-04-22 22:03:53 -04:00
										 |  |  |     consume-r dup copy-values [ nip output-d ] [ #r>, ] 2bi ;
 | 
					
						
							| 
									
										
										
										
											2009-02-23 21:27:05 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-09 02:38:10 -05:00
										 |  |  | : consume/produce ( ..a effect quot: ( ..a inputs outputs -- ..b ) -- ..b )
 | 
					
						
							| 
									
										
										
										
											2009-04-22 22:03:53 -04:00
										 |  |  |     '[ [ in>> length consume-d ] [ out>> length produce-d ] bi @ ] | 
					
						
							| 
									
										
										
										
											2009-02-23 21:27:05 -05:00
										 |  |  |     [ terminated?>> [ terminate ] when ] | 
					
						
							|  |  |  |     bi ; inline
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 22:03:53 -04:00
										 |  |  | : apply-word/effect ( word effect -- )
 | 
					
						
							|  |  |  |     swap '[ _ #call, ] consume/produce ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | : end-infer ( -- )
 | 
					
						
							| 
									
										
										
										
											2008-12-04 07:02:49 -05:00
										 |  |  |     meta-d clone #return, ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 21:27:05 -05:00
										 |  |  | : required-stack-effect ( word -- effect )
 | 
					
						
							| 
									
										
										
										
											2009-02-26 02:25:13 -05:00
										 |  |  |     dup stack-effect [ ] [ missing-effect ] ?if ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : with-infer ( quot -- effect visitor )
 | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2009-04-20 19:44:45 -04:00
										 |  |  |         init-inference | 
					
						
							|  |  |  |         init-known-values | 
					
						
							|  |  |  |         stack-visitor off
 | 
					
						
							|  |  |  |         call
 | 
					
						
							|  |  |  |         end-infer | 
					
						
							|  |  |  |         current-effect | 
					
						
							|  |  |  |         stack-visitor get
 | 
					
						
							| 
									
										
										
										
											2008-07-23 01:17:08 -04:00
										 |  |  |     ] with-scope ; inline
 | 
					
						
							| 
									
										
										
										
											2010-03-05 17:27:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (infer) ( quot -- effect )
 | 
					
						
							|  |  |  |     [ infer-quot-here ] with-infer drop ;
 | 
					
						
							| 
									
										
										
										
											2010-03-08 00:37:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : ?quotation-effect ( in -- effect/f )
 | 
					
						
							|  |  |  |     dup pair? [ second dup effect? [ drop f ] unless ] [ drop f ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :: declare-effect-d ( word effect variables branches n -- )
 | 
					
						
							|  |  |  |     meta-d length :> d-length | 
					
						
							|  |  |  |     n d-length < [ | 
					
						
							|  |  |  |         d-length 1 - n - :> n' | 
					
						
							|  |  |  |         n' meta-d nth :> value | 
					
						
							|  |  |  |         value known :> known | 
					
						
							|  |  |  |         known word effect variables branches <declared-effect> :> known' | 
					
						
							|  |  |  |         known' value set-known | 
					
						
							|  |  |  |         known' branches push
 | 
					
						
							|  |  |  |     ] [ word unknown-macro-input ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :: declare-input-effects ( word -- )
 | 
					
						
							|  |  |  |     H{ } clone :> variables | 
					
						
							|  |  |  |     V{ } clone :> branches | 
					
						
							|  |  |  |     word stack-effect in>> <reversed> [| in n | | 
					
						
							|  |  |  |         in ?quotation-effect [| effect | | 
					
						
							|  |  |  |             word effect variables branches n declare-effect-d | 
					
						
							|  |  |  |         ] when*
 | 
					
						
							|  |  |  |     ] each-index ;
 | 
					
						
							|  |  |  | 
 |