Skip to content

Commit

Permalink
Merge pull request #2532 from Kodiologist/macroexpand-as-model
Browse files Browse the repository at this point in the history
Adjust where `as_model` is called in `macroexpand`
  • Loading branch information
Kodiologist committed Nov 15, 2023
2 parents 235637d + b48b2b5 commit 408cc75
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 32 deletions.
6 changes: 3 additions & 3 deletions hy/core/result_macros.py
Expand Up @@ -223,7 +223,7 @@ def render_quoted_form(compiler, form, level):
body = [List(contents)]

if isinstance(form, FString) and form.brackets is not None:
body.extend([Keyword("brackets"), form.brackets])
body.extend([Keyword("brackets"), String(form.brackets)])
elif isinstance(form, FComponent) and form.conversion is not None:
body.extend([Keyword("conversion"), String(form.conversion)])

Expand All @@ -235,7 +235,7 @@ def render_quoted_form(compiler, form, level):

elif isinstance(form, String):
if form.brackets is not None:
body.extend([Keyword("brackets"), form.brackets])
body.extend([Keyword("brackets"), String(form.brackets)])

return (Expression([dotted("hy.models." + name), *body]).replace(form), False)

Expand Down Expand Up @@ -1862,7 +1862,7 @@ def compile_require(compiler, expr, root, entries):
(
String("EXPORTS")
if assignments == "EXPORTS"
else [[String(k), String(v)] for k, v in assignments]
else List([List([String(k), String(v)]) for k, v in assignments])
),
Keyword("prefix"),
String(prefix),
Expand Down
37 changes: 8 additions & 29 deletions hy/macros.py
Expand Up @@ -342,33 +342,13 @@ def __exit__(self, exc_type, exc_value, exc_traceback):


def macroexpand(tree, module, compiler=None, once=False, result_ok=True):
"""Expand the toplevel macros for the given Hy AST tree.
Load the macros from the given `module`, then expand the (top-level) macros
in `tree` until we no longer can. This doesn't work on local macros.
`Expression` resulting from macro expansions are assigned the module in
which the macro function is defined (determined using `inspect.getmodule`).
If the resulting `Expression` is itself macro expanded, then the namespace
of the assigned module is checked first for a macro corresponding to the
expression's head/car symbol. If the head/car symbol of such a `Expression`
is not found among the macros of its assigned module's namespace, the
outer-most namespace--e.g. the one given by the `module` parameter--is used
as a fallback.
Args:
tree (Union[Object, list]): Hy AST tree.
module (Union[str, ModuleType]): Module used to determine the local
namespace for macros.
compiler (Optional[HyASTCompiler] ): The compiler object passed to
expanded macros. Defaults to None
once (bool): Only expand the first macro in `tree`. Defaults to False
result_ok (bool): Whether or not it's okay to return a compiler `Result` instance.
Defaults to True.
Returns:
Union[Object, Result]: A mutated tree with macros expanded.
"""
'''If `tree` isn't an `Expression` that might be a macro call,
return it unchanged. Otherwise, try to expand it. Do this
repeatedly unless `once` is true. Call `as_model` after each
expansion. If the return value is a compiler `Result` object, and
`result_ok` is false, return the previous value. Otherwise, return
the final expansion.'''

if not inspect.ismodule(module):
module = importlib.import_module(module)

Expand Down Expand Up @@ -421,7 +401,7 @@ def macroexpand(tree, module, compiler=None, once=False, result_ok=True):
*([compiler]
if m.__code__.co_varnames[:1] == ('_hy_compiler',)
else []),
*tree[1:])
*map(as_model, tree[1:]))
if isinstance(obj, (hy.compiler.Result, AST)):
return obj if result_ok else tree

Expand All @@ -430,7 +410,6 @@ def macroexpand(tree, module, compiler=None, once=False, result_ok=True):
if once:
break

tree = as_model(tree)
return tree


Expand Down
5 changes: 5 additions & 0 deletions tests/native_tests/hy_misc.hy
Expand Up @@ -40,6 +40,11 @@
(assert (is
(hy.macroexpand f)
f))
; Likewise Expressions that aren't macro calls.
(setv model '(wmbatt 1 2))
(assert (is
(hy.macroexpand model)
model))
; If the macro expands to a `Result`, the user gets the original
; back instead of the `Result`.
(setv model '(+ 1 1))
Expand Down

0 comments on commit 408cc75

Please sign in to comment.