summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-02-08 00:42:21 -0800
committerKaz Kylheku <kaz@kylheku.com>2019-02-08 00:46:22 -0800
commitab258ae6b13be92d2c8bf1a946aae1a1d902f16a (patch)
tree018e68e565219fec7aa7acb3fa4b43f81bd0d818
parent124f3c016898056c3c4e3e9d67d1e5288b837b15 (diff)
downloadtxr-ab258ae6b13be92d2c8bf1a946aae1a1d902f16a.tar.gz
txr-ab258ae6b13be92d2c8bf1a946aae1a1d902f16a.tar.bz2
txr-ab258ae6b13be92d2c8bf1a946aae1a1d902f16a.zip
defvar: spectacular bug causing wrong compile.
The defvar/defparm macro expander marks symbols special only at macro-expansion time, without actually generating code in the macro expansion to do this. This means that the compiled versions of defvar and defparm forms will code will neglect to create a dynamically scoped variable! * eval.c (me_def_variable): Add code to the output to mark the symbol special, for defvar or defparm.
-rw-r--r--eval.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/eval.c b/eval.c
index c6022329..f9150b8c 100644
--- a/eval.c
+++ b/eval.c
@@ -2959,8 +2959,12 @@ static val me_def_variable(val form, val menv)
val op = first(form);
val sym = first(args);
val initform = second(args);
+ val mkspecial = if2(op == defvar_s || op == defparm_s,
+ cons(list(sys_mark_special_s,
+ list(quote_s, sym, nao), nao), nil));
val setval = if2(op == defparm_s || op == defparml_s,
cons(list(set_s, sym, initform, nao), nil));
+ val mksv = nappend2(mkspecial, setval);
(void) menv;
@@ -2970,7 +2974,7 @@ static val me_def_variable(val form, val menv)
if (!bindable(sym))
not_bindable_error(form, sym);
- if (op == defparm_s || op == defvar_s) {
+ if (mkspecial) {
mark_special(sym);
if (uw_warning_exists(cons(var_s, sym)))
eval_warn(form, lit("~s: global ~s marked special after lexical uses"),
@@ -2981,7 +2985,7 @@ static val me_def_variable(val form, val menv)
cons(defvarl_s,
cons(sym, if2(op == defvar_s,
cons(initform, nil)))),
- setval, nao));
+ mksv, nao));
}
static val get_var_syms(val vars)