diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-02-08 00:42:21 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-02-08 00:46:22 -0800 |
commit | ab258ae6b13be92d2c8bf1a946aae1a1d902f16a (patch) | |
tree | 018e68e565219fec7aa7acb3fa4b43f81bd0d818 | |
parent | 124f3c016898056c3c4e3e9d67d1e5288b837b15 (diff) | |
download | txr-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.c | 8 |
1 files changed, 6 insertions, 2 deletions
@@ -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) |