diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | match.c | 2 | ||||
-rw-r--r-- | tests/000/binding.expected | 6 | ||||
-rw-r--r-- | tests/000/binding.txr | 5 | ||||
-rw-r--r-- | txr.1 | 76 |
5 files changed, 79 insertions, 11 deletions
@@ -370,6 +370,7 @@ TESTS_OK := $(addprefix tst/,\ tests: $(TESTS_OK) $(V)echo "** tests passed!" +tst/tests/000/binding.ok: TXR_OPTS := -B tst/tests/001/%: TXR_ARGS := tests/001/data tst/tests/001/query-1.ok: TXR_OPTS := -B tst/tests/001/query-2.ok: TXR_OPTS := -B @@ -3707,7 +3707,7 @@ static val v_rebind(match_files_ctx *c) val form = second(args); val val = txeval(specline, form, c->bindings); - c->bindings = alist_remove(c->bindings, args); + c->bindings = alist_remove(c->bindings, flatten(pattern)); c->bindings = dest_bind(specline, c->bindings, pattern, val, equal_f); diff --git a/tests/000/binding.expected b/tests/000/binding.expected new file mode 100644 index 00000000..9e5303f0 --- /dev/null +++ b/tests/000/binding.expected @@ -0,0 +1,6 @@ +x="1" +y="2" +z[0]="1" +z[1]="2" +a="1" +b="0" diff --git a/tests/000/binding.txr b/tests/000/binding.txr new file mode 100644 index 00000000..95faa20d --- /dev/null +++ b/tests/000/binding.txr @@ -0,0 +1,5 @@ +@(bind x 1) +@(bind y 2) +@(rebind z (x y)) +@(bind (a b) (0 1)) +@(rebind (a b) (b a)) @@ -6857,6 +6857,14 @@ produce equal values. .dir set +The syntax of the +.code set +directive is: + +.mono +.mets @(set < pattern << bind-expression ) +.onom + The .code set directive syntactically resembles @@ -6939,21 +6947,45 @@ Because it is preceded by the .code @ escape, it is a Lisp variable, and not a pattern variable. +The +.code set +directive also doesn't support Lisp expressions in the +.metn pattern , +which must consist only of variables. + .dir rebind +The syntax of the +.code rebind +directive is: + +.mono +.mets @(rebind < pattern << bind-expression ) +.onom + The .code rebind directive resembles -.code set -but it is not an assignment. +.codn bind . It combines the semantics of -.codn local , -.code bind +.code local and -.codn set . -The expression on the right hand side is evaluated in the current -environment. Then the variables in the pattern on the left are introduced -as new bindings, whose values come from the pattern. +.code bind +into a single directive. +The +.meta bind-expression +is evaluated in the current +environment, and its value remembered. Then a new +environment is produced in which all the variables specified in +.meta pattern +are absent. Then, the pattern is newly bound in +that environment against the previously produced value, as if using +.codn bind . + +The old environment with the previous variables is not modified; +it continues to exist. This is in contrast with the +.code set +directive, which mutates existing bindings. .code rebind makes it easy to create temporary bindings based on existing bindings. @@ -6967,8 +6999,8 @@ makes it easy to create temporary bindings based on existing bindings. .brev When the function terminates, the previous value of recursion-level -is restored. The effect is like the following, but much easier -to write and faster to execute: +is restored. The effect is less verbose and more efficient than +the following equivalent .verb @(define pattern-function (arg)) @@ -6981,6 +7013,30 @@ to write and faster to execute: @(end) .brev +Like +.codn bind , +.code rebind +supports nested patterns, such as + +.verb + @(rebind (a (b c)) (1 (2 3)) +.brev + +but it does not support any keyword arguments. The filtering +features of +.code bind +do not make sense in +.code rebind +because the variables are always re-introduced into an environment +in which they don't exist, whereas filtering applies in +situations when bound variables are matched against values. + +The +.code rebind +directive also doesn't support Lisp expressions in the +.metn pattern , +which must consist only of variables. + .dir forget The |