From 7aacecd153ecfdd7b5c480dc419d4823e896ef1c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 23 Dec 2015 06:53:22 -0800 Subject: Base value in :counter * match.c (do_output_line, do_output): Decode (var expr) syntax as argument of :counter and implement displacement. * txr.1: Documented. --- match.c | 22 ++++++++++++++++++---- txr.1 | 17 +++++++++++++++-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/match.c b/match.c index cf648a9f..999d971b 100644 --- a/match.c +++ b/match.c @@ -1786,7 +1786,14 @@ static void do_output_line(val bindings, val specline, val filter, val out) val empty_clauses = pop(&clauses); val mod_clauses = pop(&clauses); val modlast_clauses = pop(&clauses); - val counter = getplist(args, counter_k); + val counter_spec = getplist(args, counter_k); + val consp_counter = consp(counter_spec); + val counter = if3(consp_counter, first(counter_spec), counter_spec); + val counter_base = if3(consp_counter, + eval_with_bindings(second(counter_spec), + elem, + bindings, + counter_spec), zero); val vars = getplist(args, vars_k); val bind_cp = extract_bindings(bindings, elem, vars); val max_depth = reduce_left(func_n2(max2), @@ -1814,7 +1821,7 @@ static void do_output_line(val bindings, val specline, val filter, val out) val bind_d = mapcar(func_n1(bind_cdr), bind_cp); if (counter) { - rplacd(counter_var, num_fast(i)); + rplacd(counter_var, plus(num_fast(i), counter_base)); rplacd(counter_bind, bind_a); bind_a = counter_bind; } @@ -1923,7 +1930,14 @@ static void do_output(val bindings, val specs, val filter, val out) val empty_clauses = pop(&clauses); val mod_clauses = pop(&clauses); val modlast_clauses = pop(&clauses); - val counter = getplist(args, counter_k); + val counter_spec = getplist(args, counter_k); + val consp_counter = consp(counter_spec); + val counter = if3(consp_counter, first(counter_spec), counter_spec); + val counter_base = if3(consp_counter, + eval_with_bindings(second(counter_spec), + first_elem, + bindings, + counter_spec), zero); val vars = getplist(args, vars_k); val bind_cp = extract_bindings(bindings, first_elem, vars); val max_depth = reduce_left(func_n2(max2), @@ -1947,7 +1961,7 @@ static void do_output(val bindings, val specs, val filter, val out) val bind_d = mapcar(func_n1(bind_cdr), bind_cp); if (counter) { - rplacd(counter_var, num_fast(i)); + rplacd(counter_var, plus(num_fast(i), counter_base)); rplacd(counter_bind, bind_a); bind_a = counter_bind; } diff --git a/txr.1 b/txr.1 index dfcbdf1f..27e72bcd 100644 --- a/txr.1 +++ b/txr.1 @@ -7488,7 +7488,9 @@ using the main clause. Repeat supports arguments. .cblk -.mets @(repeat [:counter << symbol ] [:vars <> ( symbol *)]) +.mets @(repeat +.mets \ \ \ [:counter >> { symbol | >> ( symbol << expr )}] +.mets \ \ \ [:vars <> ( symbol *)]) .cble The @@ -7496,7 +7498,18 @@ The argument 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 repetition count, starting at zero, incrementing with each -repetition. +repetition. If the the argument is given as +.cblk +.meti >> ( symbol << expr ) +.cblk +then +.meta expr +is a Lisp expression whose value is taken as a displacement value which +is added to each iteration of the counter. For instance +.code :counter (c 1) +specifies a counter +.code c +which counts from 1. The .code :vars -- cgit v1.2.3