summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2013-10-06 20:39:10 -0700
committerKaz Kylheku <kaz@kylheku.com>2013-10-06 20:39:10 -0700
commit7c8c8d326bbb8b9725efa6a3c364d3426a7cdca9 (patch)
tree86984ce58ca520cd3402fb9b77732d24f8046735
parent7a7b1d26622b2f7df03b60847f622111296b008d (diff)
downloadtxr-7c8c8d326bbb8b9725efa6a3c364d3426a7cdca9.tar.gz
txr-7c8c8d326bbb8b9725efa6a3c364d3426a7cdca9.tar.bz2
txr-7c8c8d326bbb8b9725efa6a3c364d3426a7cdca9.zip
New feature: :vars argument in repeat and rep directives in an output
block, for specifying variables to include in iteration whose presence repeat is not able to deduce. * match.c (extract_bindings): New argument, vars, specifies additional variables to consider. (do_output_line, do_output): Process :vars argument of repeat and rep directive. * txr.1: Updated.
-rw-r--r--ChangeLog13
-rw-r--r--match.c10
-rw-r--r--txr.148
3 files changed, 62 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f7511e4..c6023a90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2013-10-06 Kaz Kylheku <kaz@kylheku.com>
+
+ New feature: :vars argument in repeat and rep directives in an output
+ block, for specifying variables to include in iteration whose
+ presence repeat is not able to deduce.
+
+ * match.c (extract_bindings): New argument, vars, specifies
+ additional variables to consider.
+ (do_output_line, do_output): Process :vars argument of repeat
+ and rep directive.
+
+ * txr.1: Updated.
+
2013-08-09 Kaz Kylheku <kaz@kylheku.com>
* filter.c, utf8.c: Tabs changed to spaces. For some reason, filter.c
diff --git a/match.c b/match.c
index 612276bb..c692dbf8 100644
--- a/match.c
+++ b/match.c
@@ -1579,10 +1579,10 @@ static val extract_vars(val output_spec)
return vars;
}
-static val extract_bindings(val bindings, val output_spec)
+static val extract_bindings(val bindings, val output_spec, val vars)
{
list_collect_decl (bindings_out, ptail);
- val var_list = extract_vars(output_spec);
+ val var_list = nappend2(vars, extract_vars(output_spec));
for (; bindings; bindings = cdr(bindings)) {
val binding = car(bindings);
@@ -1627,7 +1627,8 @@ static void do_output_line(val bindings, val specline, val filter, val out)
val mod_clauses = pop(&clauses);
val modlast_clauses = pop(&clauses);
val counter = getplist(args, counter_k);
- val bind_cp = extract_bindings(bindings, elem);
+ val vars = getplist(args, vars_k);
+ val bind_cp = extract_bindings(bindings, elem, vars);
val max_depth = reduce_left(func_n2(max2),
bind_cp, zero,
chain(func_n1(cdr),
@@ -1752,7 +1753,8 @@ static void do_output(val bindings, val specs, val filter, val out)
val mod_clauses = pop(&clauses);
val modlast_clauses = pop(&clauses);
val counter = getplist(args, counter_k);
- val bind_cp = extract_bindings(bindings, first_elem);
+ val vars = getplist(args, vars_k);
+ val bind_cp = extract_bindings(bindings, first_elem, vars);
val max_depth = reduce_left(func_n2(max2),
bind_cp, zero,
chain(func_n1(cdr),
diff --git a/txr.1 b/txr.1
index de969bf5..15dc65f3 100644
--- a/txr.1
+++ b/txr.1
@@ -3789,13 +3789,49 @@ are none, or none of them activate, then @(last) is considered. If none
of those clauses are present or apply, then the repetition is processed
using the main clause.
-Repeat supports an optional keyword argument:
+Repeat supports arguments.
- @(repeat [:counter <symbol>])
+ @(repeat [:counter <symbol>] [:vars (<symbol>*)])
-This designates a symbol which will behave as an integer variable over the
-scope of the clauses inside the repeat. The variable provides access to the
-reptition count, starting at zero, incrementing with each repetition.
+The :counter argumnt designates a symbol which will behave as an integer
+variable over the scope of the clauses inside the repeat. The variable provides
+access to the reptition count, starting at zero, incrementing with each
+repetition.
+
+The :vars argument specifies a list of variables. The repeat directive
+will pick out from this list those variables which have bindings.
+It will assume that all these variables occur in the repeat block and
+are to be iterated. This syntax is needed for situations in which @(repeat)
+is not able to deduce the existence of a variable in the block.
+It does not dig very deeply to discover variables, and does not "see"
+variables that are referenced via embedded TXR Lisp expressions.
+For instance, the following produces no output:
+
+ @(bind list ("a" "b" "c"))
+ @(output)
+ @(repeat)
+ @(format nil "<~a>" list)
+ @(end)
+ @(end)
+
+Although the list variable appears in the repeat block, it is embedded
+in a TXR Lisp construct. That construct will never be evaluated because
+no repetitions take place: the repeat construct doesn't find any variables
+and so doesn't iterate. The remedy is to provide a little help via
+the :vars parameter:
+
+ @(bind list ("a" "b" "c"))
+ @(output)
+ @(repeat :vars (list))
+ @(format nil "<~a>" list)
+ @(end)
+ @(end)
+
+Now the repeat block iterates over list and the output is:
+
+ <a>
+ <b>
+ <c>
.SS Nested Repeats
@@ -3823,6 +3859,8 @@ but everything is specified within one line:
More than one @(rep) can occur within a line, mixed with other material.
A @(rep) can be nested within a @(repeat) or within another @(rep).
+Also, @(rep) accepts the same :counter and :vars arguments.
+
.SS Repeat and Rep Examples
Example 1: show the list L in parentheses, with spaces between