summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eval.c66
-rw-r--r--eval.h2
-rw-r--r--parser.c14
-rw-r--r--txr.c2
-rw-r--r--unwind.c33
-rw-r--r--unwind.h3
6 files changed, 106 insertions, 14 deletions
diff --git a/eval.c b/eval.c
index 319faa5b..38ba9738 100644
--- a/eval.c
+++ b/eval.c
@@ -100,7 +100,7 @@ val macro_time_s, with_dyn_rebinds_s, macrolet_s;
val defsymacro_s, symacrolet_s, prof_s, switch_s;
val fbind_s, lbind_s, flet_s, labels_s;
val opip_s, oand_s, chain_s, chand_s;
-val load_path_s, sys_lisp1_value_s;
+val load_path_s, load_recursive_s, sys_lisp1_value_s;
val special_s, unbound_s;
val whole_k, form_k, symacro_k;
@@ -256,6 +256,40 @@ static val eval_warn(val ctx, val fmt, ...)
return nil;
}
+static val eval_defr_warn(val ctx, val tag, val fmt, ...)
+{
+ uses_or2;
+ va_list vl;
+
+ va_start (vl, fmt);
+
+ uw_catch_begin (cons(continue_s, nil), exsym, exvals);
+
+ {
+ val form = ctx_form(ctx);
+ val stream = make_string_output_stream();
+ val loc = or2(source_loc_str(form, nil),
+ source_loc_str(last_form_evaled, nil));
+
+ if (loc)
+ format(stream, lit("(~a) "), loc, nao);
+
+ (void) vformat(stream, fmt, vl);
+
+ uw_throw(warning_s, cons(get_string_from_stream(stream), tag));
+ }
+
+ uw_catch(exsym, exvals) { (void) exsym; (void) exvals; }
+
+ uw_unwind;
+
+ uw_catch_end;
+
+ va_end (vl);
+
+ return nil;
+}
+
val lookup_origin(val form)
{
return gethash(origin_hash, form);
@@ -1650,6 +1684,7 @@ static val op_defvarl(val form, val env)
val value = eval(second(args), env, form);
remhash(top_smb, sym);
sethash(top_vb, sym, cons(sym, value));
+ uw_purge_deferred_warning(cons(var_s, sym));
}
return sym;
@@ -1686,6 +1721,7 @@ static val op_defun(val form, val env)
sethash(top_fb, name, cons(name, func_interp(env, fun)));
if (eval_initing)
sethash(builtin, name, defun_s);
+ uw_purge_deferred_warning(cons(fun_s, name));
return name;
} else if (car(name) == meth_s) {
val binding = lookup_fun(nil, intern(lit("defmeth"), system_package));
@@ -3630,6 +3666,7 @@ val load(val target)
val name, stream;
val txr_lisp_p = t;
val saved_dyn_env = dyn_env;
+ val rec = cdr(lookup_var(saved_dyn_env, load_recursive_s));
open_txr_file(path, &txr_lisp_p, &name, &stream);
@@ -3643,6 +3680,7 @@ val load(val target)
dyn_env = make_env(nil, nil, dyn_env);
env_vbind(dyn_env, load_path_s, path);
+ env_vbind(dyn_env, load_recursive_s, t);
env_vbind(dyn_env, package_s, cur_package);
if (!read_eval_stream(stream, std_error, nil)) {
@@ -3652,8 +3690,13 @@ val load(val target)
dyn_env = saved_dyn_env;
+ if (!rec)
+ uw_dump_deferred_warnings(std_error);
+
uw_unwind {
close_stream(stream, nil);
+ if (!rec)
+ uw_dump_deferred_warnings(std_null);
}
uw_catch_end;
@@ -3750,7 +3793,9 @@ static val do_expand(val form, val menv)
return expand(rlcp_tree(symac, form), menv);
}
if (!lookup_var(menv, form))
- eval_warn(last_form_expanded, lit("unbound variable ~s"), form, nao);
+ eval_defr_warn(last_form_expanded,
+ cons(var_s, form),
+ lit("unbound variable ~s"), form, nao);
return form;
} else if (atom(form)) {
return form;
@@ -4035,12 +4080,16 @@ static val do_expand(val form, val menv)
}
if (form_ex == form && args_ex == args) {
- if (!lookup_fun(menv, sym) && !special_operator_p(sym))
- eval_warn(last_form_expanded,
- if3(bindable(sym_ex),
- lit("unbound function ~s"),
- lit("~s appears in operator position")),
- sym, nao);
+ if (!lookup_fun(menv, sym) && !special_operator_p(sym)) {
+ if (!bindable(sym_ex))
+ eval_warn(last_form_expanded,
+ lit("~s appears in operator position"), sym, nao);
+ else
+ eval_defr_warn(last_form_expanded,
+ cons(fun_s, sym),
+ lit("unbound function ~s"),
+ sym, nao);
+ }
return form;
}
@@ -5139,6 +5188,7 @@ void eval_init(void)
chain_s = intern(lit("chain"), user_package);
chand_s = intern(lit("chand"), user_package);
load_path_s = intern(lit("*load-path*"), user_package);
+ load_recursive_s = intern(lit("*load-recursive*"), system_package);
sys_lisp1_value_s = intern(lit("lisp1-value"), system_package);
qquote_init();
diff --git a/eval.h b/eval.h
index d03cb490..d18f6fdb 100644
--- a/eval.h
+++ b/eval.h
@@ -31,7 +31,7 @@ extern val eval_error_s, if_s, call_s;
extern val eq_s, eql_s, equal_s;
extern val car_s, cdr_s;
extern val last_form_evaled, last_form_expanded;
-extern val load_path_s;
+extern val load_path_s, load_recursive_s;
#define load_path (deref(lookup_var_l(nil, load_path_s)))
diff --git a/parser.c b/parser.c
index f2a7e310..489ab1b5 100644
--- a/parser.c
+++ b/parser.c
@@ -45,6 +45,7 @@
#include "signal.h"
#include "unwind.h"
#include "gc.h"
+#include "args.h"
#include "utf8.h"
#include "hash.h"
#include "eval.h"
@@ -906,9 +907,16 @@ static val get_home_path(void)
return getenv_wrap(lit("HOME"));
}
-static val repl_warning(val out_stream, val exc, val arg)
+static val repl_warning(val out_stream, val exc, struct args *rest)
{
- format(out_stream, lit("** warning: ~!~a\n"), arg, nao);
+ val args = args_get_list(rest);
+ val loading = cdr(lookup_var(dyn_env, load_recursive_s));
+
+ if (loading && cdr(args))
+ uw_defer_warning(args);
+ else
+ format(out_stream, lit("** warning: ~!~a\n"), car(args), nao);
+
uw_throw(continue_s, nil);
}
@@ -936,7 +944,7 @@ val repl(val bindings, val in_stream, val out_stream)
val hist_len_var = lookup_global_var(listener_hist_len_s);
val multi_line_var = lookup_global_var(listener_multi_line_p_s);
val sel_inclusive_var = lookup_global_var(listener_sel_inclusive_p_s);
- val rw_f = func_f2(out_stream, repl_warning);
+ val rw_f = func_f1v(out_stream, repl_warning);
for (; bindings; bindings = cdr(bindings)) {
val binding = car(bindings);
diff --git a/txr.c b/txr.c
index c69def68..d339589a 100644
--- a/txr.c
+++ b/txr.c
@@ -1012,6 +1012,8 @@ int txr_main(int argc, char **argv)
close_stream(parse_stream, nil);
+ uw_dump_deferred_warnings(std_error);
+
if (!enter_repl)
return result ? 0 : EXIT_FAILURE;
}
diff --git a/unwind.c b/unwind.c
index 5a880acc..4c839735 100644
--- a/unwind.c
+++ b/unwind.c
@@ -59,6 +59,8 @@ static val sys_cont_free_s, sys_capture_cont_s;
static val frame_type, catch_frame_type, handle_frame_type;
+static val deferred_warnings;
+
/* C99 inline instantiations. */
#if __STDC_VERSION__ >= 199901L
val uw_block_return(val tag, val result);
@@ -578,7 +580,10 @@ val uw_throw(val sym, val args)
if (sym == warning_s) {
--reentry_count;
- format(std_error, lit("warning: ~a\n"), car(args), nao);
+ if (cdr(args))
+ uw_defer_warning(args);
+ else
+ format(std_error, lit("warning: ~a\n"), car(args), nao);
uw_throw(continue_s, nil);
abort();
}
@@ -669,6 +674,30 @@ val type_mismatch(val fmt, ...)
abort();
}
+val uw_defer_warning(val args)
+{
+ push(args, &deferred_warnings);
+ return nil;
+}
+
+val uw_dump_deferred_warnings(val stream)
+{
+ val wl = nreverse(zap(&deferred_warnings));
+
+ for (; wl; wl = cdr(wl)) {
+ val args = car(wl);
+ format(stream, lit("warning: ~a\n"), car(args), nao);
+ }
+
+ return nil;
+}
+
+val uw_purge_deferred_warning(val tag)
+{
+ deferred_warnings = remqual(tag, deferred_warnings, cdr_f);
+ return nil;
+}
+
val uw_register_subtype(val sub, val sup)
{
val t_entry = assoc(t, exception_subtypes);
@@ -969,7 +998,7 @@ void uw_init(void)
void uw_late_init(void)
{
protect(&frame_type, &catch_frame_type, &handle_frame_type,
- convert(val *, 0));
+ &deferred_warnings, convert(val *, 0));
types_s = intern(lit("types"), user_package);
jump_s = intern(lit("jump"), user_package);
sys_cont_s = intern(lit("cont"), system_package);
diff --git a/unwind.h b/unwind.h
index 4ca52228..7131cbc7 100644
--- a/unwind.h
+++ b/unwind.h
@@ -128,6 +128,9 @@ noreturn val uw_throwf(val sym, val fmt, ...);
noreturn val uw_throwfv(val sym, val fmt, struct args *);
noreturn val uw_errorf(val fmt, ...);
noreturn val uw_errorfv(val fmt, struct args *args);
+val uw_defer_warning(val args);
+val uw_dump_deferred_warnings(val stream);
+val uw_purge_deferred_warning(val tag);
val uw_register_subtype(val sub, val super);
val uw_exception_subtype_p(val sub, val sup);
void uw_continue(uw_frame_t *target);