diff options
-rw-r--r-- | eval.c | 41 | ||||
-rw-r--r-- | tests/011/macros-3.tl | 8 | ||||
-rw-r--r-- | txr.1 | 43 |
3 files changed, 66 insertions, 26 deletions
@@ -4749,32 +4749,49 @@ again: if (pairs == pairs_ex) return form; return rlcp(cons(cond_s, pairs_ex), form); - } else if (sym == defvarl_s || sym == defsymacro_s) { + } else if (sym == defvarl_s) { val name = second(form); val init = third(form); val init_ex = expand(init, menv); val form_ex = form; - if (sym == defsymacro_s && length(form) != three) - eval_error(form, lit("~s: two arguments expected"), sym, nao); - if (!bindable(name)) not_bindable_error(form, name); - if (sym == defvarl_s) - uw_register_tentative_def(cons(var_s, name)); + uw_register_tentative_def(cons(var_s, name)); if (init != init_ex) form_ex = rlcp(cons(sym, cons(name, cons(init_ex, nil))), form); - if (opt_compat && opt_compat <= 190 && sym == defsymacro_s) { - val result = eval(if3(opt_compat && opt_compat <= 137, - form_ex, form), - make_env(nil, nil, nil), form); - return cons(quote_s, cons(result, nil)); + return form_ex; + } else if (sym == defsymacro_s) { + val name = second(form); + val init = third(form); + + if (length(form) != three) + eval_error(form, lit("~s: two arguments expected"), sym, nao); + + if (!bindable(name)) + not_bindable_error(form, name); + + if (opt_compat && opt_compat <= 262) { + val init_ex = expand(init, menv); + val form_ex = form; + + if (init != init_ex) + form_ex = rlcp(cons(sym, cons(name, cons(init_ex, nil))), form); + + if (opt_compat <= 190 && sym == defsymacro_s) { + val result = eval(if3(opt_compat && opt_compat <= 137, + form_ex, form), + make_env(nil, nil, nil), form); + return cons(quote_s, cons(result, nil)); + } + + return form_ex; } - return form_ex; + return form; } else if (sym == lambda_s) { if (!cdr(form)) eval_error(form, lit("~s: missing argument list"), sym, nao); diff --git a/tests/011/macros-3.tl b/tests/011/macros-3.tl index bf7cf9a6..e08e5da7 100644 --- a/tests/011/macros-3.tl +++ b/tests/011/macros-3.tl @@ -10,3 +10,11 @@ (macrolet ((m (:form f) f)) (m)))))) 42) + +(defvar x 0) +(defmacro mac-time-counter () (inc x)) +(defsymacro s (mac-time-counter)) + +(mtest s 1 + s 2 + s 3) @@ -37464,15 +37464,30 @@ between a symbol .meta sym and and a .metn form . -The binding denotes the form itself, rather than its value. How the -symbol macro works is that if +The binding denotes the form itself, rather than its value. + +The +.meta form +argument is not subject to macro expansion; it is associated with .meta sym -occurs as a form in a scope where the symbol macro definition is -in scope, +in its unexpanded state, as it appears in the +.code defmacro +form. + +The +.code defsymacro +form must be evaluated for its defining to to take place; therefore, +the definition is not available in the top-level form which contains the +.code defsymacro +invocation; it becomes available to a subsequent top-level form. + +Subsequent to the evaluation of the +.code defsymacro +definition, whenever the macro expander encounters .meta sym -is replaced by +sym as a form, it replaces it by .metn form . -Immediately after this replacement takes place, +After this replacement takes place, .meta form itself is then processed for further replacement of macros and symbol macros. @@ -37485,14 +37500,6 @@ like .code set and similar. -A -.code defsymacro -form is implicitly executed at expansion time, and thus need -not be wrapped in a -.code macro-time -form, just like -.codn defmacro . - Note: if a symbol macro expands to itself directly, expansion stops. However, if a symbol macro expands to itself through a chain of expansions, runaway expansion-time recursion will occur. @@ -81870,6 +81877,14 @@ of these version values, the described behaviors are provided if is given an argument which is equal or lower. For instance .code "-C 103" selects the behaviors described below for version 105, but not those for 102. +.IP 262 +Selection 262 compatibility restores a wrong behavior which existed between +versions 191 and 262 due to a regression. The wrong behavior is that the +.code defsymacro +operator macro-expanded the replacement form, instead of associating the +macro symbol with the unexpanded form. This makes a crucial difference +to symbol macros which rely on expansion-time effects, such as producing a +different expansion each time they are used. .IP 258 Selecting 258 or lower compatibility causes .code abs-path-p |