diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-08-28 06:44:21 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-08-28 06:44:21 -0700 |
commit | 89752b07ce3695fa4302b5db3788fed7b51873d5 (patch) | |
tree | 2e93e716ad830ea49a8f85ac582b77338975500e /eval.c | |
parent | 1f7a1d489ebfd6b3ef784005b2a52b327979fc58 (diff) | |
download | txr-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.c | 39 |
1 files changed, 35 insertions, 4 deletions
@@ -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) |