| 
									
										
										
										
											2011-10-03 02:33:28 -04:00
										 |  |  | ! Copyright (C) 2003, 2011 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2011-11-30 19:02:37 -05:00
										 |  |  | USING: accessors assocs combinators combinators.private kernel | 
					
						
							|  |  |  | kernel.private make namespaces sequences vectors ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: continuations | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-03 19:10:21 -04:00
										 |  |  | : with-datastack ( stack quot -- new-stack )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [ [ datastack ] dip swap [ { } like set-datastack ] dip ] dip
 | 
					
						
							|  |  |  |         swap [ call datastack ] dip
 | 
					
						
							|  |  |  |         swap [ set-datastack ] dip
 | 
					
						
							| 
									
										
										
										
											2011-10-18 16:18:42 -04:00
										 |  |  |     ] ( stack quot -- new-stack ) call-effect-unsafe ;
 | 
					
						
							| 
									
										
										
										
											2010-04-03 19:10:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-30 05:33:34 -04:00
										 |  |  | SYMBOL: original-error | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | SYMBOL: error | 
					
						
							|  |  |  | SYMBOL: error-continuation | 
					
						
							| 
									
										
										
										
											2008-02-27 20:23:22 -05:00
										 |  |  | SYMBOL: error-thread | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | SYMBOL: restarts | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : catchstack* ( -- catchstack )
 | 
					
						
							| 
									
										
										
										
											2011-11-02 15:54:31 -04:00
										 |  |  |     CONTEXT-OBJ-CATCHSTACK context-object { vector } declare ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-22 04:12:15 -04:00
										 |  |  | ! We have to defeat some optimizations to make continuations work | 
					
						
							|  |  |  | : dummy-1 ( -- obj ) f ;
 | 
					
						
							| 
									
										
										
										
											2011-10-03 02:33:28 -04:00
										 |  |  | : dummy-2 ( obj -- obj ) ;
 | 
					
						
							| 
									
										
										
										
											2007-10-03 17:35:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-18 05:06:00 -04:00
										 |  |  | : catchstack ( -- catchstack ) catchstack* clone ; inline
 | 
					
						
							| 
									
										
										
										
											2008-02-27 20:23:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-18 05:06:00 -04:00
										 |  |  | : set-catchstack ( catchstack -- )
 | 
					
						
							| 
									
										
										
										
											2011-11-02 15:54:31 -04:00
										 |  |  |     >vector CONTEXT-OBJ-CATCHSTACK set-context-object ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-18 05:06:00 -04:00
										 |  |  | : init-catchstack ( -- ) f set-catchstack ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-18 05:06:00 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | TUPLE: continuation data call retain name catch ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | C: <continuation> continuation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : continuation ( -- continuation )
 | 
					
						
							|  |  |  |     datastack callstack retainstack namestack catchstack | 
					
						
							|  |  |  |     <continuation> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-18 05:06:00 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : >continuation< ( continuation -- data call retain name catch )
 | 
					
						
							| 
									
										
										
										
											2010-03-18 05:06:00 -04:00
										 |  |  |     { [ data>> ] [ call>> ] [ retain>> ] [ name>> ] [ catch>> ] } cleave ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  | : ifcc ( capture restore -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-23 03:44:56 -05:00
										 |  |  |     [ dummy-1 continuation ] 2dip [ dummy-2 ] prepose ?if ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  | : callcc0 ( quot -- ) [ drop ] ifcc ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  | : callcc1 ( quot -- obj ) [ ] ifcc ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-16 21:11:36 -04:00
										 |  |  | : (continue) ( continuation -- * )
 | 
					
						
							| 
									
										
										
										
											2009-04-17 00:14:11 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         >continuation< | 
					
						
							|  |  |  |         set-catchstack | 
					
						
							|  |  |  |         set-namestack
 | 
					
						
							|  |  |  |         set-retainstack | 
					
						
							|  |  |  |         [ set-datastack ] dip
 | 
					
						
							|  |  |  |         set-callstack | 
					
						
							| 
									
										
										
										
											2011-10-18 16:18:42 -04:00
										 |  |  |     ] ( continuation -- * ) call-effect-unsafe ;
 | 
					
						
							| 
									
										
										
										
											2009-04-13 00:01:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 21:27:05 -05:00
										 |  |  | : continue-with ( obj continuation -- * )
 | 
					
						
							| 
									
										
										
										
											2009-03-16 21:11:36 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2011-11-02 15:54:31 -04:00
										 |  |  |         swap OBJ-CALLCC-1 set-special-object | 
					
						
							| 
									
										
										
										
											2009-03-16 21:11:36 -04:00
										 |  |  |         >continuation< | 
					
						
							|  |  |  |         set-catchstack | 
					
						
							|  |  |  |         set-namestack
 | 
					
						
							|  |  |  |         set-retainstack | 
					
						
							| 
									
										
										
										
											2011-11-02 15:54:31 -04:00
										 |  |  |         [ | 
					
						
							|  |  |  |             set-datastack drop
 | 
					
						
							|  |  |  |             OBJ-CALLCC-1 special-object | 
					
						
							|  |  |  |             f OBJ-CALLCC-1 set-special-object | 
					
						
							|  |  |  |             f
 | 
					
						
							|  |  |  |         ] dip
 | 
					
						
							| 
									
										
										
										
											2009-03-16 21:11:36 -04:00
										 |  |  |         set-callstack | 
					
						
							| 
									
										
										
										
											2011-10-18 16:18:42 -04:00
										 |  |  |     ] ( obj continuation -- * ) call-effect-unsafe ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 21:27:05 -05:00
										 |  |  | : continue ( continuation -- * )
 | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  |     f swap continue-with ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-07 08:49:29 -04:00
										 |  |  | SYMBOL: return-continuation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : with-return ( quot -- )
 | 
					
						
							|  |  |  |     [ [ return-continuation set ] prepose callcc0 ] with-scope ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 21:27:05 -05:00
										 |  |  | : return ( -- * )
 | 
					
						
							| 
									
										
										
										
											2008-05-07 08:49:29 -04:00
										 |  |  |     return-continuation get continue ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | GENERIC: compute-restarts ( error -- seq )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : save-error ( error -- )
 | 
					
						
							| 
									
										
										
										
											2010-04-30 05:33:34 -04:00
										 |  |  |     [ error set-global ] | 
					
						
							|  |  |  |     [ compute-restarts restarts set-global ] bi ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 02:33:28 -04:00
										 |  |  | GENERIC: error-in-thread ( error thread -- * )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: thread-error-hook ! ( error thread -- ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | thread-error-hook [ [ die ] ] initialize
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 19:19:03 -04:00
										 |  |  | M: object error-in-thread ( error thread -- * )
 | 
					
						
							| 
									
										
										
										
											2011-10-03 02:33:28 -04:00
										 |  |  |     thread-error-hook get-global call( error thread -- * ) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-02 15:54:31 -04:00
										 |  |  | : in-callback? ( -- ? ) CONTEXT-OBJ-IN-CALLBACK-P context-object ;
 | 
					
						
							| 
									
										
										
										
											2011-10-03 02:33:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: callback-error-hook ! ( error -- * ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | callback-error-hook [ [ die ] ] initialize
 | 
					
						
							| 
									
										
										
										
											2008-02-18 06:07:40 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : rethrow ( error -- * )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 02:24:24 -05:00
										 |  |  |     dup save-error | 
					
						
							| 
									
										
										
										
											2011-10-03 02:33:28 -04:00
										 |  |  |     catchstack* [ | 
					
						
							|  |  |  |         in-callback?
 | 
					
						
							|  |  |  |         [ callback-error-hook get-global call( error -- * ) ] | 
					
						
							| 
									
										
										
										
											2011-11-02 15:54:31 -04:00
										 |  |  |         [ OBJ-CURRENT-THREAD special-object error-in-thread ] | 
					
						
							| 
									
										
										
										
											2011-10-03 02:33:28 -04:00
										 |  |  |         if
 | 
					
						
							|  |  |  |     ] [ pop continue-with ] if-empty ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-08 21:28:19 -05:00
										 |  |  | : recover ( ..a try: ( ..a -- ..b ) recovery: ( ..a error -- ..b ) -- ..b )
 | 
					
						
							| 
									
										
										
										
											2011-10-03 02:33:28 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             [ catchstack* push ] dip
 | 
					
						
							|  |  |  |             call
 | 
					
						
							|  |  |  |             catchstack* pop*
 | 
					
						
							|  |  |  |         ] curry
 | 
					
						
							|  |  |  |     ] dip ifcc ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-26 15:58:02 -05:00
										 |  |  | : ignore-errors ( quot -- )
 | 
					
						
							|  |  |  |     [ drop ] recover ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : cleanup ( try cleanup-always cleanup-error -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-23 03:44:56 -05:00
										 |  |  |     [ compose [ dip rethrow ] curry recover ] [ drop ] 2bi call ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-12 19:53:22 -04:00
										 |  |  | ERROR: attempt-all-error ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-08 21:28:19 -05:00
										 |  |  | : attempt-all ( ... seq quot: ( ... elt -- ... obj ) -- ... obj )
 | 
					
						
							| 
									
										
										
										
											2008-05-12 19:53:22 -04:00
										 |  |  |     over empty? [ | 
					
						
							|  |  |  |         attempt-all-error
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             [ [ , f ] compose [ , drop t ] recover ] curry all?
 | 
					
						
							| 
									
										
										
										
											2009-05-25 17:38:33 -04:00
										 |  |  |         ] { } make last swap [ rethrow ] when
 | 
					
						
							| 
									
										
										
										
											2008-05-12 19:53:22 -04:00
										 |  |  |     ] if ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  | TUPLE: condition error restarts continuation ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  | C: <condition> condition ( error restarts cc -- condition )
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : throw-restarts ( error restarts -- restart )
 | 
					
						
							|  |  |  |     [ <condition> throw ] callcc1 2nip ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : rethrow-restarts ( error restarts -- restart )
 | 
					
						
							|  |  |  |     [ <condition> rethrow ] callcc1 2nip ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-19 19:41:33 -05:00
										 |  |  | : throw-continue ( error -- )
 | 
					
						
							|  |  |  |     { { "Continue" t } } throw-restarts drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | TUPLE: restart name obj continuation ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | C: <restart> restart | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 21:27:05 -05:00
										 |  |  | : restart ( restart -- * )
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  |     [ obj>> ] [ continuation>> ] bi continue-with ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: object compute-restarts drop { } ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: condition compute-restarts | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  |     [ error>> compute-restarts ] | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [ restarts>> ] | 
					
						
							| 
									
										
										
										
											2008-08-31 08:45:33 -04:00
										 |  |  |         [ continuation>> [ <restart> ] curry ] bi
 | 
					
						
							| 
									
										
										
										
											2008-04-04 01:33:06 -04:00
										 |  |  |         { } assoc>map
 | 
					
						
							|  |  |  |     ] bi append ;
 | 
					
						
							| 
									
										
										
										
											2008-07-28 23:03:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : init-error-handler ( -- )
 | 
					
						
							| 
									
										
										
										
											2010-03-18 05:06:00 -04:00
										 |  |  |     init-catchstack | 
					
						
							| 
									
										
										
										
											2008-07-28 23:03:13 -04:00
										 |  |  |     ! VM calls on error | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2011-10-24 17:26:58 -04:00
										 |  |  |         ! 65 = self | 
					
						
							| 
									
										
										
										
											2011-11-02 15:54:31 -04:00
										 |  |  |         OBJ-CURRENT-THREAD special-object error-thread set-global
 | 
					
						
							| 
									
										
										
										
											2008-07-28 23:03:13 -04:00
										 |  |  |         continuation error-continuation set-global
 | 
					
						
							| 
									
										
										
										
											2010-04-30 05:33:34 -04:00
										 |  |  |         [ original-error set-global ] [ rethrow ] bi
 | 
					
						
							| 
									
										
										
										
											2011-11-02 15:54:31 -04:00
										 |  |  |     ] ERROR-HANDLER-QUOT set-special-object | 
					
						
							| 
									
										
										
										
											2008-07-28 23:03:13 -04:00
										 |  |  |     ! VM adds this to kernel errors, so that user-space | 
					
						
							|  |  |  |     ! can identify them | 
					
						
							| 
									
										
										
										
											2011-11-02 15:54:31 -04:00
										 |  |  |     "kernel-error" OBJ-ERROR set-special-object ;
 | 
					
						
							| 
									
										
										
										
											2008-07-28 23:03:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 |