Skip to content

Commit

Permalink
Fix bug: is_lvalue should check recursively
Browse files Browse the repository at this point in the history
  • Loading branch information
hsfzxjy committed Feb 7, 2021
1 parent f0af419 commit 55fbfb6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
3 changes: 2 additions & 1 deletion lambdex/compiler/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,5 @@ def assert_name_in(self, clause, names):
self.assert_(clause.name in names, 'expect ' + ' or '.join(names), clause.node)

def assert_lvalue(self, node):
self.assert_(is_lvalue(node), EM_NOT_LVALUE, node)
check_result, failed_at = is_lvalue(node)
self.assert_(check_result, EM_NOT_LVALUE, failed_at)
16 changes: 14 additions & 2 deletions lambdex/utils/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,21 @@ def copy_lineinfo(src: ast.AST, dst: ast.AST):

def is_lvalue(node: ast.AST) -> bool:
"""
Check whether `node` has field `ctx` (so that it can be used as L-value).
Check whether `node` can be L-value.
"""
return hasattr(node, 'ctx')
from collections import deque
todo = deque([node])
while todo:
n = todo.popleft()
if 'ctx' not in n._fields:
return False, n
if isinstance(n, (ast.List, ast.Tuple, ast.Starred)):
todo.extend(
cn for cn in ast.iter_child_nodes(n) \
if not isinstance(cn, ast.expr_context)
)

return True, None


def cast_to_lvalue(node: ast.AST):
Expand Down

0 comments on commit 55fbfb6

Please sign in to comment.