Move logic from macroexpand_1 to macroexpand
By ending macro-expansion immediately when appropriate, this change fixes a bug arising from the fact that NaN != NaN.
This commit is contained in:
parent
026316ebef
commit
c1a487cdf7
1
NEWS.rst
1
NEWS.rst
@ -42,6 +42,7 @@ Bug Fixes
|
|||||||
* Fixed a case where `->` and `->>` duplicated an argument
|
* Fixed a case where `->` and `->>` duplicated an argument
|
||||||
* Fixed bugs that caused `defclass` to drop statements or crash
|
* Fixed bugs that caused `defclass` to drop statements or crash
|
||||||
* Fixed a REPL crash caused by illegle unicode escape string inputs
|
* Fixed a REPL crash caused by illegle unicode escape string inputs
|
||||||
|
* `NaN` can no longer create an infinite loop during macro-expansion
|
||||||
|
|
||||||
Misc. Improvements
|
Misc. Improvements
|
||||||
----------------------------
|
----------------------------
|
||||||
|
25
hy/macros.py
25
hy/macros.py
@ -156,24 +156,16 @@ def make_empty_fn_copy(fn):
|
|||||||
return empty_fn
|
return empty_fn
|
||||||
|
|
||||||
|
|
||||||
def macroexpand(tree, compiler):
|
def macroexpand(tree, compiler, once=False):
|
||||||
"""Expand the toplevel macros for the `tree`.
|
"""Expand the toplevel macros for the `tree`.
|
||||||
|
|
||||||
Load the macros from the given `module_name`, then expand the (top-level)
|
Load the macros from the given `module_name`, then expand the (top-level)
|
||||||
macros in `tree` until it stops changing.
|
macros in `tree` until we no longer can.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
load_macros(compiler.module_name)
|
load_macros(compiler.module_name)
|
||||||
old = None
|
while True:
|
||||||
while old != tree:
|
|
||||||
old = tree
|
|
||||||
tree = macroexpand_1(tree, compiler)
|
|
||||||
return tree
|
|
||||||
|
|
||||||
|
|
||||||
def macroexpand_1(tree, compiler):
|
|
||||||
"""Expand the toplevel macro from `tree` once, in the context of
|
|
||||||
`module_name`."""
|
|
||||||
if not isinstance(tree, HyExpression) or tree == []:
|
if not isinstance(tree, HyExpression) or tree == []:
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
@ -207,7 +199,16 @@ def macroexpand_1(tree, compiler):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = "expanding `" + str(tree[0]) + "': " + repr(e)
|
msg = "expanding `" + str(tree[0]) + "': " + repr(e)
|
||||||
raise HyMacroExpansionError(tree, msg)
|
raise HyMacroExpansionError(tree, msg)
|
||||||
return replace_hy_obj(obj, tree)
|
tree = replace_hy_obj(obj, tree)
|
||||||
|
|
||||||
|
if once:
|
||||||
|
return tree
|
||||||
|
|
||||||
|
|
||||||
|
def macroexpand_1(tree, compiler):
|
||||||
|
"""Expand the toplevel macro from `tree` once, in the context of
|
||||||
|
`compiler`."""
|
||||||
|
return macroexpand(tree, compiler, once=True)
|
||||||
|
|
||||||
|
|
||||||
def tag_macroexpand(tag, tree, compiler):
|
def tag_macroexpand(tag, tree, compiler):
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
from hy.macros import macro, macroexpand
|
from hy.macros import macro, macroexpand
|
||||||
from hy.lex import tokenize
|
from hy.lex import tokenize
|
||||||
|
|
||||||
from hy.models import HyString, HyList, HySymbol, HyExpression
|
from hy.models import HyString, HyList, HySymbol, HyExpression, HyFloat
|
||||||
from hy.errors import HyMacroExpansionError
|
from hy.errors import HyMacroExpansionError
|
||||||
|
|
||||||
from hy.compiler import HyASTCompiler
|
from hy.compiler import HyASTCompiler
|
||||||
@ -53,3 +53,12 @@ def test_preprocessor_exceptions():
|
|||||||
except HyMacroExpansionError as e:
|
except HyMacroExpansionError as e:
|
||||||
assert "_hy_anon_fn_" not in str(e)
|
assert "_hy_anon_fn_" not in str(e)
|
||||||
assert "TypeError" not in str(e)
|
assert "TypeError" not in str(e)
|
||||||
|
|
||||||
|
|
||||||
|
def test_macroexpand_nan():
|
||||||
|
# https://github.com/hylang/hy/issues/1574
|
||||||
|
import math
|
||||||
|
NaN = float('nan')
|
||||||
|
x = macroexpand(HyFloat(NaN), HyASTCompiler(__name__))
|
||||||
|
assert type(x) is HyFloat
|
||||||
|
assert math.isnan(x)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user