Drop the bare names that were sprinkled everywhere in the generated AST.

This closes #162

We make sure not to drop *explicitly written* bare names.
This commit is contained in:
Nicolas Dandrimont 2013-05-08 18:49:07 +02:00
parent 04b2d9d291
commit 772927c53d
2 changed files with 28 additions and 1 deletions

View File

@ -193,9 +193,13 @@ class Result(object):
This is useful when we want to use the stored expression in a
statement context (for instance in a code branch).
We drop ast.Names if they are appended to statements, as they
can't have any side effect. "Bare" names still get converted to
statements.
If there is no expression context, return an empty result.
"""
if self.expr:
if self.expr and not (isinstance(self.expr, ast.Name) and self.stmts):
return Result() + ast.Expr(lineno=self.expr.lineno,
col_offset=self.expr.col_offset,
value=self.expr)

View File

@ -1,4 +1,5 @@
# Copyright (c) 2013 Julien Danjou <julien@danjou.info>
# Copyright (c) 2013 Nicolas Dandrimont <nicolas.dandrimont@crans.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@ -29,6 +30,7 @@ else:
from hy.models.expression import HyExpression
from hy.models.list import HyList
from hy.models.symbol import HySymbol
from hy.compiler import HyASTCompiler
@ -63,3 +65,24 @@ class HyASTCompilerTest(unittest.TestCase):
self.assertIsInstance(stmt.body[0], ast.Pass)
self.assertIsInstance(ret.expr, ast.Name)
def test_compiler_bare_names(self):
"""Check that the compiler doesn't drop bare names from code branches"""
ret = self.c.compile(self._make_expression(HySymbol("do"),
HySymbol("a"),
HySymbol("b"),
HySymbol("c")))
# We expect two statements and a final expr.
self.assertEqual(len(ret.stmts), 2)
stmt = ret.stmts[0]
self.assertIsInstance(stmt, ast.Expr)
self.assertIsInstance(stmt.value, ast.Name)
self.assertEqual(stmt.value.id, "a")
stmt = ret.stmts[1]
self.assertIsInstance(stmt, ast.Expr)
self.assertIsInstance(stmt.value, ast.Name)
self.assertEqual(stmt.value.id, "b")
expr = ret.expr
self.assertIsInstance(expr, ast.Name)
self.assertEqual(expr.id, "c")