summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-02-06 22:24:33 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-02-06 22:24:33 -0800
commit55cc849371a0dc0782f3f749cb58c46e0a558e40 (patch)
treef82e0ff125c582ef2753fef122e4761a9a4533e2
parent3b7f7ef0422537391879d356e61baa50f74483a1 (diff)
downloadtxr-55cc849371a0dc0782f3f749cb58c46e0a558e40.tar.gz
txr-55cc849371a0dc0782f3f749cb58c46e0a558e40.tar.bz2
txr-55cc849371a0dc0782f3f749cb58c46e0a558e40.zip
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.
-rw-r--r--ChangeLog27
-rw-r--r--eval.c4
-rw-r--r--match.c5
-rw-r--r--unwind.c23
-rw-r--r--unwind.h4
5 files changed, 46 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 4243ab4c..9708b7cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,32 @@
2015-02-06 Kaz Kylheku <kaz@kylheku.com>
+ 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 <kaz@kylheku.com>
+
Serious bugfix in the op macro, and derived macro, in
the handling of missing meta-numbers (for
instance (op ... @1 .. @3): 1 and 3 occur, but not 2.
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 */ \