summaryrefslogtreecommitdiffstats
path: root/tests/011
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-11-24 06:46:09 -0800
committerKaz Kylheku <kaz@kylheku.com>2017-11-24 06:46:09 -0800
commit87caead8269055b4791de53be0e03afab01f1dd4 (patch)
treeac9f70afaaa38f2b76861cf639ee2db399d0bc35 /tests/011
parent389458021d4baa70a150021aa2d6ab02f78dccd2 (diff)
downloadtxr-87caead8269055b4791de53be0e03afab01f1dd4.tar.gz
txr-87caead8269055b4791de53be0e03afab01f1dd4.tar.bz2
txr-87caead8269055b4791de53be0e03afab01f1dd4.zip
macros: expand declined form in outer env.
This patch implements a new requirement which clarifies what happens when a macro declines to expand a form. To decline expanding a form means to return the original form (same object) without returning it. The expander detects this situation with an eq comparison on the input and output. The current behavior is that no further attempts are made to expand the form. This is problematic for various reasons. In code which is expanded more than once, this can lead to the expansion being different between the expansion passes. In the first pass, a local macro M might decline to expand a form. In the second pass, the local macro definition no longer exists, and the form does get expanded by a global macro M. This kind of instability introduces a flaw into complex macros which expand their argument material more than once. The new requirement is that if a macro definition declines to expand a macro, then a search takes place through the outer lexical scopes, and global scope, for the innermost macro definition which will expand the form. The search tries every macro in turn, stopping if a macro is found which doesn't decline the expansion, or after passing the global scope. * eval.c (expand_macro): Implement new searching behavior. * txr.1: Documented the expansion declining mechanism under defmacro and macrolet. * tests/011/macros-3.tl: New file. * tests/011/macros-3.expected: New file.
Diffstat (limited to 'tests/011')
-rw-r--r--tests/011/macros-3.expected0
-rw-r--r--tests/011/macros-3.tl12
2 files changed, 12 insertions, 0 deletions
diff --git a/tests/011/macros-3.expected b/tests/011/macros-3.expected
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/011/macros-3.expected
diff --git a/tests/011/macros-3.tl b/tests/011/macros-3.tl
new file mode 100644
index 00000000..bf7cf9a6
--- /dev/null
+++ b/tests/011/macros-3.tl
@@ -0,0 +1,12 @@
+(load "../common")
+
+(defmacro m () 42)
+
+(test
+ (macrolet ((m (:form f) f))
+ (let ((n 3))
+ (macrolet ((m (:form f) f))
+ (let ((n 3))
+ (macrolet ((m (:form f) f))
+ (m))))))
+ 42)