diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-11-04 21:37:42 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-11-04 21:37:42 -0800 |
commit | 7deb862ac8925c4ced0246adbd79b353b88512d8 (patch) | |
tree | e33fdf8776ecf3cf638736ae5a552ee0f9a4ffc1 /share | |
parent | 8cdf0417090b2c6e6b29aa67c7b1efca5501bb7c (diff) | |
download | txr-7deb862ac8925c4ced0246adbd79b353b88512d8.tar.gz txr-7deb862ac8925c4ced0246adbd79b353b88512d8.tar.bz2 txr-7deb862ac8925c4ced0246adbd79b353b88512d8.zip |
yield-from can omit form; access initial value.
* share/txr/stdlib/yield.tl (sys:rcv-item): New struct type.
(sys:obtain-impl): Handle rcv-item, produced by a no-argument
yield-from, which requests an immediate resumption with
the previously given resume value. The reply value
is renamed the resume value.
(yield-from, yield): Form argument is optional.
* txr.1: Rewrote obtain and yield documentation with
lesser focus on implementation and greater focus on
abstract semantics.
Diffstat (limited to 'share')
-rw-r--r-- | share/txr/stdlib/yield.tl | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/share/txr/stdlib/yield.tl b/share/txr/stdlib/yield.tl index 43fa57ee..d076267b 100644 --- a/share/txr/stdlib/yield.tl +++ b/share/txr/stdlib/yield.tl @@ -25,16 +25,23 @@ (defstruct (sys:yld-item val cont) nil val cont) +(defstruct (sys:rcv-item val cont) nil val cont) + (defun sys:obtain-impl (fun) (finalize - (lambda (: reply) - (let ((yi (call fun reply))) - (cond - ((eq (typeof yi) 'sys:yld-item) - (call fun 'sys:cont-free) - (set fun yi.cont) - yi.val) - (t yi)))) + (lambda (: resume-val) + (let ((yi (call fun resume-val))) + (while t + (cond + ((eq (typeof yi) 'sys:yld-item) + (call fun 'sys:cont-free) + (set fun yi.cont) + (return yi.val)) + ((eq (typeof yi) 'sys:rcv-item) + (call fun 'sys:cont-free) + (set fun yi.cont) + (set yi (call fun resume-val))) + (t (return yi)))))) (lambda (cont) (call cont 'sys:cont-poison)))) @@ -47,17 +54,22 @@ (defmacro obtain-block (name . body) ^(obtain (block ,name ,*body))) -(defmacro yield-from (:form ctx-form name form) +(defmacro yield-from (:form ctx-form name : (form nil have-form-p)) (let ((cont-sym (gensym))) ^(sys:capture-cont ',name (lambda (,cont-sym) (sys:abscond-from ,name - (new (sys:yld-item - ,form ,cont-sym)))) + ,(if have-form-p + ^(new (sys:yld-item + ,form ,cont-sym)) + ^(new (sys:rcv-item + nil ,cont-sym))))) ',ctx-form))) -(defmacro yield (form) - ^(yield-from nil ,form)) +(defmacro yield (: (form nil have-form-p)) + (if have-form-p + ^(yield-from nil ,form) + ^(yield-from nil))) (defmacro suspend (:form form name var . body) ^(sys:capture-cont ',name (lambda (,var) |