summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-08-28 06:44:21 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-08-28 06:44:21 -0700
commit89752b07ce3695fa4302b5db3788fed7b51873d5 (patch)
tree2e93e716ad830ea49a8f85ac582b77338975500e /eval.c
parent1f7a1d489ebfd6b3ef784005b2a52b327979fc58 (diff)
downloadtxr-89752b07ce3695fa4302b5db3788fed7b51873d5.tar.gz
txr-89752b07ce3695fa4302b5db3788fed7b51873d5.tar.bz2
txr-89752b07ce3695fa4302b5db3788fed7b51873d5.zip
expander: do dot-to-apply for meta-expressions.
The dot-to-apply transformation is now applied when meta-expressions like @foo and @(bar) apparently occur in the dot position. This change is made in anticipation of a rewrite of the op macro, in which the @1, @2, and @rest arguments will be implemented as macrolets, rather than the ad-hoc, hacky code walk currently performed in the transform_op function. * eval.c (dot_meta_list_p): New static function. (dot_to_apply): Detect the presence of a sys:var or sys:expr argument in a form. If found, then turn it and the remaining forms into a single compound form which replaces them. * txr.1: Update doc under Dot Position in Function Calls.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/eval.c b/eval.c
index 765c438c..da0a560d 100644
--- a/eval.c
+++ b/eval.c
@@ -2883,18 +2883,49 @@ static val imp_list_to_list(val list)
return out;
}
+static val dot_meta_list_p(val list)
+{
+ if (!consp(list))
+ return list;
+
+ list = cdr(list);
+
+ for (; consp(list); list = cdr(list)) {
+ val a = car(list);
+ if (a == var_s || a == expr_s)
+ return list;
+ }
+
+ return nil;
+}
+
static val dot_to_apply(val form, val lisp1_p)
{
- if ((opt_compat && opt_compat <= 137) || proper_list_p(form)) {
- return form;
- } else {
+ val args = nil, meta = nil;
+
+ if (opt_compat) {
+ if (opt_compat <= 137)
+ return form;
+ if (opt_compat <= 184 && proper_list_p(form))
+ return form;
+ }
+
+ if ((meta = dot_meta_list_p(form)) != nil) {
+ val pfx = ldiff(form, meta);
+ args = append2(cdr(pfx), cons(meta, nil));
+ } else if (!proper_list_p(form)) {
+ args = imp_list_to_list(cdr(form));
+ }
+
+ if (args) {
val sym = car(form);
- val args = imp_list_to_list(cdr(form));
return cons(sys_apply_s, cons(if3(lisp1_p,
sym,
list(fun_s, sym, nao)),
args));
}
+
+ return form;
}
val expand_forms(val form, val menv)