| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (make_var_shadowing_env): We cannot return the
original env in the empty variable case, but earnestly
make a new one. This function is used by the expander when
walking the lbind/fbind special from emitted by labels/flet.
That form clobbers the environment via make_fun_shadowing_env,
which calls make_var_shadowing_env and then destructively
moves the variable bindings to the function binding slot of
the environment. The manifestation is that when we have
(symacrolet ((x 1)) (labels () x)), the x fails to expand; it
has been wrongly moved to the function bindings area of the
macro environment.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* genman.txr (dupes, tagnum): Replace defvar with defvarl.
* stdlib/doc-lookup.tl (os-symbol): Same.
* tests/011/macros-3.tl (x): Same.
* tests/011/mandel.txr (x-centre, y-centre, width, i-max, j-max, n)
(r-max, pixel-size, x-offset, y-offset): Same.
(file, colour-max): Delete (unused) variables.
* tests/012/circ.tl (x): Replace defvar with defvarl.
* tests/012/stack.tl (stack-limited): Same.
* tests/012/struct.tl (s): Same.
* tests/013/maze.tl (vi, pa, sc): Delete variables. Use
function arguments instead.
(usage): Fix typo.
* tests/014/dgram-stream.tl (family): Rename to...
(*family*): ...this.
* tests/014/socket-basic.tl (socktype): Rename to...
(*socktype*): ...this.
(%iters%): Replace defvar with defvarl.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a regression that was introduced in 191. The change in
191 was trying to prevent defsymacro from being expanded
immediately by the expander except in 190 compatibility.
Unfortunately, this caused the whole defsymacro block not to
be entered unless in 190 compatibility, otherwise taking the
common exit which returns form_ex, containing the expanded
replacement form.
* eval.c (do_expand): Split up implementation of defvarl and
defsymacro. In the defsymacro block, do not do any expanding
on entry. Absent of compatibility mode, we just do some sanity
checks and pass the entire form through. In 262 compatibility,
we do the expansion to obtain form_ex. Then all the previous
compat logic is wrapped in that block.
* tests/011/macros-3.tl: Add a test case which confirms that
symbol macros are lazily expanded. Weakness in the test suite
is how these regressions creep in.
* txr.1: Improve defsymacro documentation, spelling out
clearly that the unexpanded replacement form is associated
with the symbol. Eliminate obsolescent text suggesting that
defsymacro is evaluated at macro time.
|
|
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.
|