From 7c8c8d326bbb8b9725efa6a3c364d3426a7cdca9 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 6 Oct 2013 20:39:10 -0700 Subject: 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. --- ChangeLog | 13 +++++++++++++ match.c | 10 ++++++---- txr.1 | 48 +++++++++++++++++++++++++++++++++++++++++++----- 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 + + 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 * 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 ]) + @(repeat [:counter ] [:vars (*)]) -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: + + + + .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 -- cgit v1.2.3