summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-10-17 21:17:11 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-10-17 21:17:11 -0700
commit43b4d36e37ca650cdf70568240ccc041b20306bd (patch)
treecd2600fcd8f859636399e88eafbf55a11217a5b5
parenta1b531c559cf06722ce30e04afe7295b2d143ce4 (diff)
downloadtxr-43b4d36e37ca650cdf70568240ccc041b20306bd.tar.gz
txr-43b4d36e37ca650cdf70568240ccc041b20306bd.tar.bz2
txr-43b4d36e37ca650cdf70568240ccc041b20306bd.zip
* match.c (dest_bind): Remove the restriction of not allowing
@(expr ...) and @var on the left side of a bind. This is useful, and necessary for @(line @(lisp expr)) to work: matching computed line numbers and character positions. * txr.1: Document use of Lisp on left hand side of bind, that there is a restriction on the left hand side of a set, and that Lisp can be used in a line or chr directive for computed matches.
-rw-r--r--ChangeLog12
-rw-r--r--match.c16
-rw-r--r--txr.155
3 files changed, 81 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 5d876612..6453947e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2014-10-17 Kaz Kylheku <kaz@kylheku.com>
+ * match.c (dest_bind): Remove the restriction of not allowing
+ @(expr ...) and @var on the left side of a bind. This
+ is useful, and necessary for @(line @(lisp expr)) to work:
+ matching computed line numbers and character positions.
+
+ * txr.1: Document use of Lisp on left hand side of bind,
+ that there is a restriction on the left hand side of a set,
+ and that Lisp can be used in a line or chr directive for
+ computed matches.
+
+2014-10-17 Kaz Kylheku <kaz@kylheku.com>
+
* HACKING: New section Type Safety.
Table of contents regenerated with line numbers.
diff --git a/match.c b/match.c
index 95328b32..9e699646 100644
--- a/match.c
+++ b/match.c
@@ -296,15 +296,27 @@ static val dest_bind(val spec, val bindings, val pattern,
}
} else if (consp(pattern)) {
val piter = pattern, viter = value;
+ val lisp_evaled = nil;
+ val ret;
if (first(pattern) == var_s) {
- sem_error(spec, lit("metavariable @~a syntax cannot be used here"), second(pattern), nao);
+ uw_env_begin;
+ uw_set_match_context(cons(spec, bindings));
+ ret = eval(second(pattern), make_env(bindings, nil, nil), pattern);
+ lisp_evaled = t;
+ uw_env_end;
}
if (first(pattern) == expr_s) {
- sem_error(spec, lit("the @~s syntax cannot be used here"), rest(pattern), nao);
+ uw_env_begin;
+ uw_set_match_context(cons(spec, bindings));
+ ret = eval(rest(pattern), make_env(bindings, nil, nil), pattern);
+ lisp_evaled = t;
+ uw_env_end;
}
+ if (lisp_evaled)
+ return if3(tree_find(value, ret, swap_12_21(testfun)), bindings, t);
while (consp(piter) && consp(viter))
{
diff --git a/txr.1 b/txr.1
index 4541c485..006d3b0a 100644
--- a/txr.1
+++ b/txr.1
@@ -3678,6 +3678,19 @@ takes the entire line of input:
@(chr 0)@(chr 0)@x
.cble
+The argument of
+.code line
+or
+.code chr
+may be a
+.codn @ -delimited
+Lisp expression. This is useful for matching computed lines or
+character positions:
+
+.cblk
+ @(line @(+ a (* b c)))
+.cble
+
.dirs some all none maybe cases choose
These directives, called the parallel directives, combine multiple subqueries,
@@ -5351,6 +5364,33 @@ matches
.str c
if these are upcased.
+.coNP Lisp forms in the @ bind directive
+
+\*(TL forms, introduced by
+.code @
+may be used on either side of
+.codn bind .
+
+
+Example:
+
+.cblk
+ @(bind a @(+ 2 2))
+ @(bind @(+ 2 2) @(* 2 2))
+.cble
+
+Here,
+.code a
+is bound to the integer
+.codn 4 .
+The second
+.code bind
+then succeeds because the forms
+.code (+ 2 2)
+and
+.code (* 2 2)
+produce equal values.
+
.dir set
The
@@ -5420,6 +5460,21 @@ binds to
@(set (A B . C) D)
.cble
+Note that
+.code set
+does not support a \*(TL expression on the left side, so the following
+are invalid syntax:
+
+.cblk
+ @(set @(+ 1 1) @(* 2 2))
+ @(set @b @(list "a"))
+.cble
+
+The second one is erroneous even though there is a variable on the left.
+Because it is preceded by the
+.code @
+escape, it is a Lisp variable, and not a pattern variable.
+
.dir rebind
The