From 55cc849371a0dc0782f3f749cb58c46e0a558e40 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 6 Feb 2015 22:24:33 -0800 Subject: Slight internal representation change of string-only exceptions. One upshot of all this is that (throw 'foo "msg") now does exactly the same thing as (throwf 'foo "msg"). A message-only exception really is a one-string exception argument list ("message ..."), like the documentation says. * unwind.h (struct uw_catch): exception member renamed to args. (uw_catch): Macro follows structure member rename. * eval.c (op_catch): Removed now unnecessary kludge of turning non-list exception argument list into a one-element argument list. * match.c (v_try): Similar hack to the one in op_catch removed here. * unwind.c (uw_unwind_to_exit_point, uw_push_catch): Follows rename of exception member. (uw_throw): The exception parameter is renamed to args. The kludge removed from op_catch re-appears here, because numerous calls to uw_throw just pass a string as args. It's less of a kludge here because this is the master entry point to exception processing, and it straightens out the representation right away. The exception arguments or message are printed in a clearer way. --- ChangeLog | 27 +++++++++++++++++++++++++++ eval.c | 4 +--- match.c | 5 +---- unwind.c | 23 +++++++++++++++-------- unwind.h | 4 ++-- 5 files changed, 46 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4243ab4c..9708b7cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2015-02-06 Kaz Kylheku + + Slight internal representation change of string-only exceptions. + + One upshot of all this is that (throw 'foo "msg") now + does exactly the same thing as (throwf 'foo "msg"). + A message-only exception really is a one-string exception argument + list ("message ..."), like the documentation says. + + * unwind.h (struct uw_catch): exception member renamed to args. + (uw_catch): Macro follows structure member rename. + + * eval.c (op_catch): Removed now unnecessary kludge of turning non-list + exception argument list into a one-element argument list. + + * match.c (v_try): Similar hack to the one in op_catch + removed here. + + * unwind.c (uw_unwind_to_exit_point, uw_push_catch): Follows rename of + exception member. + (uw_throw): The exception parameter is renamed to args. The kludge + removed from op_catch re-appears here, because numerous calls + to uw_throw just pass a string as args. It's less of a kludge here + because this is the master entry point to exception processing, + and it straightens out the representation right away. + The exception arguments or message are printed in a clearer way. + 2015-02-06 Kaz Kylheku Serious bugfix in the op macro, and derived macro, in diff --git a/eval.c b/eval.c index 7e27c962..056f4b68 100644 --- a/eval.c +++ b/eval.c @@ -2002,9 +2002,7 @@ static val op_catch(val form, val env) if (uw_exception_subtype_p(exsym, type)) { val params = second(clause); val saved_de = set_dyn_env(make_env(nil, nil, dyn_env)); - val clause_env = bind_args(env, params, if3(listp(exvals), - exvals, cons(exvals, nil)), - clause); + val clause_env = bind_args(env, params, exvals, clause); result = eval_progn(rest(rest(clause)), clause_env, clause); set_dyn_env(saved_de); break; diff --git a/match.c b/match.c index 13d58fe1..e4e7b119 100644 --- a/match.c +++ b/match.c @@ -3299,16 +3299,13 @@ static val v_try(match_files_ctx *c) val type = first(second(clause)); val params = second(second(clause)); val body = third(clause); - val vals = if3(listp(exvals), - exvals, - cons(exvals, nil)); if (first(clause) == catch_s) { if (uw_exception_subtype_p(exsym, type)) { val all_bind = t; val piter, viter; - for (piter = params, viter = vals; + for (piter = params, viter = exvals; piter && viter; piter = cdr(piter), viter = cdr(viter)) { diff --git a/unwind.c b/unwind.c index 05ff6335..3a8324f0 100644 --- a/unwind.c +++ b/unwind.c @@ -75,7 +75,7 @@ static void uw_unwind_to_exit_point(void) continue the unwinding by calling uw_continue, passing it the ca.cont value. */ uw_stack->ca.sym = nil; - uw_stack->ca.exception = nil; + uw_stack->ca.args = nil; uw_stack->ca.cont = uw_exit_point; /* 1 means unwind only. */ extended_longjmp(uw_stack->ca.jb, 1); @@ -238,7 +238,7 @@ void uw_push_catch(uw_frame_t *fr, val matches) memset(fr, 0, sizeof *fr); fr->ca.type = UW_CATCH; fr->ca.matches = matches; - fr->ca.exception = nil; + fr->ca.args = nil; fr->ca.cont = 0; fr->ca.visible = 1; fr->ca.up = uw_stack; @@ -257,10 +257,13 @@ val uw_exception_subtype_p(val sub, val sup) } } -val uw_throw(val sym, val exception) +val uw_throw(val sym, val args) { uw_frame_t *ex; + if (!listp(args)) + args = cons(args, nil); + for (ex = uw_stack; ex != 0; ex = ex->uw.up) { if (ex->uw.type == UW_CATCH && ex->ca.visible) { /* The some_satisfy would require us to @@ -290,7 +293,7 @@ val uw_throw(val sym, val exception) if (fun) { if (functionp(fun)) { - funcall3(fun, sym, exception, last_form_evaled); + funcall3(fun, sym, args, last_form_evaled); } else { format(std_error, lit("~a: *unhandled-hook* ~s isn't a function\n"), prog_string, fun, nao); @@ -302,7 +305,8 @@ val uw_throw(val sym, val exception) } if (opt_loglevel >= 1) { - val s = stringp(exception); + val is_msg = and2(stringp(car(args)), null(cdr(args))); + val msg_or_args = if3(is_msg, car(args), args); val info = if2(source_loc(last_form_evaled), source_loc_str(last_form_evaled)); format(std_error, lit("~a: unhandled exception of type ~a:\n"), @@ -312,8 +316,11 @@ val uw_throw(val sym, val exception) format(std_error, lit("~a: possibly triggered by ~a\n"), prog_string, info, nao); - format(std_error, s ? lit("~a: ~a\n") : lit("~a: ~s\n"), - prog_string, exception, nao); + format(std_error, + if3(is_msg, + lit("~a: message: ~a\n"), + lit("~a: exception args: ~s\n")), + prog_string, msg_or_args, nao); } if (uw_exception_subtype_p(sym, query_error_s) || uw_exception_subtype_p(sym, file_error_s)) { @@ -325,7 +332,7 @@ val uw_throw(val sym, val exception) } ex->ca.sym = sym; - ex->ca.exception = exception; + ex->ca.args = args; uw_exit_point = ex; uw_unwind_to_exit_point(); abort(); diff --git a/unwind.h b/unwind.h index 634fdfea..b2a02e74 100644 --- a/unwind.h +++ b/unwind.h @@ -60,7 +60,7 @@ struct uw_catch { uw_frtype_t type; val matches; val sym; - val exception; + val args; uw_frame_t *cont; int visible; extended_jmp_buf jb; @@ -172,7 +172,7 @@ noreturn val type_mismatch(val, ...); goto uw_unwind_label; \ break; \ case 2: \ - EXCVAR = uw_catch.ca.exception; \ + EXCVAR = uw_catch.ca.args; \ SYMVAR = uw_catch.ca.sym; \ (void) SYMVAR; \ /* prevent looping */ \ -- cgit v1.2.3