diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-03-16 23:18:25 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-03-16 23:18:25 -0700 |
commit | e84da36197b809c50a0c43cceb5c7b27b3d5733e (patch) | |
tree | 49ea25ca1b9299ae9c5c6b978a05a8d48e552f4b /match.c | |
parent | c1e94e69d1bea54330bd94371b101828b31e9add (diff) | |
download | txr-e84da36197b809c50a0c43cceb5c7b27b3d5733e.tar.gz txr-e84da36197b809c50a0c43cceb5c7b27b3d5733e.tar.bz2 txr-e84da36197b809c50a0c43cceb5c7b27b3d5733e.zip |
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).
Diffstat (limited to 'match.c')
-rw-r--r-- | match.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -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); |