summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-12-30 12:26:41 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-12-30 12:26:41 -0800
commitac08d22c2b916fbd88c938569e0cd6af488b7a67 (patch)
tree845a929d332f67cc7ec6bd5196b3acf3d52f69b7 /match.c
parent0b81b8b4c39b6c60cbbe8de5a6a785beb43c3dbb (diff)
downloadtxr-ac08d22c2b916fbd88c938569e0cd6af488b7a67.tar.gz
txr-ac08d22c2b916fbd88c938569e0cd6af488b7a67.tar.bz2
txr-ac08d22c2b916fbd88c938569e0cd6af488b7a67.zip
* match.c (counter_k): New keyword symbol variable.
(do_output_line): Process new :counter argument of rep. (do_output): Ditto, for repeat. (syms_init): Intern new keyword symbol. * match.h (counter_k): Declared. * parser.l (REPEAT, REP): Lexical syntax changed to allow arguments. * parser.y (repeat_rep_helper): Takes extra argument, representing the repeat/rep args. This is inserted into the second position of the output list. (repeat_clause, rep_elem): Extract repeat/rep arguments and pass to repeat_rep_helper. (yybadtoken): Do not put quotes around the word "number". * txr.1: Updated.
Diffstat (limited to 'match.c')
-rw-r--r--match.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/match.c b/match.c
index e87b7496..044e1300 100644
--- a/match.c
+++ b/match.c
@@ -58,7 +58,7 @@ val lines_k, chars_k;
val text_s, choose_s, gather_s, do_s, mod_s, modlast_s;
val longest_k, shortest_k, greedy_k;
val vars_k, resolve_k;
-val append_k, into_k, var_k, list_k, string_k, env_k;
+val append_k, into_k, var_k, list_k, string_k, env_k, counter_k;
val filter_s;
@@ -1534,6 +1534,7 @@ static void do_output_line(val bindings, val specline, val filter, val out)
put_string(out, str);
} else if (directive == rep_s) {
val clauses = cdr(elem);
+ val args = pop(&clauses);
val main_clauses = pop(&clauses);
val single_clauses = pop(&clauses);
val first_clauses = pop(&clauses);
@@ -1541,6 +1542,7 @@ 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 bind_cp = extract_bindings(bindings, elem);
val max_depth = reduce_left(func_n2(max2),
bind_cp, zero,
@@ -1548,18 +1550,30 @@ static void do_output_line(val bindings, val specline, val filter, val out)
func_n1(robust_length),
nao));
+ if (counter && !bindable(counter))
+ sem_error(elem, lit(":counter requires a bindable symbol, not ~s"),
+ counter, nao);
+
if (equal(max_depth, zero) && empty_clauses) {
do_output_line(nappend2(bind_cp, bindings), empty_clauses, filter, out);
} else if (equal(max_depth, one) && single_clauses) {
val bind_a = nappend2(mapcar(func_n1(bind_car), bind_cp), bindings);
do_output_line(bind_a, single_clauses, filter, out);
} else if (!zerop(max_depth)) {
+ val counter_var = if2(counter, cons(counter, nil));
+ val counter_bind = if2(counter, cons(counter_var, nil));
cnum i;
for (i = 0; i < c_num(max_depth); i++) {
val bind_a = nappend2(mapcar(func_n1(bind_car), bind_cp), bindings);
val bind_d = mapcar(func_n1(bind_cdr), bind_cp);
+ if (counter) {
+ rplacd(counter_var, num_fast(i));
+ rplacd(counter_bind, bind_a);
+ bind_a = counter_bind;
+ }
+
if (i == 0 && first_clauses) {
do_output_line(bind_a, first_clauses, filter, out);
} else if (i == c_num(max_depth) - 1 &&
@@ -1645,6 +1659,7 @@ static void do_output(val bindings, val specs, val filter, val out)
if (sym == repeat_s) {
val clauses = cdr(first_elem);
+ val args = pop(&clauses);
val main_clauses = pop(&clauses);
val single_clauses = pop(&clauses);
val first_clauses = pop(&clauses);
@@ -1652,6 +1667,7 @@ 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 bind_cp = extract_bindings(bindings, first_elem);
val max_depth = reduce_left(func_n2(max2),
bind_cp, zero,
@@ -1665,12 +1681,20 @@ static void do_output(val bindings, val specs, val filter, val out)
val bind_a = nappend2(mapcar(func_n1(bind_car), bind_cp), bindings);
do_output(bind_a, single_clauses, filter, out);
} else if (!zerop(max_depth)) {
+ val counter_var = if2(counter, cons(counter, nil));
+ val counter_bind = if2(counter, cons(counter_var, nil));
cnum i;
for (i = 0; i < c_num(max_depth); i++) {
val bind_a = nappend2(mapcar(func_n1(bind_car), bind_cp), bindings);
val bind_d = mapcar(func_n1(bind_cdr), bind_cp);
+ if (counter) {
+ rplacd(counter_var, num_fast(i));
+ rplacd(counter_bind, bind_a);
+ bind_a = counter_bind;
+ }
+
if (i == 0 && first_clauses) {
do_output(bind_a, first_clauses, filter, out);
} else if (i == c_num(max_depth) - 1 &&
@@ -3413,8 +3437,9 @@ static void syms_init(void)
filter_s = intern(lit("filter"), user_package);
noval_s = intern(lit("noval"), system_package);
- mod_s = intern(lit("mod"), system_package);
- modlast_s = intern(lit("modlast"), system_package);
+ mod_s = intern(lit("mod"), user_package);
+ modlast_s = intern(lit("modlast"), user_package);
+ counter_k = intern(lit("counter"), keyword_package);
}
static void dir_tables_init(void)