diff options
-rw-r--r-- | eval.c | 32 | ||||
-rw-r--r-- | txr.1 | 39 |
2 files changed, 67 insertions, 4 deletions
@@ -4501,7 +4501,7 @@ val macro_form_p(val form, val menv) return nil; } -static val macroexpand_1(val form, val menv) +static val do_macroexpand_1(val form, val menv, val (*lookup)(val, val)) { val macro; @@ -4514,7 +4514,7 @@ static val macroexpand_1(val form, val menv) return rlcp_tree(rlcp_tree(mac_expand, form), macro); } - if (bindable(form) && (macro = lookup_symac(menv, form))) { + if (bindable(form) && (macro = lookup(menv, form))) { val mac_expand = cdr(macro); if (mac_expand == form) return form; @@ -4524,16 +4524,36 @@ static val macroexpand_1(val form, val menv) return form; } -static val macroexpand(val form, val menv) +static val macroexpand_1(val form, val menv) +{ + return do_macroexpand_1(form, menv, lookup_symac); +} + +static val macroexpand_1_lisp1(val form, val menv) +{ + return do_macroexpand_1(form, menv, lookup_symac_lisp1); +} + +static val do_macroexpand(val form, val menv, val (*lookup_sm)(val, val)) { for (;;) { - val mac_expand = macroexpand_1(form, menv); + val mac_expand = do_macroexpand_1(form, menv, lookup_sm); if (mac_expand == form) return form; form = mac_expand; } } +static val macroexpand(val form, val menv) +{ + return do_macroexpand(form, menv, lookup_symac); +} + +static val macroexpand_lisp1(val form, val menv) +{ + return do_macroexpand(form, menv, lookup_symac_lisp1); +} + static val constantp_noex(val form) { if (consp(form)) { @@ -5976,8 +5996,12 @@ void eval_init(void) reg_fun(intern(lit("macro-form-p"), user_package), func_n2o(macro_form_p, 1)); reg_fun(intern(lit("macroexpand-1"), user_package), func_n2o(macroexpand_1, 1)); + reg_fun(intern(lit("macroexpand-1-lisp1"), user_package), + func_n2o(macroexpand_1_lisp1, 1)); reg_fun(intern(lit("macroexpand"), user_package), func_n2o(macroexpand, 1)); + reg_fun(intern(lit("macroexpand-lisp1"), user_package), + func_n2o(macroexpand_lisp1, 1)); reg_fun(intern(lit("expand-params"), system_package), func_n5(expand_params)); reg_fun(intern(lit("constantp"), user_package), func_n2o(constantp, 1)); reg_fun(intern(lit("make-env"), user_package), func_n3o(make_env_intrinsic, 0)); @@ -30172,6 +30172,45 @@ and .code a respectively. +.coNP Functions @ macroexpand-1-lisp1 and @ macroexpand-lisp1 +.synb +.mets (macroexpand-1-lisp1 < obj <> [ env ]) +.mets (macroexpand-lisp1 < obj <> [ env ]) +.syne +.desc +The +.code macroexpand-1-lisp1 +and +.code macroexpand-lisp1 +functions closely resemble, respectively, +.code macroexpand-1 +and +.codn macroexpand . + +The argument and return value syntax and semantics is almost +identical, except for one difference. These functions consider argument +.meta obj +to be syntax in a Lisp-1 evaluation context, such as any argument +position of the +.code dwim +operator, or the equivalent DWIM Brackets notation. + +This makes a difference because in a Lisp-1 evaluation context, an +inner function binding is able to shadow an outer symbol macro binding +of the same name. + +The requirements about this language area are given in more +detail in the description of the +.code dwim +operator. + +Note: the +.code macroexpand-lisp1 +function is useful to the implementor of a macro whose semantics requires +one or more argument forms to be treated in a Lisp-1 context, in situations +when such a macro needs to itself expand the material, rather than merely +insert it as-is into the output code template. + .coNP Functions @ lexical-var-p and @ lexical-fun-p .synb .mets (lexical-var-p < env << form ) |