diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2011-09-26 20:22:06 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2011-09-26 20:22:06 -0700 |
commit | 070d3dfe7759943406cd76e7aebe72bf92ab3503 (patch) | |
tree | 254d02889a993cb4caeb568422291e7cf2726cca /match.c | |
parent | f3fe0151fc4116f0fec40e7454d8866f11908560 (diff) | |
download | txr-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.c | 42 |
1 files changed, 35 insertions, 7 deletions
@@ -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); |