Bang on BUILD_MAP_UNPACK_WITH_CALL a little...

more cases are needed still. And there's a bug in BUILD_TUPLE_UNPACK_WITH_CALL now
in adding the count twice.
This commit is contained in:
rocky
2017-12-12 07:05:32 -05:00
parent ec1be81de7
commit 0059f53196
3 changed files with 92 additions and 74 deletions

View File

@@ -104,6 +104,18 @@ class Python36Parser(Python35Parser):
%s ::= %sBUILD_STRING %s ::= %sBUILD_STRING
""" % (joined_str_n, joined_str_n, "formatted_value " * v) """ % (joined_str_n, joined_str_n, "formatted_value " * v)
self.add_unique_doc_rules(rules_str, customize) self.add_unique_doc_rules(rules_str, customize)
elif opname.startswith('BUILD_MAP_UNPACK_WITH_CALL'):
v = token.attr
rule = ('build_map_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
'expr32 ' * int((v//32) % 32) +
'expr ' * (v % 32) + opname)
self.addRule(rule, nop_func)
elif opname.startswith('BUILD_TUPLE_UNPACK_WITH_CALL'):
v = token.attr
rule = ('build_tuple_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
'expr32 ' * int((v//32) % 32) +
'expr ' * (v % 32) + opname)
self.addRule(rule, nop_func)
elif opname == 'SETUP_WITH': elif opname == 'SETUP_WITH':
rules_str = """ rules_str = """
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST
@@ -121,23 +133,15 @@ class Python36Parser(Python35Parser):
self.addRule(rule, nop_func) self.addRule(rule, nop_func)
rule = 'kwargs_36 ::= {values} LOAD_CONST'.format(**locals()) rule = 'kwargs_36 ::= {values} LOAD_CONST'.format(**locals())
self.add_unique_rule(rule, token.kind, token.attr, customize) self.add_unique_rule(rule, token.kind, token.attr, customize)
elif opname.startswith('BUILD_TUPLE_UNPACK_WITH_CALL'):
v = token.attr
rule = ('build_tuple_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
'expr32 ' * int((v//32) % 32) +
'expr ' * (v % 32) + opname)
self.addRule(rule, nop_func)
elif opname == 'CALL_FUNCTION_EX_KW': elif opname == 'CALL_FUNCTION_EX_KW':
args_pos, args_kw = self.get_pos_kw(token) self.addRule("""expr ::= call_ex_kw
uniq_param = args_kw + args_pos call_ex_kw ::= expr expr build_map_unpack_with_call
self.addRule("expr ::= call_ex_kw", nop_func) CALL_FUNCTION_EX_KW
rule = ('call_ex_kw ::= ' """,
'expr build_tuple_unpack_with_call build_map_unpack_with_call ' nop_func)
'CALL_FUNCTION_EX_KW')
self.addRule(rule, nop_func)
elif opname == 'CALL_FUNCTION_EX': elif opname == 'CALL_FUNCTION_EX':
self.addRule("expr ::= call_ex", nop_func)
self.addRule(""" self.addRule("""
expr ::= call_ex
unpack_list ::= list unpack_list ::= list
call_ex ::= expr unpack_list CALL_FUNCTION_EX call_ex ::= expr unpack_list CALL_FUNCTION_EX
""", nop_func) """, nop_func)

View File

@@ -439,55 +439,8 @@ class SourceWalker(GenericASTTraversal, object):
# 'unmapexpr': ( '{**%c}', 0), # done by n_unmapexpr # 'unmapexpr': ( '{**%c}', 0), # done by n_unmapexpr
}) })
if version >= 3.6:
TABLE_DIRECT.update({
'try_except36': ( '%|try:\n%+%c%-%c\n\n', 1, 2 ),
'unpack_list': ( '*%c', (0, 'list') ),
'call_ex' : (
'%c(%c)',
(0, 'expr'), 1),
})
def n_build_tuple_unpack_with_call(node): def async_call(node):
if node[0] == 'expr':
first = node[0][0]
else:
first = node[0]
pass
if first == 'tuple':
# Note: don't iteratee over last element which is a
# BUILD_TUPLE...
flat_elems = flatten_list(first[:-1], INDENT_PER_LEVEL)
self.indent_more(INDENT_PER_LEVEL)
sep = ''
for elem in flat_elems:
if elem in ('ROT_THREE', 'EXTENDED_ARG'):
continue
assert elem == 'expr'
line_number = self.line_number
value = self.traverse(elem)
if line_number != self.line_number:
sep += '\n' + self.indent + INDENT_PER_LEVEL[:-1]
self.write(sep, value)
sep = ', '
self.indent_less(INDENT_PER_LEVEL)
btuwc = node[-1]
assert btuwc.kind.startswith('BUILD_TUPLE_UNPACK_WITH_CALL')
for n in node[1:-1]:
self.f.write(', *')
self.preorder(n)
pass
self.prune()
return
self.n_build_tuple_unpack_with_call = n_build_tuple_unpack_with_call
def n_async_call(node):
self.f.write('async ') self.f.write('async ')
node.kind == 'call' node.kind == 'call'
p = self.prec p = self.prec
@@ -497,7 +450,7 @@ class SourceWalker(GenericASTTraversal, object):
self.prec = p self.prec = p
node.kind == 'async_call' node.kind == 'async_call'
self.prune() self.prune()
self.n_async_call = n_async_call self.n_async_call = async_call
self.n_build_list_unpack = self.n_list self.n_build_list_unpack = self.n_list
if version == 3.5: if version == 3.5:
@@ -543,7 +496,7 @@ class SourceWalker(GenericASTTraversal, object):
self.prune() self.prune()
self.n_function_def = n_function_def self.n_function_def = n_function_def
def n_unmapexpr(node): def unmapexpr(node):
last_n = node[0][-1] last_n = node[0][-1]
for n in node[0]: for n in node[0]:
self.preorder(n) self.preorder(n)
@@ -553,40 +506,101 @@ class SourceWalker(GenericASTTraversal, object):
pass pass
self.prune() self.prune()
pass pass
self.n_unmapexpr = n_unmapexpr self.n_unmapexpr = unmapexpr
if version >= 3.6: if version >= 3.6:
######################## ########################
# Python 3.6+ Additions # Python 3.6+ Additions
####################### #######################
TABLE_DIRECT.update({ TABLE_DIRECT.update({
'fstring_expr': ( "{%c%{conversion}}", 0), 'fstring_expr': ( "{%c%{conversion}}", 0),
'fstring_single': ( "f'{%c%{conversion}}'", 0), 'fstring_single': ( "f'{%c%{conversion}}'", 0),
'fstring_multi': ( "f'%c'", 0), 'fstring_multi': ( "f'%c'", 0),
'func_args36': ( "%c(**", 0), 'func_args36': ( "%c(**", 0),
#'kwargs_only_36': ( "%c(**", 0), 'try_except36': ( '%|try:\n%+%c%-%c\n\n', 1, 2 ),
'unpack_list': ( '*%c', (0, 'list') ),
'call_ex' : (
'%c(%c)',
(0, 'expr'), 1),
'call_ex_kw' : (
'%c(%c)',
(0, 'expr'), 2),
}) })
TABLE_R.update({ TABLE_R.update({
'CALL_FUNCTION_EX': ('%c(*%P)', 0, (1, 2, ', ', 100)), 'CALL_FUNCTION_EX': ('%c(*%P)', 0, (1, 2, ', ', 100)),
# Not quite right # Not quite right
'CALL_FUNCTION_EX_KW': ('%c(**%C)', 0, (2,3, ',')), 'CALL_FUNCTION_EX_KW': ('%c(**%C)', 0, (2,3, ',')),
}) })
def build_unpack_tuple_with_call(node):
if node[0] == 'expr':
first = node[0][0]
else:
first = node[0]
pass
assert first == 'tuple'
# Note: don't iterate over last element which is a
# BUILD_TUPLE...
flat_elems = flatten_list(first[:-1])
self.indent_more(INDENT_PER_LEVEL)
sep = ''
for elem in flat_elems:
if elem in ('ROT_THREE', 'EXTENDED_ARG'):
continue
assert elem == 'expr'
line_number = self.line_number
value = self.traverse(elem)
if line_number != self.line_number:
sep += '\n' + self.indent + INDENT_PER_LEVEL[:-1]
self.write(sep, value)
sep = ', '
self.indent_less(INDENT_PER_LEVEL)
buwc = node[-1]
assert buwc.kind.startswith('BUILD_TUPLE_UNPACK_WITH_CALL')
for n in node[1:-1]:
self.f.write(', *')
self.preorder(n)
pass
self.prune()
return
self.n_build_tuple_unpack_with_call = build_unpack_tuple_with_call
def build_unpack_map_with_call(node):
sep = '**'
for n in node[:-1]:
self.f.write(sep)
self.preorder(n)
sep = ', **'
pass
self.prune()
return
self.n_build_map_unpack_with_call = build_unpack_map_with_call
FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'} FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'}
def f_conversion(node): def f_conversion(node):
node.conversion = FSTRING_CONVERSION_MAP.get(node.data[1].attr, '') node.conversion = FSTRING_CONVERSION_MAP.get(node.data[1].attr, '')
def n_fstring_expr(node): def fstring_expr(node):
f_conversion(node) f_conversion(node)
self.default(node) self.default(node)
self.n_fstring_expr = n_fstring_expr self.n_fstring_expr = fstring_expr
def n_fstring_single(node): def fstring_single(node):
f_conversion(node) f_conversion(node)
self.default(node) self.default(node)
self.n_fstring_single = n_fstring_single self.n_fstring_single = fstring_single
def n_kwargs_only_36(node): def kwargs_only_36(node):
keys = node[-1].attr keys = node[-1].attr
num_kwargs = len(keys) num_kwargs = len(keys)
values = node[:num_kwargs] values = node[:num_kwargs]
@@ -597,13 +611,13 @@ class SourceWalker(GenericASTTraversal, object):
self.write(',') self.write(',')
self.prune() self.prune()
return return
self.n_kwargs_only_36 = n_kwargs_only_36 self.n_kwargs_only_36 = kwargs_only_36
def n_return_closure(node): def return_closure(node):
# Nothing should be output here # Nothing should be output here
self.prune() self.prune()
return return
self.n_return_closure = n_return_closure self.n_return_closure = return_closure
pass # version > 3.6 pass # version > 3.6
pass # version > 3.4 pass # version > 3.4
pass # version > 3.0 pass # version > 3.0