summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-04-15 18:28:36 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-04-15 18:28:36 -0700
commit9d59b9a607b0ebee9102ec7e2da00d7f24b54b0e (patch)
treeb682e7f5b6b707064668ca8a8e7bdc82e20654d8 /eval.c
parentc7089d15344e963397e9c58864f476729caeb225 (diff)
downloadtxr-9d59b9a607b0ebee9102ec7e2da00d7f24b54b0e.tar.gz
txr-9d59b9a607b0ebee9102ec7e2da00d7f24b54b0e.tar.bz2
txr-9d59b9a607b0ebee9102ec7e2da00d7f24b54b0e.zip
Bugfix expansion: return-from, sys:abscond-from, block*.
These three forms are not being traversed properly by the macro expander. * eval.c (do_expand): Do not treat return-from, sys:abscond-from and block* in the same case as block. block* evaluates all of its forms and so can just be walked as a function call in the fallback case. The other two must be in their own case because we must not use expand_progn on them; they do not evaluate a progn-like list of forms. This leads to inappropriate optimizations like (return-from x (progn a b c)) -> (return-from x a b c).
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/eval.c b/eval.c
index 815689f0..60766b4b 100644
--- a/eval.c
+++ b/eval.c
@@ -4050,15 +4050,20 @@ static val do_expand(val form, val menv)
} else {
return rlcp(cons(sym, cons(funcs_ex, body_ex)), form);
}
- } else if (sym == block_s || sym == return_from_s ||
- sym == sys_abscond_from_s || sym == block_star_s)
- {
+ } else if (sym == block_s) {
val name = second(form);
val body = rest(rest(form));
val body_ex = expand_progn(body, menv);
if (body == body_ex)
return form;
return rlcp(cons(sym, cons(name, body_ex)), form);
+ } else if (sym == return_from_s || sym == sys_abscond_from_s) {
+ val name = second(form);
+ val ret = third(form);
+ val ret_ex = expand(ret, menv);
+ if (ret == ret_ex)
+ return form;
+ return rlcp(list(sym, name, ret_ex, nao), form);
} else if (sym == cond_s) {
val pairs = rest(form);
val pairs_ex = expand_cond_pairs(pairs, menv);