summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-11-04 21:37:42 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-11-04 21:37:42 -0800
commit7deb862ac8925c4ced0246adbd79b353b88512d8 (patch)
treee33fdf8776ecf3cf638736ae5a552ee0f9a4ffc1 /share
parent8cdf0417090b2c6e6b29aa67c7b1efca5501bb7c (diff)
downloadtxr-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.tl38
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)