diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2011-10-08 21:15:34 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2011-10-08 21:15:34 -0700 |
commit | e4f1c4c7efa33df19a22cc577c93e590ca99543b (patch) | |
tree | 8f4f7cc5b92a717e5e94da2b742f03460bb5c0cc /match.c | |
parent | 9b352a96e064d5d201e2d448f9650a0dd9d67b68 (diff) | |
download | txr-e4f1c4c7efa33df19a22cc577c93e590ca99543b.tar.gz txr-e4f1c4c7efa33df19a22cc577c93e590ca99543b.tar.bz2 txr-e4f1c4c7efa33df19a22cc577c93e590ca99543b.zip |
* match.c (vars_k): New symbol variable.
(match_files): Implemented :vars in collect.
(match_init): New symbol variable initialized.
Diffstat (limited to 'match.c')
-rw-r--r-- | match.c | 45 |
1 files changed, 42 insertions, 3 deletions
@@ -50,6 +50,7 @@ int output_produced; val mingap_k, maxgap_k, gap_k, mintimes_k, maxtimes_k, times_k; val lines_k, chars_k; val choose_s, longest_k, shortest_k, greedy_k; +val vars_k; static void debugf(val fmt, ...) { @@ -1637,6 +1638,7 @@ repeat_spec_same_data: val mintimes = getplist(args, mintimes_k); val maxtimes = getplist(args, maxtimes_k); val lines = getplist(args, lines_k); + val vars = getplist(args, vars_k); cnum cmax = nump(gap) ? c_num(gap) : (nump(max) ? c_num(max) : 0); cnum cmin = nump(gap) ? c_num(gap) : (nump(min) ? c_num(min) : 0); cnum mincounter = cmin, maxcounter = 0; @@ -1652,6 +1654,24 @@ repeat_spec_same_data: if (gap && (max || min)) sem_error(spec_linenum, lit("collect: cannot mix :gap with :mingap or :maxgap"), nao); + if (vars) { + list_collect_decl (fixed_vars, tail); + + if (!consp(vars)) + sem_error(spec_linenum, lit("collect: invalid argument to :vars"), nao); + for (iter = vars; iter; iter = cdr(iter)) { + val item = car(iter); + if (bindable(item)) { + list_collect (tail, cons(item, nil)); + } else if (consp(item) && bindable(first(item))) { + list_collect (tail, cons(first(item), second(item))); + } else { + sem_error(spec_linenum, lit("not a variable spec: ~a"), item, nao); + } + } + vars = fixed_vars; + } + if ((times && ctimes == 0) || (lines && clines == 0)) { if ((spec = rest(spec)) == nil) break; @@ -1711,13 +1731,31 @@ repeat_spec_same_data: debuglf(spec_linenum, lit("collect matched ~a:~a"), first(files), num(data_lineno), nao); + for (iter = vars; iter; iter = cdr(iter)) { + cons_bind (var, dfl, car(iter)); + val exists = assoc(new_bindings, var); + + if (!exists) { + if (!dfl) + sem_error(spec_linenum, lit("collect failed to bind ~a"), + var, nao); + else + strictly_new_bindings = acons(strictly_new_bindings, + var, dfl); + } + } + for (iter = strictly_new_bindings; iter; iter = cdr(iter)) { val binding = car(iter); - val existing = assoc(bindings_coll, car(binding)); + val vars_binding = assoc(vars, car(binding)); + + if (!vars || vars_binding) { + val existing = assoc(bindings_coll, car(binding)); - bindings_coll = acons_new(bindings_coll, car(binding), - cons(cdr(binding), cdr(existing))); + bindings_coll = acons_new(bindings_coll, car(binding), + cons(cdr(binding), cdr(existing))); + } } } @@ -2311,4 +2349,5 @@ void match_init(void) longest_k = intern(lit("longest"), keyword_package); shortest_k = intern(lit("shortest"), keyword_package); greedy_k = intern(lit("greedy"), keyword_package); + vars_k = intern(lit("vars"), keyword_package); } |