diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-02-16 01:52:56 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-02-16 01:52:56 -0800 |
commit | 83778347170b3168bbfd5a87bad1eb12700f5cd0 (patch) | |
tree | 9af5a9c884ab7834519e6650022d763f8415bb62 /eval.c | |
parent | b68fb2aad15663edfe7c3671c97bd85bc531c565 (diff) | |
download | txr-83778347170b3168bbfd5a87bad1eb12700f5cd0.tar.gz txr-83778347170b3168bbfd5a87bad1eb12700f5cd0.tar.bz2 txr-83778347170b3168bbfd5a87bad1eb12700f5cd0.zip |
In the spirit of the previous hack, here is another hack to
alleviate a long-standing pain: when an exception happens in
TXR's library somewhere, the program dies without leaving
a clue about what code was being evaluated when that happened.
What we can do is have the evaluator publish the most recent
compound form it has processed by stashing it in a variable.
Then when an unhandled exception occurs, we can peek at that
and try to pull out source location info.
* eval.c (last_form_evaled): New variable.
(do_eval): When evaluating a compound form, stash it in
last_form_evaled.
(eval_init): Protect last_form_evaled from gc.
* eval.h (last_form_evaled): Declared.
(eval_error_s): Existing variable declared.
* unwind.c: Has to include "eval.h" for the above variable
and "parser.h" for the source_loc function.
(uw_throw): When an exception is unhandled, if
last_form_evaled has source info, add it to the diagnostic.
But not if the exception is eval-error; because errors from
the evaluators already have the info.
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 6 |
1 files changed, 5 insertions, 1 deletions
@@ -91,6 +91,8 @@ val macro_time_s; val whole_k, env_k; +val last_form_evaled; + val make_env(val vbindings, val fbindings, val up_env) { val env = make_obj(); @@ -717,6 +719,8 @@ static val do_eval(val form, val env, val ctx_form, } else if (consp(form)) { val oper = car(form); + last_form_evaled = form; + if (regexp(oper)) debug_return (oper); @@ -2502,7 +2506,7 @@ static val and_fun(val vals) void eval_init(void) { - protect(&top_vb, &top_fb, &top_mb, &op_table, (val *) 0); + protect(&top_vb, &top_fb, &top_mb, &op_table, &last_form_evaled, (val *) 0); top_fb = make_hash(t, nil, nil); top_vb = make_hash(t, nil, nil); top_mb = make_hash(t, nil, nil); |