summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-12-08 07:16:00 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-12-08 07:16:00 -0800
commit1e4eadfd30f675f80e17e84682dfc88da6be9681 (patch)
treea1bc89f27d7d4c748f4189f974a95a59f1f933ce
parenta621bb39d04e1f77fc45c24a3ac3fc08291533fa (diff)
downloadtxr-1e4eadfd30f675f80e17e84682dfc88da6be9681.tar.gz
txr-1e4eadfd30f675f80e17e84682dfc88da6be9681.tar.bz2
txr-1e4eadfd30f675f80e17e84682dfc88da6be9681.zip
each-match macro family: missing anon block.
* txr.1: Adding the missing requirement that each-match and the other macros in that family must have an implicit anonymous block around the body forms. This is a requirements bug, effectively: the programmer expects these operators to be consistent with the each operator, as part of the same family. * match.tl (each-match-expander): Implement the requirement. Since we are using mapping functions, we must use temporary variables: the evaluation of the expressions which produce the sequence argument values to the mapping functions must be outside of the anonymous block. The block must surround only the function call. * tests/011/patmatch.tl: Add small test case covering this.
-rw-r--r--stdlib/match.tl7
-rw-r--r--tests/011/patmatch.tl3
-rw-r--r--txr.116
3 files changed, 22 insertions, 4 deletions
diff --git a/stdlib/match.tl b/stdlib/match.tl
index 8d014f11..a38798d6 100644
--- a/stdlib/match.tl
+++ b/stdlib/match.tl
@@ -1070,8 +1070,11 @@
(eql 2 (length pair)))
(compile-error f "invalid pattern-sequence pair ~s" pair)))
(let* ((pats [mapcar car pat-seq-pairs])
- (seqs [mapcar cadr pat-seq-pairs]))
- ^(,fun (lambda-match ((,*pats) (progn ,*body))) ,*seqs))))
+ (seqs [mapcar cadr pat-seq-pairs])
+ (gens [mapcar (ret (gensym)) pat-seq-pairs]))
+ ^(let ,(zip gens seqs)
+ (block nil
+ (,fun (lambda-match ((,*pats) (progn ,*body))) ,*gens))))))
(defmacro each-match (:form f pat-seq-pairs . body)
(each-match-expander f pat-seq-pairs body 'mapdo))
diff --git a/tests/011/patmatch.tl b/tests/011/patmatch.tl
index da2f8de4..fbdd3da0 100644
--- a/tests/011/patmatch.tl
+++ b/tests/011/patmatch.tl
@@ -470,6 +470,9 @@
(list x y))
((1 2) (1 4) (3 2) (3 4) (5 2) (5 4)))
+(test
+ (each-match (@a '(1 2 3)) (return 42)) 42)
+
(mtest
(when-match ^(,a ,b) '(1 2) (list a b)) (1 2)
(when-match ^(,(oddp @a) ,(evenp @b)) '(1 2) (list a b)) (1 2)
diff --git a/txr.1 b/txr.1
index 4c286a37..92e322bb 100644
--- a/txr.1
+++ b/txr.1
@@ -44707,6 +44707,14 @@ The remaining arguments are
.metn body-form s
to evaluated for successful matches.
+The
+.metn body-form s
+are surrounded by an implicit anonymous block. If any of the forms
+.code return
+invoke a return out of this block, then the iteration terminates, and
+the result value of the block becomes the result value of
+the loop.
+
The processing takes place as follows:
.RS
.IP 1.
@@ -44806,7 +44814,9 @@ The macro
.code append-matches
is subject to all of the requirements specified for
.code each-match
-in regard to the argument conventions and semantics.
+in regard to the argument conventions and semantics,
+and the presence of the implicit anonymous block around the
+.metn body-form s.
Whereas
.code each-match
@@ -44873,7 +44883,9 @@ The macro
.code keep-matches
is subject to all of the requirements specified for
.code each-match
-in regard to the argument conventions and semantics.
+in regard to the argument conventions and semantics,
+and the presence of the implicit anonymous block around the
+.metn body-form s.
Whereas
.code each-match