diff options
-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 |