From 71cacde9c896a1532247a349a298e68fd20500a8 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 20 Nov 2011 12:02:13 -0800 Subject: Relaxing :vars in collect/coll a little bit. * match.c (h_coll, v_collect): Only throw an error about missing required variables if the collect iteration collected some new variables. This allows strict collects with :vars to have some cases which explicitly match and skip unwanted material, without binding variables. Also, print all missing variables in the diagnostic. * txr.1: Mention this special exception. * RELNOTES: Updated. --- ChangeLog | 15 +++++++++++++++ RELNOTES | 5 +++++ match.c | 18 ++++++++++++++---- txr.1 | 2 ++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 67e71097..ce7a90f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2011-11-20 Kaz Kylheku + + Relaxing :vars in collect/coll a little bit. + + * match.c (h_coll, v_collect): Only throw an error about + missing required variables if the collect iteration collected some new + variables. This allows strict collects with :vars to have + some cases which explicitly match and skip unwanted material, + without binding variables. Also, print all missing variables in the + diagnostic. + + * txr.1: Mention this special exception. + + * RELNOTES: Updated. + 2011-11-19 Kaz Kylheku * Makefile (tests/008/soundex.ok): New test case. diff --git a/RELNOTES b/RELNOTES index 79e7043c..20142bdb 100644 --- a/RELNOTES +++ b/RELNOTES @@ -38,6 +38,11 @@ Version 042 - Stability fix: several long-time uninitialized variable bugs found, and some faulty object initialization orders. + - :vars in @(collect)/@(coll) does not fire an exception about missing + required variables if no variable bindings are produced at all, + allowing strict collects to have explicit matches for unwanted material + without triggering this nuisance error. + Internal - New infrastructure for matching location info to source forms. diff --git a/match.c b/match.c index 3df2656c..05b542bd 100644 --- a/match.c +++ b/match.c @@ -740,8 +740,10 @@ static val h_coll(match_line_ctx c, match_line_ctx *cout) } if (new_pos) { + list_collect_decl (missing, ptail); val strictly_new_bindings = set_diff(new_bindings, c.bindings, eq_f, nil); + val have_new = strictly_new_bindings; LOG_MATCH("coll", new_pos); for (iter = vars; iter; iter = cdr(iter)) { @@ -750,14 +752,17 @@ static val h_coll(match_line_ctx c, match_line_ctx *cout) if (!exists) { if (dfl == noval_s) - sem_error(elem, lit("coll failed to bind ~a"), - var, nao); + list_collect (ptail, var); else strictly_new_bindings = acons(strictly_new_bindings, var, dfl); } } + if (have_new && missing) + sem_error(elem, lit("collect failed to bind ~a"), + missing, nao); + for (iter = strictly_new_bindings; iter; iter = cdr(iter)) { val binding = car(iter); @@ -2305,8 +2310,10 @@ static val v_collect(match_files_ctx *c) } if (success) { + list_collect_decl (missing, ptail); val strictly_new_bindings = set_diff(new_bindings, c->bindings, eq_f, nil); + val have_new = strictly_new_bindings; debuglf(specline, lit("collect matched ~a:~a"), first(c->files), c->data_lineno, nao); @@ -2317,14 +2324,17 @@ static val v_collect(match_files_ctx *c) if (!exists) { if (dfl == noval_s) - sem_error(specline, lit("collect failed to bind ~a"), - var, nao); + list_collect (ptail, var); else strictly_new_bindings = acons(strictly_new_bindings, var, dfl); } } + if (have_new && missing) + sem_error(specline, lit("collect failed to bind ~a"), + missing, nao); + for (iter = strictly_new_bindings; iter; iter = cdr(iter)) { val binding = car(iter); diff --git a/txr.1 b/txr.1 index 17c4307c..0953dfef 100644 --- a/txr.1 +++ b/txr.1 @@ -2062,6 +2062,8 @@ variables do not propagate. Furthermore, for any variable which is not specified with a default value, the collect body, whenever it matches successfully, must bind that variable. If it neglects to bind the variable, an exception of type query_error is thrown. +(If a collect body matches successfully, but produces no new bindings, then +this error is suppressed.) For any variable which does have a default value, if the collect body neglects to bind that variable, the behavior is as if the collect did bind that variable -- cgit v1.2.3