diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-12-08 07:01:40 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-12-08 07:01:40 -0800 |
commit | a621bb39d04e1f77fc45c24a3ac3fc08291533fa (patch) | |
tree | dd50be4ca98b8b279bc7ad1e4066461629c98649 | |
parent | 078819a0ae62eaa981a271e127ecbcf2ce0a435f (diff) | |
download | txr-a621bb39d04e1f77fc45c24a3ac3fc08291533fa.tar.gz txr-a621bb39d04e1f77fc45c24a3ac3fc08291533fa.tar.bz2 txr-a621bb39d04e1f77fc45c24a3ac3fc08291533fa.zip |
case macros: bug in singleton key optimization.
* eval.c (me_case): Reduce (key) to key only if key is
an atom. Otherwise we reduce ((a b c)), which
is a single list-valued key to (a b c), which looks like
three keys. This was introduced on Oct 25, 2017 in
commit b72c9309c8d8f1af320dce616a69412510531b48,
making it a regression.
* tests/012/case.tl: New file. The last test
case fails without this bugfix. The others pass either way.
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | tests/012/case.tl | 32 |
2 files changed, 33 insertions, 1 deletions
@@ -4166,7 +4166,7 @@ static val me_case(val form, val menv) hash_keys = keys = expand_eval(cons(list_s, keys), nil, menv); } - if (consp(keys) && !cdr(keys)) + if (consp(keys) && atom(car(keys)) && !cdr(keys)) keys = car(keys); if (atom(keys)) { diff --git a/tests/012/case.tl b/tests/012/case.tl new file mode 100644 index 00000000..856ac56c --- /dev/null +++ b/tests/012/case.tl @@ -0,0 +1,32 @@ +(load "../common") + +(mtest + (caseq 0 (1 :match)) nil + (caseq 0 ((1) :match)) nil + (caseq 1 (1 :match)) :match + (caseq 1 ((1) :match)) :match + (caseq 1 ((0 1) :match)) :match + (caseq 1 ((0 2) :match)) nil + (caseq 1 (t :match)) :match + (caseq 1 ((t) :match)) nil + (caseq t ((t) :match)) :match) + +(defvar o 1) +(defvar y t) + +(mtest + (caseq* 0 (o :match)) nil + (caseq* 0 ((o) :match)) nil + (caseq* 1 (o :match)) :match + (caseq* 1 ((o) :match)) :match + (caseq* 1 ((0 o) :match)) :match + (caseq* 1 ((0 2) :match)) nil + (caseq* 1 (t :match)) :match + (caseq* 1 (y :match)) nil + (caseq* 1 ((t) :match)) nil + (caseq* t ((t) :match)) :match + (caseq* t ((y) :match)) :match) + +(test (casequal '(a b c d) + (((a b c d)) :match)) + :match) |