summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eval.c2
-rw-r--r--eval.h1
-rw-r--r--match.c33
-rw-r--r--txr.142
4 files changed, 73 insertions, 5 deletions
diff --git a/eval.c b/eval.c
index 21e1dcea..62841f6e 100644
--- a/eval.c
+++ b/eval.c
@@ -926,7 +926,7 @@ static void do_eval_args(val form, val env, val ctx_form,
}
}
-static val set_dyn_env(val de)
+val set_dyn_env(val de)
{
val old = dyn_env;
dyn_env = de;
diff --git a/eval.h b/eval.h
index 9653a6f7..cedaeeff 100644
--- a/eval.h
+++ b/eval.h
@@ -38,6 +38,7 @@ val lookup_global_var(val sym);
loc lookup_var_l(val env, val sym);
loc lookup_global_var_l(val sym);
val lookup_fun(val env, val sym);
+val set_dyn_env(val de);
val interp_fun(val env, val fun, struct args *);
val boundp(val sym);
val fboundp(val sym);
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;
}
diff --git a/txr.1 b/txr.1
index 9a16104e..aa850614 100644
--- a/txr.1
+++ b/txr.1
@@ -10442,6 +10442,34 @@ is provided by
and
.codn lexical-lisp1-binding .
+.NP* Pattern Language and Lisp Scope Nesting
+
+\*(TL expressions can be embedded in the \*(TX pattern language in various
+ways. Likewise, the pattern language can be invoked from \*(TL. This
+creates the possibility that Lisp code makes references to variables
+bound in the pattern language. The pattern language can also reference
+Lisp variables indirectly using the
+.code @
+escape to evaluate a variable reference as Lisp code. Plain variable
+references in the pattern language do not refer to Lisp variables.
+
+The rules are as follows, but they haven't always been that way.
+See the COMPATIBILITY section.
+
+A Lisp expression evaluated from the \*(TX pattern language executes
+in a null lexical environment. The current set of pattern variables captured
+up to that point by the pattern language are installed as dynamic variables.
+They shadow any Lisp global variables (whether those are defined
+by
+.code defvar
+or
+.codn defvarl ).
+
+The variable bindings are also stored in a dynamic environment frame.
+When \*(TX pattern code is re-entered from Lisp, these bindings are picked
+up from the closest environment frame, allowing the pattern code to
+continue with those bindings.
+
.SH* LISP OPERATOR, FUNCTION AND MACRO REFERENCE
.SS* Conventions
@@ -37246,6 +37274,20 @@ is given an argument which is equal or lower. For instance
.code -C 103
selects the behaviors described below for version 105, but not those for 102.
+.IP 121
+In \*(TX 121 and earlier versions, \*(TL expressions evaluated in the
+pattern language were placed in a lexical environment in which the
+pattern variables were visible as lexical variables. The meant that
+these variables could be directly captured in lexical closures. On the other
+hand, it meant that a Lisp function defined in a
+.code @(do)
+block could not access a variable established by a later
+.codn @(bind) .
+It doesn't make sense for dynamically captured variables to be lexical,
+so the rule was changed. The backward compatibility switch will enable
+the old scoping behavior. Capturing the values of pattern variables in
+closures is possible indirectly under the new rule: simply bind new lexical
+variables with their values.
.IP 118
The
.code slot-p