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

View File

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

View File

@@ -663,16 +663,22 @@ class Python3Parser(PythonParser):
rule = 'kvlist_n ::=' rule = 'kvlist_n ::='
self.add_unique_rule(rule, 'kvlist_n', 1, customize) self.add_unique_rule(rule, 'kvlist_n', 1, customize)
rule = "mapexpr ::= BUILD_MAP_n kvlist_n" 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_WITH_CALL':
if opname == 'BUILD_MAP_UNPACK': if opname == 'BUILD_MAP_UNPACK':
lhs = 'unmap_dict' rule = kvlist_n + ' ::= ' + 'expr ' * (token.attr*2)
self.add_unique_rule(rule, opname, token.attr, customize)
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: else:
lhs = kvlist_n rule = kvlist_n + ' ::= ' + 'expr ' * (token.attr*2)
rule = lhs + ' ::= ' + 'expr ' * (token.attr*2) self.add_unique_rule(rule, opname, token.attr, customize)
self.add_unique_rule(rule, opname, token.attr, customize) rule = "mapexpr ::= %s %s" % (kvlist_n, opname)
lhs = 'unmapexpr' if opname == 'BUILD_MAP_UNPACK' else' mapexpr'
rule = "%s ::= %s %s" % (lhs, kvlist_n, opname)
else: else:
rule = kvlist_n + ' ::= ' + 'expr expr STORE_MAP ' * token.attr rule = kvlist_n + ' ::= ' + 'expr expr STORE_MAP ' * token.attr
self.add_unique_rule(rule, opname, token.attr, customize) self.add_unique_rule(rule, opname, token.attr, customize)

View File

@@ -36,10 +36,11 @@ class Python35Parser(Python34Parser):
expr ::= unmap_dict expr ::= unmap_dict
expr ::= unmapexpr expr ::= unmapexpr
unmap_dict ::= mapexpr BUILD_MAP_UNPACK unmap_dict ::= dictcomp BUILD_MAP_UNPACK
unmap_dict ::= mapexpr unmap_dict
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 # 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 %c:\n%+%c%-', 0, 7),
'async_with_as_stmt': ( 'async_with_as_stmt': (
'%|async with %c as %c:\n%+%c%-', 0, 6, 7), '%|async with %c as %c:\n%+%c%-', 0, 6, 7),
'unmap_dict': ( '{**%c}', 0), 'unmap_dict': ( '{**%C}', (0, -1, ', **') ),
'unmapexpr': ( '{**%c}', 0), 'unmapexpr': ( '{**%c}', 0),
}) })
@@ -1433,7 +1433,7 @@ class SourceWalker(GenericASTTraversal, object):
i += 2 i += 2
pass pass
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 # Python 3.0..3.4 style key/value list in mapexpr
kv_node = node[1] kv_node = node[1]
l = list(kv_node) l = list(kv_node)