diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-10-17 21:17:11 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-10-17 21:17:11 -0700 |
commit | 43b4d36e37ca650cdf70568240ccc041b20306bd (patch) | |
tree | cd2600fcd8f859636399e88eafbf55a11217a5b5 | |
parent | a1b531c559cf06722ce30e04afe7295b2d143ce4 (diff) | |
download | txr-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-- | ChangeLog | 12 | ||||
-rw-r--r-- | match.c | 16 | ||||
-rw-r--r-- | txr.1 | 55 |
3 files changed, 81 insertions, 2 deletions
@@ -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. @@ -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)) { @@ -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 |