summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-11-04 06:44:25 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-11-04 06:44:25 -0800
commit8cdf0417090b2c6e6b29aa67c7b1efca5501bb7c (patch)
tree5d9420167dacb3314a3553b5c117d00b3664c52d /match.c
parent7ab744e142b33e641a72b163a4f6f9a2eaf18f15 (diff)
downloadtxr-8cdf0417090b2c6e6b29aa67c7b1efca5501bb7c.tar.gz
txr-8cdf0417090b2c6e6b29aa67c7b1efca5501bb7c.tar.bz2
txr-8cdf0417090b2c6e6b29aa67c7b1efca5501bb7c.zip
Pattern vars accessed from Lisp now dynamic.
* eval.c (set_dyn_env): Static function becomes external. * eval.h (set_dyn_env): Declared. * match.c (eval_with_bindings, eval_progn_with_bindings): Evaluate Lisp code in null lexical environment. Instead install the pattern variables as dynamic, so they shadow global variables. A compatibility check for 121 or earlier provides the old behavior. * txr.1: Document scoping rules, and added compatibility notes.
Diffstat (limited to 'match.c')
-rw-r--r--match.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/match.c b/match.c
index 45ba7423..8b127a0d 100644
--- a/match.c
+++ b/match.c
@@ -283,20 +283,45 @@ static val eval_with_bindings(val form, val spec,
val bindings, val ctx_form)
{
val ret;
+
uw_env_begin;
- uw_set_match_context(cons(spec, bindings));
- ret = eval(form, make_env(bindings, nil, nil), ctx_form);
+
+ if (opt_compat && opt_compat <= 121) {
+ uw_set_match_context(cons(spec, bindings));
+ ret = eval(form, make_env(bindings, nil, nil), ctx_form);
+ } else {
+ val saved_de = set_dyn_env(make_env(bindings, nil, nil));
+
+ uw_set_match_context(cons(spec, bindings));
+ ret = eval(form, nil, ctx_form);
+
+ set_dyn_env(saved_de);
+ }
+
uw_env_end;
return ret;
}
+
static val eval_progn_with_bindings(val forms, val spec,
val bindings, val ctx_form)
{
val ret;
+
uw_env_begin;
- uw_set_match_context(cons(spec, bindings));
- ret = eval_progn(forms, make_env(bindings, nil, nil), ctx_form);
+
+ if (opt_compat && opt_compat <= 121) {
+ uw_set_match_context(cons(spec, bindings));
+ ret = eval_progn(forms, make_env(bindings, nil, nil), ctx_form);
+ } else {
+ val saved_de = set_dyn_env(make_env(bindings, nil, nil));
+
+ uw_set_match_context(cons(spec, bindings));
+ ret = eval_progn(forms, nil, ctx_form);
+
+ set_dyn_env(saved_de);
+ }
+
uw_env_end;
return ret;
}