From a5f90cf8a467ac8817ab3db5c9f8190b7a547d67 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku <kaz@kylheku.com> Date: Fri, 22 Jan 2021 00:17:46 -0800 Subject: matcher: existing variables in @(all) now backref. This commit fixes the inadequacy that all variables occurring in a pattern under @(all ...) or @(coll ...) are blindly collated into lists, ignoring the fact that they may be previously bound variables that must back-reference and not be colleced into lists (just like in the TXR Pattern language!) * share/txr/stdlib/match.tl (compile-loop-match): Calculate the subset of variables in the pattern that have been freshly bound. Only generate the collection gensyms for those variables and only collect and nreverse those variables. * tests/011/patmatch.tl: Some test cases that backreference into an @(all). * txr.1: Documented. --- txr.1 | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'txr.1') diff --git a/txr.1 b/txr.1 index e2f88973..45800d08 100644 --- a/txr.1 +++ b/txr.1 @@ -40066,10 +40066,15 @@ is applied against every element of the sequence. The match is successful if .meta pattern matches every element. -Furthermore, in the case of a successful match, these operators take -each of the variables specified in the +Furthermore, in the case of a successful match, each variable that +is freshly bound by .meta pattern -and bind it to a list of the elements which that variable matched. +is converted into a list of all of the objects which that variable +encounters from all elements of the sequence. Those variables which already +have a binding from another +.meta pattern +are not converted to lists. Their existing values are merely required to match +each corresponding object they encounter. The difference between .code all @@ -40095,6 +40100,15 @@ operator behaves like a failed match when the sequence is empty. '((x 1 a) (x 2 b) (x 3 c)) (list a b)) --> ((1 2 3) (a b c)) + + ;; Match a two element list whose second element + ;; consists of nothing but zero or more repetitions + ;; of the first element. x is not turned into a list + ;; because it has a binding due to @x. + (when-match @(@x @(all x)) '(1 (1 1 1 1)) x) -> 1 + + ;; no match because of the 2 + (when-match @(@x @(all x)) '(1 (1 1 1 2)) x) -> nil .brev .coNP Pattern operator @ some @@ -40139,6 +40153,15 @@ is applied against every element of the sequence. The match is successful if .meta pattern matches at least one element. +Each variable that is freshly bound by the +.meta pattern +is converted into a list of all of the objects which that variable +encounters from the matching elements of the sequence. Those variables which +already have a binding from another +.meta pattern +are not converted to lists. Their existing values are merely required to match +each corresponding object they encounter. + Variables are extracted from all matching elements, and collected into parallel lists, just like with the .code @(all) -- cgit v1.2.3