summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-04-05 07:14:01 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-04-05 07:14:01 -0700
commit06ce08dc2c0d2db522c5f6293cf9a28c2c22d24a (patch)
tree665d03c406d1990e98787c78d894d25832b1e1bc /eval.c
parent7f639b761bfd44c6a07b8417007e1cb8a3a2856c (diff)
downloadtxr-06ce08dc2c0d2db522c5f6293cf9a28c2c22d24a.tar.gz
txr-06ce08dc2c0d2db522c5f6293cf9a28c2c22d24a.tar.bz2
txr-06ce08dc2c0d2db522c5f6293cf9a28c2c22d24a.zip
tagbody: code replication bug.
tagbody translates to a loop around a sys:switch special form. The compiler recognizes substructure sharing among the branches of the the sys:switch code and de-duplicates the generated assembly code accordingly. Unfortunately, the expander for sys:switch has a bug which spoils the substructure sharing. * eval.c (expand_forms_ss): We must process the incoming form list itself into the hash, not just that list's cdr. Onthe other hand, there is no need to hash the cars of the forms list (the forms themselves), so the code simplifies quite a bit.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c34
1 files changed, 14 insertions, 20 deletions
diff --git a/eval.c b/eval.c
index e057043c..93ca1d5d 100644
--- a/eval.c
+++ b/eval.c
@@ -3233,32 +3233,26 @@ val expand_forms(val form, val menv)
}
}
-static val expand_forms_ss(val form, val menv, val ss_hash)
+static val expand_forms_ss(val forms, val menv, val ss_hash)
{
- uses_or2;
+ val fh;
- if (atom(form)) {
- if (!form)
- return form;
- dotted_form_error(form);
+ if (atom(forms)) {
+ if (!forms)
+ return forms;
+ dotted_form_error(forms);
+ } else if ((fh = gethash(ss_hash, forms)) != nil) {
+ return fh;
} else {
- val f = car(form);
- val r = cdr(form);
- val ss_f = gethash(ss_hash, f);
- val ss_r = gethash(ss_hash, r);
- val ex_f = or2(ss_f, expand(f, menv));
- val ex_r = or2(ss_r, expand_forms_ss(r, menv, ss_hash));
-
- if (!ss_f)
- sethash(ss_hash, f, ex_f);
-
- if (!ss_r)
- sethash(ss_hash, r, ex_r);
+ val f = car(forms);
+ val r = cdr(forms);
+ val ex_f = expand(f, menv);
+ val ex_r = expand_forms_ss(r, menv, ss_hash);
if (ex_f == f && ex_r == r)
- return form;
+ return sethash(ss_hash, forms, forms);
- return sethash(ss_hash, form, rlcp(cons(ex_f, ex_r), form));
+ return sethash(ss_hash, forms, rlcp(cons(ex_f, ex_r), forms));
}
}