diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-11-24 06:46:09 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-11-24 06:46:09 -0800 |
commit | 87caead8269055b4791de53be0e03afab01f1dd4 (patch) | |
tree | ac9f70afaaa38f2b76861cf639ee2db399d0bc35 /tests | |
parent | 389458021d4baa70a150021aa2d6ab02f78dccd2 (diff) | |
download | txr-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')
-rw-r--r-- | tests/011/macros-3.expected | 0 | ||||
-rw-r--r-- | tests/011/macros-3.tl | 12 |
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) |