From 387bc0d9f2c45555d5a963b46c9b98157731c1e6 Mon Sep 17 00:00:00 2001 From: Nicolas Dandrimont Date: Fri, 3 May 2013 17:49:45 +0200 Subject: [PATCH] Split eval in two steps to allow eval'ing statements We compile the evaluated operand, separating the body (statements) from the expression. We then eval() those separately, and return the evaluated expression. --- hy/importer.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hy/importer.py b/hy/importer.py index 2368439..8ad8d45 100644 --- a/hy/importer.py +++ b/hy/importer.py @@ -91,8 +91,22 @@ def hy_eval(hytree, namespace): foo.start_column = 0 foo.end_column = 0 hytree.replace(foo) - _ast = hy_compile(hytree, root=ast.Expression) - return eval(ast_compile(_ast, "", "eval"), namespace) + _ast, expr = hy_compile(hytree, get_expr=True) + + # Spoof the positions in the generated ast... + for node in ast.walk(_ast): + node.lineno = 1 + node.col_offset = 1 + + for node in ast.walk(expr): + node.lineno = 1 + node.col_offset = 1 + + # Two-step eval: eval() the body of the exec call + eval(ast_compile(_ast, "", "exec"), namespace) + + # Then eval the expression context and return that + return eval(ast_compile(expr, "", "eval"), namespace) def write_hy_as_pyc(fname):