Add 3.5+ async with/for ..

scanner3.py: 3.6 bytecode vs wordcode fix
This commit is contained in:
rocky
2017-01-08 08:54:03 -05:00
parent 66741d16ba
commit 21023fea74
6 changed files with 109 additions and 14 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +1,26 @@
# Python 3.5+ async and await
async def foo():
async def await_test():
await bar()
async def afor_test():
async for i in [1,2,3]:
x = i
async def afor_else_test():
async for i in [1,2,3]:
x = i
else:
z = 4
async def awith_test():
async with i:
print(i)
async def awith_as_test():
async with 1 as i:
print(i)

View File

@@ -16,23 +16,79 @@ class Python35Parser(Python34Parser):
def p_35on(self, args):
"""
# The number of canned instructions in new statements is mind boggling.
# I'm sure by the time Python 4 comes around these will be turned
# into special opcodes
# Python 3.5+ Await statement
sstmt ::= await_stmt
stmt ::= await_stmt
await_stmt ::= call_function GET_AWAITABLE LOAD_CONST YIELD_FROM POP_TOP
# Python 3.5+ has WITH_CLEANUP_START/FINISH
withstmt ::= expr SETUP_WITH exprlist suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
withstmt ::= expr
SETUP_WITH exprlist suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
withstmt ::= expr
SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
withasstmt ::= expr
SETUP_WITH designator suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
# Python 3.5+ async additions
stmt ::= async_with_stmt
async_with_stmt ::= expr
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
SETUP_ASYNC_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST
WITH_CLEANUP_START
GET_AWAITABLE LOAD_CONST YIELD_FROM
WITH_CLEANUP_FINISH END_FINALLY
stmt ::= async_with_as_stmt
async_with_as_stmt ::= expr
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
SETUP_ASYNC_WITH designator suite_stmts_opt
POP_BLOCK LOAD_CONST
WITH_CLEANUP_START
GET_AWAITABLE LOAD_CONST YIELD_FROM
WITH_CLEANUP_FINISH END_FINALLY
stmt ::= async_for_stmt
async_for_stmt ::= SETUP_LOOP expr
GET_AITER
LOAD_CONST YIELD_FROM SETUP_EXCEPT GET_ANEXT LOAD_CONST
YIELD_FROM
designator
POP_BLOCK JUMP_FORWARD COME_FROM_EXCEPT DUP_TOP
LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_FALSE
POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_BLOCK
JUMP_ABSOLUTE END_FINALLY COME_FROM
for_block POP_BLOCK JUMP_ABSOLUTE
opt_come_from_loop
stmt ::= async_forelse_stmt
async_forelse_stmt ::= SETUP_LOOP expr
GET_AITER
LOAD_CONST YIELD_FROM SETUP_EXCEPT GET_ANEXT LOAD_CONST
YIELD_FROM
designator
POP_BLOCK JUMP_FORWARD COME_FROM_EXCEPT DUP_TOP
LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_FALSE
POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_BLOCK
JUMP_ABSOLUTE END_FINALLY COME_FROM
for_block POP_BLOCK JUMP_ABSOLUTE
else_suite COME_FROM_LOOP
withasstmt ::= expr SETUP_WITH designator suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
inplace_op ::= INPLACE_MATRIX_MULTIPLY
binary_op ::= BINARY_MATRIX_MULTIPLY

View File

@@ -461,11 +461,15 @@ class Scanner3(Scanner):
has_arg = (op >= op3.HAVE_ARGUMENT)
if has_arg:
label = self.fixed_jumps.get(offset)
oparg = code[offset+1] + code[offset+2] * 256
if self.version >= 3.6:
oparg = code[offset+1]
else:
oparg = code[offset+1] + code[offset+2] * 256
next_offset = offset + self.op_size(op)
if label is None:
if op in op3.hasjrel and op != self.opc.FOR_ITER:
label = offset + 3 + oparg
label = next_offset + oparg
elif op in op3.hasjabs:
if op in self.jump_if_pop:
if oparg > offset:

View File

@@ -649,9 +649,21 @@ class SourceWalker(GenericASTTraversal, object):
TABLE_DIRECT.update({
'LOAD_CLASSDEREF': ( '%{pattr}', ),
})
########################
# Python 3.5+ Additions
#######################
if version >= 3.5:
TABLE_DIRECT.update({
'await_stmt': ( '%|await %c', 0),
'await_stmt': ( '%|await %c', 0),
'async_for_stmt': (
'%|async for %c in %c:\n%+%c%-\n\n', 9, 1, 25 ),
'async_forelse_stmt': (
'%|async for %c in %c:\n%+%c%-%|else:\n%+%c%-\n\n', 9, 1, 25, 28 ),
'async_with_stmt': (
'%|async with %c:\n%+%c%-', 0, 7),
'async_with_as_stmt': (
'%|async with %c as %c:\n%+%c%-', 0, 6, 7),
})
def n_funcdef(node):
code_node = node[0][1]