| 
									
										
										
										
											2008-02-06 14:47:19 -05:00
										 |  |  | ! Copyright (C) 2003, 2008 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | USING: arrays vectors kernel kernel.private sequences | 
					
						
							| 
									
										
										
										
											2008-09-10 21:07:00 -04:00
										 |  |  | namespaces make math splitting sorting quotations assocs | 
					
						
							| 
									
										
										
										
											2008-03-29 01:59:05 -04:00
										 |  |  | combinators accessors ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: continuations | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 )
 | 
					
						
							|  |  |  |     1 getenv { vector } declare ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : >c ( continuation -- ) catchstack* push ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : c> ( -- continuation ) catchstack* pop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-22 04:12:15 -04:00
										 |  |  | ! We have to defeat some optimizations to make continuations work | 
					
						
							|  |  |  | : dummy-1 ( -- obj ) f ;
 | 
					
						
							|  |  |  | : dummy-2 ( obj -- obj ) dup drop ;
 | 
					
						
							| 
									
										
										
										
											2007-10-03 17:35:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-08 16:32:55 -04:00
										 |  |  | : init-catchstack ( -- ) V{ } clone 1 setenv ;
 | 
					
						
							| 
									
										
										
										
											2008-02-27 20:23:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : catchstack ( -- catchstack ) catchstack* clone ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : set-catchstack ( catchstack -- ) >vector 1 setenv ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: continuation data call retain name catch ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | C: <continuation> continuation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : continuation ( -- continuation )
 | 
					
						
							|  |  |  |     datastack callstack retainstack namestack catchstack | 
					
						
							|  |  |  |     <continuation> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : >continuation< ( continuation -- data call retain name catch )
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-03-29 01:59:05 -04:00
										 |  |  |         [ data>>   ] | 
					
						
							|  |  |  |         [ call>>   ] | 
					
						
							|  |  |  |         [ retain>> ] | 
					
						
							|  |  |  |         [ name>>   ] | 
					
						
							|  |  |  |         [ catch>>  ] | 
					
						
							|  |  |  |     } cleave ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  | : ifcc ( capture restore -- )
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     #! After continuation is being captured, the stacks looks | 
					
						
							|  |  |  |     #! like: | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  |     #! ( f continuation r:capture r:restore ) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     #! so the 'capture' branch is taken. | 
					
						
							|  |  |  |     #!
 | 
					
						
							|  |  |  |     #! Note that the continuation itself is not captured as part | 
					
						
							|  |  |  |     #! of the datastack. | 
					
						
							|  |  |  |     #!
 | 
					
						
							|  |  |  |     #! BUT... | 
					
						
							|  |  |  |     #!
 | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  |     #! After the continuation is resumed, (continue-with) pushes | 
					
						
							|  |  |  |     #! the given value together with f, | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     #! so now, the stacks looks like: | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  |     #! ( value f r:capture r:restore ) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     #! Execution begins right after the call to 'continuation'. | 
					
						
							|  |  |  |     #! The 'restore' branch is taken. | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-05 01:08:18 -04:00
										 |  |  | : (continue) ( continuation -- )
 | 
					
						
							|  |  |  |     >continuation< | 
					
						
							|  |  |  |     set-catchstack | 
					
						
							|  |  |  |     set-namestack
 | 
					
						
							|  |  |  |     set-retainstack | 
					
						
							| 
									
										
										
										
											2008-11-23 03:44:56 -05:00
										 |  |  |     [ set-datastack ] dip
 | 
					
						
							| 
									
										
										
										
											2007-10-05 01:08:18 -04:00
										 |  |  |     set-callstack ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  | : (continue-with) ( obj continuation -- )
 | 
					
						
							|  |  |  |     swap 4 setenv | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     >continuation< | 
					
						
							|  |  |  |     set-catchstack | 
					
						
							|  |  |  |     set-namestack
 | 
					
						
							|  |  |  |     set-retainstack | 
					
						
							| 
									
										
										
										
											2008-11-23 03:44:56 -05:00
										 |  |  |     [ set-datastack drop 4 getenv f 4 setenv f ] dip
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     set-callstack ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-23 21:27:05 -05:00
										 |  |  | : continue-with ( obj continuation -- * )
 | 
					
						
							| 
									
										
										
										
											2008-02-20 00:17:59 -05:00
										 |  |  |     [ (continue-with) ] 2 (throw) ;
 | 
					
						
							| 
									
										
										
										
											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 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-22 22:25:49 -04:00
										 |  |  | : with-datastack ( stack quot -- newstack )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             [ [ { } like set-datastack ] dip call datastack ] dip
 | 
					
						
							|  |  |  |             continue-with
 | 
					
						
							|  |  |  |         ] 3 (throw) | 
					
						
							|  |  |  |     ] callcc1 2nip ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-05 09:25:26 -05:00
										 |  |  | : assert-depth ( quot -- )
 | 
					
						
							|  |  |  |     { } swap with-datastack { } assert= ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | GENERIC: compute-restarts ( error -- seq )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : save-error ( error -- )
 | 
					
						
							|  |  |  |     dup error set-global
 | 
					
						
							|  |  |  |     compute-restarts restarts set-global ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-18 06:07:40 -05:00
										 |  |  | SYMBOL: thread-error-hook | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : rethrow ( error -- * )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 02:24:24 -05:00
										 |  |  |     dup save-error | 
					
						
							| 
									
										
										
										
											2008-02-18 06:07:40 -05:00
										 |  |  |     catchstack* empty? [ | 
					
						
							|  |  |  |         thread-error-hook get-global
 | 
					
						
							|  |  |  |         [ 1 (throw) ] [ die ] if*
 | 
					
						
							|  |  |  |     ] when
 | 
					
						
							| 
									
										
										
										
											2008-02-21 02:24:24 -05:00
										 |  |  |     c> continue-with ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : recover ( try recovery -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-23 03:44:56 -05:00
										 |  |  |     [ [ swap >c call c> drop ] 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 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | : attempt-all ( seq quot -- obj )
 | 
					
						
							| 
									
										
										
										
											2008-05-12 19:53:22 -04:00
										 |  |  |     over empty? [ | 
					
						
							|  |  |  |         attempt-all-error
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             [ [ , f ] compose [ , drop t ] recover ] curry all?
 | 
					
						
							|  |  |  |         ] { } make peek swap [ rethrow ] when
 | 
					
						
							|  |  |  |     ] if ; inline
 | 
					
						
							| 
									
										
										
										
											2008-12-03 09:32:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : retry ( quot: ( -- ? )  n -- ) swap [ drop ] prepose attempt-all ; 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 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 ( -- )
 | 
					
						
							|  |  |  |     V{ } clone set-catchstack | 
					
						
							|  |  |  |     ! VM calls on error | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         ! 63 = self | 
					
						
							|  |  |  |         63 getenv error-thread set-global
 | 
					
						
							|  |  |  |         continuation error-continuation set-global
 | 
					
						
							|  |  |  |         rethrow
 | 
					
						
							|  |  |  |     ] 5 setenv | 
					
						
							|  |  |  |     ! VM adds this to kernel errors, so that user-space | 
					
						
							|  |  |  |     ! can identify them | 
					
						
							|  |  |  |     "kernel-error" 6 setenv ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 |