summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-09-26 20:22:06 -0700
committerKaz Kylheku <kaz@kylheku.com>2011-09-26 20:22:06 -0700
commit070d3dfe7759943406cd76e7aebe72bf92ab3503 (patch)
tree254d02889a993cb4caeb568422291e7cf2726cca /match.c
parentf3fe0151fc4116f0fec40e7454d8866f11908560 (diff)
downloadtxr-070d3dfe7759943406cd76e7aebe72bf92ab3503.tar.gz
txr-070d3dfe7759943406cd76e7aebe72bf92ab3503.tar.bz2
txr-070d3dfe7759943406cd76e7aebe72bf92ab3503.zip
New feature: @(deffilter)
Bugfix in @(throw) when non-symbol is thrown: exception message referred to the symbol throw rather than the erroneous object. * filter.c (build_filter_from_list, register_filter): New functions. * filter.h (register_filter): New function declared. * lib.c (deffilter_s): New variable defined. (chain): Function changed from single list argument to variable argument list to reduce the complexity of use. (do_and, and): New functions. (obj_init): deffilter_s initializatio added. * lib.h (deffilter_s, and): New declarations. (chain): Declaration updated to new function signature. (eq): Changed from macro to inline function. * match.c (do_output_line): Simplified expression involving chain. (do_output): Likewise. (match_files): Bugfix in error handling of throw. Implementation of deffilter. * txr.1: Documented deffilter.
Diffstat (limited to 'match.c')
-rw-r--r--match.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/match.c b/match.c
index e92d9687..fb533c50 100644
--- a/match.c
+++ b/match.c
@@ -805,9 +805,9 @@ static void do_output_line(val bindings, val specline,
val bind_cp = extract_bindings(bindings, elem);
val max_depth = reduce_left(func_n2(max2),
bind_cp, zero,
- chain(list(func_n1(cdr),
- func_n1(robust_length),
- nao)));
+ chain(func_n1(cdr),
+ func_n1(robust_length),
+ nao));
if (equal(max_depth, zero) && empty_clauses) {
do_output_line(bindings, empty_clauses, spec_lineno, filter, out);
@@ -871,9 +871,9 @@ static void do_output(val bindings, val specs, val filter, val out)
val bind_cp = extract_bindings(bindings, first_elem);
val max_depth = reduce_left(func_n2(max2),
bind_cp, zero,
- chain(list(func_n1(cdr),
- func_n1(robust_length),
- nao)));
+ chain(func_n1(cdr),
+ func_n1(robust_length),
+ nao));
if (equal(max_depth, zero) && empty_clauses) {
do_output(bind_cp, empty_clauses, filter, out);
@@ -1672,12 +1672,40 @@ repeat_spec_same_data:
val args = rest(rest(first_spec));
if (!symbolp(type))
sem_error(spec_linenum, lit("throw: ~a is not a type symbol"),
- first(first_spec), nao);
+ type, nao);
{
val values = mapcar(bind2other(func_n2(eval_form), bindings),
args);
uw_throw(type, values);
}
+ } else if (sym == deffilter_s) {
+ val sym = second(first_spec);
+ val table = rest(rest(first_spec));
+
+ if (!symbolp(sym))
+ sem_error(spec_linenum, lit("deffilter: ~a is not a symbol"),
+ first(first_spec), nao);
+
+ if (!all_satisfy(table, and(func_n1(listp),
+ chain(func_n1(length),
+ bind2(func_n2(eq), two),
+ nao),
+ chain(func_n1(first),
+ func_n1(stringp),
+ nao),
+ chain(func_n1(second),
+ func_n1(stringp),
+ nao),
+ nao),
+ nil))
+ sem_error(spec_linenum,
+ lit("deffilter arguments must be string pairs"),
+ nao);
+ register_filter(sym, table);
+ /* TODO: warn about replaced filter. */
+ if ((spec = rest(spec)) == nil)
+ break;
+ goto repeat_spec_same_data;
} else {
val func = uw_get_func(sym);