diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-05-14 09:32:23 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-05-14 09:32:23 -0700 |
commit | 30b4cd7fd4aa40616e089b834e34f1928c700ab1 (patch) | |
tree | 6aee301a40e21b6950ea1ca5f8bd6dff40f0229d /eval.c | |
parent | 5162fde5237ce801f74e8db2bc680f72f00fb0ce (diff) | |
download | txr-30b4cd7fd4aa40616e089b834e34f1928c700ab1.tar.gz txr-30b4cd7fd4aa40616e089b834e34f1928c700ab1.tar.bz2 txr-30b4cd7fd4aa40616e089b834e34f1928c700ab1.zip |
bug: symbol-value place always global.
We have a problem. If v is a dynamic variable, then
the form
(let (v)
(set (symbol-value 'v) 3))
is not behaving correctly; it's updating the top-level
value of v not the rebound one.
* eval.c (set_symbol_value): New static function.
(eval_init): Register sys:set-symbol-value intrinsic.
The top-vb variable, though no longer referenced by
the symbol-value place, because existing compiled
code depends on it.
* stdlib/place.tl (symbol-value): Rewrite the place
logic to use symbol-value to access the variable,
and set-symbol-value to update it, instead of referencing
sys:top-vb.
(sys:get-vb): This function has to stay, because it
provides run-time support for code compiled with the
buggy version of the place.
* tests/019/symbol-value.tl: New file.
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 13 |
1 files changed, 13 insertions, 0 deletions
@@ -5832,6 +5832,18 @@ static val symbol_value(val sym) lookup_symac(nil, sym))); } +static val set_symbol_value(val sym, val value) +{ + val vbind = lookup_var(nil, sym); + + if (vbind) + rplacd(vbind, value); + else + sethash(top_vb, sym, cons(sym, value)); + + return value; +} + static val symbol_function(val sym) { uses_or2; @@ -7579,6 +7591,7 @@ void eval_init(void) reg_varl(intern(lit("top-fb"), system_package), top_fb); reg_varl(intern(lit("top-mb"), system_package), top_mb); reg_fun(intern(lit("symbol-value"), user_package), func_n1(symbol_value)); + reg_fun(intern(lit("set-symbol-value"), system_package), func_n2(set_symbol_value)); reg_fun(intern(lit("symbol-function"), user_package), func_n1(symbol_function)); reg_fun(intern(lit("symbol-macro"), user_package), func_n1(symbol_macro)); reg_fun(intern(lit("boundp"), user_package), func_n1(boundp)); |