From e84da36197b809c50a0c43cceb5c7b27b3d5733e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 16 Mar 2016 23:18:25 -0700 Subject: Support binding in @(repeat)/@(rep) :vars. * match.c (extract_bindings): Check for (var expr) syntax, evaluate and bind. * match.h (vars_k): Declared. * parser.y (expand_repeat_rep_args): New static function. (repeat_rep_helper): The :counter and :var arguments of repeat/rep must be macro-expanded, since there can be Lisp expressions there. This supports the new feature, but also fixes the bug of :counter (var form) not expanding form. * txr.1: Updated documentation about :vars in @(repeat). --- match.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'match.c') diff --git a/match.c b/match.c index 5c2ce188..4e5ed362 100644 --- a/match.c +++ b/match.c @@ -47,6 +47,7 @@ #include "hash.h" #include "debug.h" #include "eval.h" +#include "cadr.h" #include "match.h" int opt_print_bindings = 0; @@ -1617,7 +1618,21 @@ static val extract_vars(val output_spec) static val extract_bindings(val bindings, val output_spec, val vars) { list_collect_decl (bindings_out, ptail); - val var_list = nappend2(extract_vars(output_spec), vars); + list_collect_decl (var_list, vtail); + + vtail = list_collect_nconc(vtail, extract_vars(output_spec)); + + for (; vars; vars = cdr(vars)) { + val var = car(vars); + if (consp(var)) { + val form = cadr(var); + val value = eval_with_bindings(form, output_spec, bindings, form); + bindings = cons(cons(car(var), value), bindings); + vtail = list_collect(vtail, car(var)); + } else { + vtail = list_collect(vtail, var); + } + } for (; bindings; bindings = cdr(bindings)) { val binding = car(bindings); -- cgit v1.2.3