Bang more on BUIlD_MAP_UNPACK

there are still bugs. Note:

{**{'x': 1}, **{'y': 2}} and
{{'x': 1}, **{'y': 2}}

generate the same Python 3.5+ bytecode.
This commit is contained in:
rocky
2017-05-02 21:55:41 -04:00
parent 91b86ac156
commit 246495febd
6 changed files with 20 additions and 15 deletions

Binary file not shown.

View File

@@ -1,7 +1,7 @@
# Python 3.5+ PEP 448 - Additional Unpacking Generalizations for dictionaries
{**{}}
{**{'a': 1, 'b': 2}}
{'x': 1, **{'y': 2}}
## {**{'x': 1}, **{'y': 2}}
# {'c': 1, {'d': 2}, **{'e': 3}}
[*[]]
{**{0:0 for a in b}}

View File

@@ -35,8 +35,6 @@ class PythonParser(GenericASTBuilder):
'exprlist', 'kvlist', 'kwargs', 'come_froms', '_come_from',
# Python < 3
'print_items',
# Python 3.5+
# 'unmap_dict',
# PyPy:
'kvlist_n'])

View File

@@ -663,16 +663,22 @@ class Python3Parser(PythonParser):
rule = 'kvlist_n ::='
self.add_unique_rule(rule, 'kvlist_n', 1, customize)
rule = "mapexpr ::= BUILD_MAP_n kvlist_n"
elif self.version == 3.5:
elif self.version >= 3.5:
if opname != 'BUILD_MAP_WITH_CALL':
if opname == 'BUILD_MAP_UNPACK':
lhs = 'unmap_dict'
else:
lhs = kvlist_n
rule = lhs + ' ::= ' + 'expr ' * (token.attr*2)
rule = kvlist_n + ' ::= ' + 'expr ' * (token.attr*2)
self.add_unique_rule(rule, opname, token.attr, customize)
lhs = 'unmapexpr' if opname == 'BUILD_MAP_UNPACK' else' mapexpr'
rule = "%s ::= %s %s" % (lhs, kvlist_n, opname)
rule = 'dict ::= ' + 'expr ' * (token.attr*2)
self.add_unique_rule(rule, opname, token.attr, customize)
rule = 'mapexpr ::= ' + 'dict ' * token.attr
self.add_unique_rule(rule, opname, token.attr, customize)
rule = ('unmap_dict ::= ' +
('mapexpr ' * token.attr) +
' BUILD_MAP_UNPACK')
else:
rule = kvlist_n + ' ::= ' + 'expr ' * (token.attr*2)
self.add_unique_rule(rule, opname, token.attr, customize)
rule = "mapexpr ::= %s %s" % (kvlist_n, opname)
else:
rule = kvlist_n + ' ::= ' + 'expr expr STORE_MAP ' * token.attr
self.add_unique_rule(rule, opname, token.attr, customize)

View File

@@ -36,10 +36,11 @@ class Python35Parser(Python34Parser):
expr ::= unmap_dict
expr ::= unmapexpr
unmap_dict ::= mapexpr BUILD_MAP_UNPACK
unmap_dict ::= mapexpr unmap_dict
unmap_dict ::= dictcomp BUILD_MAP_UNPACK
build_list ::= expr BUILD_MAP_UNPACK
unmap_dict ::= kv_lists BUILD_MAP_UNPACK
kv_lists ::= kv_list kv_lists
kv_lists ::= kv_list
# Python 3.5+ has WITH_CLEANUP_START/FINISH

View File

@@ -345,7 +345,7 @@ class SourceWalker(GenericASTTraversal, object):
'%|async with %c:\n%+%c%-', 0, 7),
'async_with_as_stmt': (
'%|async with %c as %c:\n%+%c%-', 0, 6, 7),
'unmap_dict': ( '{**%c}', 0),
'unmap_dict': ( '{**%C}', (0, -1, ', **') ),
'unmapexpr': ( '{**%c}', 0),
})
@@ -1433,7 +1433,7 @@ class SourceWalker(GenericASTTraversal, object):
i += 2
pass
pass
elif node[1].type.startswith('kvlist'):
elif len(node) > 1 and node[1].type.startswith('kvlist'):
# Python 3.0..3.4 style key/value list in mapexpr
kv_node = node[1]
l = list(kv_node)