X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=src%2Fscheme.4th;h=027a1938634e528fd8dadc2bee859d39bfc71c9a;hb=c775ab2562b213ac96fe1803d4e7001a73e874a8;hp=2edd16da5fc43309c34387e9c4eb10afa0770ed3;hpb=c6aa8bc94536cbac6a7df5ad6872131665aeefeb;p=scheme.forth.jl.git diff --git a/src/scheme.4th b/src/scheme.4th index 2edd16d..027a193 100644 --- a/src/scheme.4th +++ b/src/scheme.4th @@ -548,14 +548,19 @@ global-env obj! 2swap cons 2 +loop - depth 2- fixnum-type 2swap cons + depth 2- 2/ fixnum-type 2swap cons ; -: make-continuation +: make-continuation ( -- continuation true-obj ) + \ true-obj allows calling code to detect whether + \ it is being called immediately following make-continuation + \ or by a restore-continuation. cons-param-stack cons-return-stack cons drop continuation-type + + true boolean-type ; : continuation->pstack-list @@ -564,35 +569,85 @@ global-env obj! : continuation->rstack-list drop pair-type cdr ; -: restore-param-stack ( continuation -- obj_stack continuation ) +: stack-list-len ( stack-list -- n ) + car drop +; +: restore-param-stack ( continuation -- obj_stack ) continuation->pstack-list 2dup >R >R ( Allocate stack space first using psp!, then copy objects from list. ) - car drop + car drop 2* object-stack-base @ psp0 + + psp! R> R> 2dup cdr 2swap - car drop 2- 0 swap do + stack-list-len 1- 0 swap do 2dup car - PSP0 object-stack-base @ + i + 2 + ! - PSP0 object-stack-base @ + i + 1 + ! + PSP0 object-stack-base @ + i 2* + 2 + ! + PSP0 object-stack-base @ + i 2* + 1 + ! cdr - -2 +loop + -1 +loop 2drop +; + +( This word restores the return stack to that contained in the +continuation object, and thus NEVER RETURNS. ) +: restore-return-stack ( continuation -- ) + + continuation->rstack-list + + 2dup cdr 2swap stack-list-len ( list n ) + + dup RSP0 + RSP! \ expand return stack to accommodate entries + + ( list n ) + 1- \ initial offset n-1 + 0 \ final offset 0 + swap + do + 2dup cdr 2swap car drop + RSP0 i 1+ + ! + -1 +loop + + 2drop ; -: restore-continuation - \ TODO: replace current parameter and return stacks with - \ contents of continuation object. +( This word restores the parameter and return stacks +to those in the continuation object. The restoration of the +return stack means that execution continues at the point +described in the continuation object, so this word NEVER RETURNS. + +Note that both obj and a false-obj are added to the parameter +stack before the return stack is restored, so that make-continuation +knows that this execution path is the result of a continuation +restoration rather than the original call to make-continuation. ) +: restore-continuation-with-arg ( continuation obj -- ) + + >R >R \ Store obj on return stack + + 2dup >R >R \ Store copy of continuation on return stack + + restore-param-stack + + R> R> \ Pop continuation from return stack + + R> R> \ Pop obj from return stack + + 2swap + + false boolean-type \ Add flag signifying continuation restore + + 2swap + + restore-return-stack ; \ }}} @@ -1738,7 +1793,22 @@ parse-idx-stack parse-idx-sp ! endof continuation-type of - \ TODO: Apply continuation + 2swap + nil? if + except-message: ." Continuations expect exactly 1 argument." + recoverable-exception throw + then + + 2dup cdr + + nil? invert if + except-message: ." Continuations expect exactly 1 argument." + recoverable-exception throw + then + + 2drop car + + restore-continuation-with-arg endof except-message: ." object '" drop print ." ' not applicable." recoverable-exception throw @@ -2042,6 +2112,7 @@ parse-idx-stack parse-idx-sp ! symbol-type istype? if true exit then compound-proc-type istype? if true exit then port-type istype? if true exit then + continuation-type istype? if true exit then false ; @@ -2125,8 +2196,6 @@ parse-idx-stack parse-idx-sp ! \ }}} -xxxx - \ ---- Loading files ---- {{{ : load ( addr n -- finalResult )