summaryrefslogtreecommitdiffstats
path: root/tests/012/quasi.tl
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-06-15 07:58:43 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-06-15 07:58:43 -0700
commitca118fac3a97a6cd6b9342d301b3b06c515ad5f1 (patch)
treeb9a08668bc2fee299886e9182a4827d98ec5a30f /tests/012/quasi.tl
parent5a584a973b632f28edcc0312d92e4a38ee567d8c (diff)
downloadtxr-ca118fac3a97a6cd6b9342d301b3b06c515ad5f1.tar.gz
txr-ca118fac3a97a6cd6b9342d301b3b06c515ad5f1.tar.bz2
txr-ca118fac3a97a6cd6b9342d301b3b06c515ad5f1.zip
expander: bug: atoms in quasiliteral.
Via macros, atoms can sneak into a quasiliteral which then blow up because they get treated as strings without being converted. Example: (defmacro two () 2) `@(two)xyz` -> ;; error The expansion produces the invalid form, in which the 2 is subsequently treated as a string. (sys:quasi 2 "xyz") On the other hand, symbol macros don't have this problem: (defsymacro two 2) `@{two}xyz` -> "2xyz" The reason is that the (sys:var two) syntax will expand to (sys:var 2), and not 2. The straightforward, consistent fix is to ensure that the first case will also go to (sys:var 2). * eval.c (expand_quasi): If the expanded form is an atom which is not a bindable symbol, wrap it in a sys:var. * tests/012/quasi.tl: Test cases added. Also adding a compilation test for this file, cribbed from patmatch.tl.
Diffstat (limited to 'tests/012/quasi.tl')
-rw-r--r--tests/012/quasi.tl15
1 files changed, 15 insertions, 0 deletions
diff --git a/tests/012/quasi.tl b/tests/012/quasi.tl
index 276d5395..1cb24578 100644
--- a/tests/012/quasi.tl
+++ b/tests/012/quasi.tl
@@ -36,3 +36,18 @@
(let ((s))
(mapcar (ret `<@{(push (inc @1) s) d}>`) (range 0 2))))
("<1>" "<2-1>" "<3-2-1>"))
+
+(test
+ (symacrolet ((two 2))
+ `@{two}abc`)
+ "2abc")
+
+(test
+ (macrolet ((two () 2))
+ `@(two)abc`)
+ "2abc")
+
+(compile-only
+ (eval-only
+ (compile-file (base-name *load-path*) "temp.tlo")
+ (remove-path "temp.tlo")))