diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-12-13 20:44:23 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-12-13 20:44:23 -0800 |
commit | 9ae286b5a405f52cd83a0d2f6f8ee348e86b824e (patch) | |
tree | 93f618f4fb32b4224a873e8e94dc85020b4e34f8 | |
parent | 4f0c5f1273cb756b886f3a63930e8aa8698aa5c2 (diff) | |
download | txr-9ae286b5a405f52cd83a0d2f6f8ee348e86b824e.tar.gz txr-9ae286b5a405f52cd83a0d2f6f8ee348e86b824e.tar.bz2 txr-9ae286b5a405f52cd83a0d2f6f8ee348e86b824e.zip |
Adding prog and prog* macros.
* lisplib.c (tagbody_set_entries): Add prog and prog* to
autoload list.
* share/txr/stdlib/tagbody.tl (prog, prog*): New macros.
* txr.1: Documented.
-rw-r--r-- | lisplib.c | 2 | ||||
-rw-r--r-- | share/txr/stdlib/tagbody.tl | 9 | ||||
-rw-r--r-- | txr.1 | 65 |
3 files changed, 75 insertions, 1 deletions
@@ -452,7 +452,7 @@ static val getput_instantiate(val set_fun) static val tagbody_set_entries(val dlt, val fun) { val name[] = { - lit("tagbody"), lit("go"), nil + lit("tagbody"), lit("go"), lit("prog"), lit("prog*"), nil }; set_dlt_entries(dlt, name, fun); return nil; diff --git a/share/txr/stdlib/tagbody.tl b/share/txr/stdlib/tagbody.tl index 7cfcd3f1..d3ca8a86 100644 --- a/share/txr/stdlib/tagbody.tl +++ b/share/txr/stdlib/tagbody.tl @@ -73,3 +73,12 @@ (if [[orf symbolp integerp chrp] label] (throwf 'eval-error "~s: no ~s label visible" 'go label) (throwf 'eval-error "~s: ~s isn't a symbol, integer or character" 'go label))) + + +(defmacro prog (vars . body) + ^(block nil + (let ,vars (tagbody ,*body)))) + +(defmacro prog* (vars . body) + ^(block nil + (let* ,vars (tagbody ,*body)))) @@ -14795,6 +14795,71 @@ characters are not supported. (prinl 'out)) .cble +.coNP Macros @ prog and @ prog* +.synb +.mets (prog >> ({ sym | >> ( sym << init-form )}*) +.mets \ \ >> { body-form | << label }*) +.mets (prog* >> ({ sym | >> ( sym << init-form )}*) +.mets \ \ >> { body-form | << label }*) +.syne +.desc +The +.code prog +and +.code progn* +macros combine the features of +.code let +and +.codn let* , +respectively, +anonymous block and +.codn tagbody . + +The +.code prog +macro treats the +.meta sym +and +.code init-form +expressions similarly to +.codn let , +establishing variable bindings in parallel. +The +.code prog* +macro treats these expressions in a similar way to +.codn let* . + +The forms enclosed are treated like the argument forms of the +.code tagbody +macro: labels are permitted, along with use of +.codn go . + +Finally, an anonymous block is established around all of the enclosed +forms (both the +.metn init-form -s +and +.metn body-forms -s) +allowing the use of +.code return +to terminate evaluation with a value. + +The +.code prog +macro may be understood according to the following equivalence: + +.cblk + (prog vars forms ...) <--> (block nil + (let vars + (tagbody forms ...))) +.cble + +Likewise, the +.code prog* +macro follows an analogous equivalence, with +.code let +replaced by +.codn let* . + .SS* Evaluation .coNP Function @ eval |