summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisplib.c2
-rw-r--r--share/txr/stdlib/tagbody.tl9
-rw-r--r--txr.165
3 files changed, 75 insertions, 1 deletions
diff --git a/lisplib.c b/lisplib.c
index a7247693..76e142e8 100644
--- a/lisplib.c
+++ b/lisplib.c
@@ -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))))
diff --git a/txr.1 b/txr.1
index 78f72bf4..5f5d1ef9 100644
--- a/txr.1
+++ b/txr.1
@@ -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