summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-03-16 23:18:25 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-03-16 23:18:25 -0700
commite84da36197b809c50a0c43cceb5c7b27b3d5733e (patch)
tree49ea25ca1b9299ae9c5c6b978a05a8d48e552f4b /match.c
parentc1e94e69d1bea54330bd94371b101828b31e9add (diff)
downloadtxr-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.c17
1 files changed, 16 insertions, 1 deletions
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);