Start to handle 3.5 build_map_unpack_with_call

3.6 also started but needs even more work
This commit is contained in:
rocky
2016-12-16 20:39:24 -05:00
parent 7755563b65
commit 08dcc7d820
7 changed files with 43 additions and 10 deletions

Binary file not shown.

View File

@@ -0,0 +1 @@
f(**a, **b)

View File

@@ -590,9 +590,10 @@ class Python3Parser(PythonParser):
self.add_unique_rule(rule, 'kvlist_n', 1, customize)
rule = "mapexpr ::= BUILD_MAP_n kvlist_n"
elif self.version >= 3.5:
rule = kvlist_n + ' ::= ' + 'expr ' * (token.attr*2)
self.add_unique_rule(rule, opname, token.attr, customize)
rule = "mapexpr ::= %s %s" % (kvlist_n, opname)
if opname != 'BUILD_MAP_WITH_CALL':
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

@@ -47,6 +47,26 @@ class Python35Parser(Python34Parser):
yield_from ::= expr GET_YIELD_FROM_ITER LOAD_CONST YIELD_FROM
"""
def add_custom_rules(self, tokens, customize):
super(Python35Parser, self).add_custom_rules(tokens, customize)
for i, token in enumerate(tokens):
opname = token.type
if opname == 'BUILD_MAP_UNPACK_WITH_CALL':
nargs = token.attr % 256
map_unpack_n = "map_unpack_%s" % nargs
rule = map_unpack_n + ' ::= ' + 'expr ' * (nargs)
self.add_unique_rule(rule, opname, token.attr, customize)
rule = "unmapexpr ::= %s %s" % (map_unpack_n, opname)
self.add_unique_rule(rule, opname, token.attr, customize)
call_token = tokens[i+1]
if self.version == 3.5:
rule = 'call_function ::= expr unmapexpr ' + call_token.type
self.add_unique_rule(rule, opname, token.attr, customize)
pass
pass
return
class Python35ParserSingle(Python35Parser, PythonParserSingle):
pass

View File

@@ -18,6 +18,9 @@ class Python36Parser(Python35Parser):
"""
fstring_multi ::= fstring_expr_or_strs BUILD_STRING
fstring_expr_or_strs ::= fstring_expr_or_str+
func_args36 ::= expr BUILD_TUPLE_0
call_function ::= func_args36 unmapexpr CALL_FUNCTION_EX
"""
def add_custom_rules(self, tokens, customize):
@@ -46,6 +49,7 @@ class Python36Parser(Python35Parser):
""" % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v)
self.add_unique_doc_rules(rules_str, customize)
class Python36ParserSingle(Python36Parser, PythonParserSingle):
pass

View File

@@ -684,11 +684,6 @@ class Scanner3(Scanner):
# rocky: if we have a conditional jump to the next instruction, then
# possibly I am "skipping over" a "pass" or null statement.
try:
code[prev_op[target]]
except:
from trepan.api import debug; debug()
if ((code[prev_op[target]] in self.pop_jump_if_pop) and
(target > offset) and prev_op[target] != offset):
self.fixed_jumps[offset] = prev_op[target]

View File

@@ -352,7 +352,7 @@ MAP_R = (TABLE_R, -1)
MAP = {
'stmt': MAP_R,
'call_function': MAP_R,
'call_function': MAP_R,
'del_stmt': MAP_R,
'designator': MAP_R,
'exprlist': MAP_R0,
@@ -630,6 +630,19 @@ class SourceWalker(GenericASTTraversal, object):
TABLE_DIRECT.update({
'LOAD_CLASSDEREF': ( '%{pattr}', ),
})
if version >= 3.5:
def n_unmapexpr(node):
last_n = node[0][-1]
for n in node[0]:
self.preorder(n)
if n != last_n:
self.f.write(', **')
pass
pass
self.prune()
pass
self.n_unmapexpr = n_unmapexpr
if version >= 3.6:
########################
# Python 3.6+ Additions
@@ -653,7 +666,6 @@ class SourceWalker(GenericASTTraversal, object):
def n_fstring_single(node):
f_conversion(node)
self.default(node)
self.n_fstring_single = n_fstring_single
return