Copy in compile_atom instead of macroexpand_1

This copying is what keeps all the mutating code in the compiler methods (e.g., `expr.pop(0)`) from breaking cases in which Hy model objects are compiled more than once or inspected after compilation.
This commit is contained in:
Kodi Arfer 2018-04-06 13:12:48 -07:00
parent 4a6b633ad2
commit 116d7fa6ec
2 changed files with 4 additions and 5 deletions

View File

@ -423,6 +423,8 @@ class HyASTCompiler(object):
# pass in `atom_type`.
atom_compiler = _compile_table[atom_type]
arity = hy.inspect.get_arity(atom_compiler)
# Compliation methods may mutate the atom, so copy it first.
atom = copy.copy(atom)
ret = (atom_compiler(self, atom, atom_type)
if arity == 3
else atom_compiler(self, atom))

View File

@ -181,8 +181,6 @@ def macroexpand_1(tree, compiler):
fn = tree[0]
if fn in ("quote", "quasiquote"):
return tree
ntree = HyExpression(tree[:])
ntree.replace(tree)
opts = {}
@ -197,14 +195,14 @@ def macroexpand_1(tree, compiler):
try:
m_copy = make_empty_fn_copy(m)
m_copy(compiler.module_name, *ntree[1:], **opts)
m_copy(compiler.module_name, *tree[1:], **opts)
except TypeError as e:
msg = "expanding `" + str(tree[0]) + "': "
msg += str(e).replace("<lambda>()", "", 1).strip()
raise HyMacroExpansionError(tree, msg)
try:
obj = m(compiler.module_name, *ntree[1:], **opts)
obj = m(compiler.module_name, *tree[1:], **opts)
except HyTypeError as e:
if e.expression is None:
e.expression = tree
@ -214,7 +212,6 @@ def macroexpand_1(tree, compiler):
raise HyMacroExpansionError(tree, msg)
replace_hy_obj(obj, tree)
return obj
return ntree
return tree