From 87caead8269055b4791de53be0e03afab01f1dd4 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 24 Nov 2017 06:46:09 -0800 Subject: 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. --- tests/011/macros-3.expected | 0 tests/011/macros-3.tl | 12 ++++++++++++ 2 files changed, 12 insertions(+) create mode 100644 tests/011/macros-3.expected create mode 100644 tests/011/macros-3.tl (limited to 'tests') diff --git a/tests/011/macros-3.expected b/tests/011/macros-3.expected new file mode 100644 index 00000000..e69de29b 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) -- cgit v1.2.3