You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
2.6 ifelse/while modifications
This commit is contained in:
BIN
test/bytecode_2.6/07_for_if_continue.pyc
Normal file
BIN
test/bytecode_2.6/07_for_if_continue.pyc
Normal file
Binary file not shown.
16
test/simple_source/stmts/07_for_if_continue.py
Normal file
16
test/simple_source/stmts/07_for_if_continue.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# Python 2.6.9 Cookie.py
|
||||
# Problem in 2.6 is making sure
|
||||
# the two JUMP_ABSOLUTES get turned into:
|
||||
# 26 CONTINUE 7 '7'
|
||||
# 29 JUMP_BACK 7 '7'
|
||||
# The fact that the "continue" is on the same
|
||||
# line as the "if" is important.
|
||||
|
||||
for K in items:
|
||||
if V: continue
|
||||
|
||||
# 32 CONTINUE 7 '7'
|
||||
# 35 JUMP_FORWARD 1 (to 39)
|
||||
for K,V in items:
|
||||
if V == "": continue
|
||||
if K not in attrs: continue
|
@@ -57,29 +57,47 @@ class Python26Parser(Python2Parser):
|
||||
|
||||
"""
|
||||
|
||||
def p_misc26(self, args):
|
||||
# In contrast to Python 2.7, Python 2.6 has a lot of
|
||||
# POP_TOP's which come right after various jumps.
|
||||
# The COME_FROM instructions our scanner adds, here it is to assist
|
||||
# distinguishing the extraneous POP_TOPs from those that start
|
||||
# after one of these jumps
|
||||
def p_jumps26(self, args):
|
||||
"""
|
||||
jmp_false ::= JUMP_IF_FALSE
|
||||
jmp_true ::= JUMP_IF_TRUE
|
||||
jmp_true ::= JUMP_IF_TRUE POP_TOP
|
||||
jmp_false ::= JUMP_IF_FALSE POP_TOP
|
||||
jf_pop ::= JUMP_FORWARD come_from_pop
|
||||
jb_pop ::= JUMP_BACK come_from_pop
|
||||
|
||||
jb_cf_pop ::= JUMP_BACK come_froms POP_TOP
|
||||
ja_cf_pop ::= JUMP_ABSOLUTE come_from_pop
|
||||
|
||||
_ifstmts_jump ::= c_stmts_opt jf_pop COME_FROM
|
||||
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM come_from_pop
|
||||
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms POP_TOP COME_FROM
|
||||
|
||||
# This is what happens after a jump where
|
||||
# we start a new block. For reasons I don't fully
|
||||
# understand, there is also a value on the top of the stack
|
||||
come_from_pop ::= COME_FROM POP_TOP
|
||||
|
||||
_ifstmts_jump ::= c_stmts_opt jf_pop COME_FROM
|
||||
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM come_from_pop
|
||||
"""
|
||||
|
||||
def p_stmt26(self, args):
|
||||
"""
|
||||
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 come_from_pop
|
||||
ifelsestmt ::= testexpr c_stmts_opt jf_pop else_suite COME_FROM
|
||||
|
||||
# This rule is contorted a little to make sutie_stmts_opt be the
|
||||
# forth argument for the semantic routines.
|
||||
ifelsestmt ::= testexpr c_stmts_opt jf_pop else_suite COME_FROM
|
||||
ifelsestmt ::= testexpr c_stmts_opt else_suitel come_froms POP_TOP
|
||||
|
||||
# Semantic actions want else_suitel to be at index 2 or 3
|
||||
ifelsestmtl ::= testexpr c_stmts_opt jb_cf_pop else_suitel
|
||||
ifelsestmtc ::= testexpr c_stmts_opt ja_cf_pop else_suitec
|
||||
|
||||
iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE come_froms POP_TOP
|
||||
|
||||
# Semantic actions want suite_stmts_opt to be at index 3
|
||||
withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt
|
||||
POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY
|
||||
|
||||
@@ -87,12 +105,14 @@ class Python26Parser(Python2Parser):
|
||||
# opcode SETUP_WITH
|
||||
setupwith ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 POP_TOP
|
||||
|
||||
whilestmt ::= SETUP_LOOP
|
||||
testexpr
|
||||
l_stmts_opt jb_pop
|
||||
POP_BLOCK _come_from
|
||||
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_pop POP_BLOCK _come_from
|
||||
|
||||
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop POP_BLOCK COME_FROM
|
||||
|
||||
return_if_stmt ::= ret_expr RETURN_END_IF come_from_pop
|
||||
|
||||
iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK come_from_pop
|
||||
iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE come_from_pop
|
||||
"""
|
||||
|
||||
def p_comp26(self, args):
|
||||
@@ -130,11 +150,6 @@ class Python26Parser(Python2Parser):
|
||||
except_suite ::= c_stmts_opt jmp_abs new_block
|
||||
'''
|
||||
|
||||
def p_jump26(self, args):
|
||||
"""
|
||||
jmp_false ::= JUMP_IF_FALSE
|
||||
jmp_true ::= JUMP_IF_TRUE
|
||||
"""
|
||||
|
||||
|
||||
class Python26ParserSingle(Python2Parser, PythonParserSingle):
|
||||
|
@@ -10,6 +10,11 @@ other versions of Python. Also, we save token information for later
|
||||
use in deparsing.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from uncompyle6 import PYTHON3
|
||||
if PYTHON3:
|
||||
intern = sys.intern
|
||||
|
||||
from xdis.bytecode import findlinestarts
|
||||
import uncompyle6.scanners.scanner2 as scan
|
||||
|
||||
@@ -217,6 +222,11 @@ class Scanner26(scan.Scanner2):
|
||||
if target > offset and self.code[target] == self.opc.RETURN_VALUE:
|
||||
# Python 2.5 sometimes has this
|
||||
op_name = 'JUMP_RETURN'
|
||||
# FIXME: this is a hack to catch stuff like:
|
||||
# if x: continue
|
||||
# the "continue" is not on a new line.
|
||||
if tokens[-1].type == 'JUMP_BACK':
|
||||
tokens[-1].type = intern('CONTINUE')
|
||||
|
||||
elif op in self.opc.hasjabs:
|
||||
pattr = repr(oparg)
|
||||
@@ -252,6 +262,11 @@ class Scanner26(scan.Scanner2):
|
||||
op_name = 'CONTINUE'
|
||||
else:
|
||||
op_name = 'JUMP_BACK'
|
||||
# FIXME: this is a hack to catch stuff like:
|
||||
# if x: continue
|
||||
# the "continue" is not on a new line.
|
||||
if tokens[-1].type == 'JUMP_BACK':
|
||||
tokens[-1].type = intern('CONTINUE')
|
||||
|
||||
elif op == self.opc.LOAD_GLOBAL:
|
||||
if offset in self.load_asserts:
|
||||
|
@@ -849,8 +849,14 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
self.println()
|
||||
self.prune() # stop recursing
|
||||
|
||||
def n_ifelsestmt(self, node, preprocess=0):
|
||||
n = node[3][0]
|
||||
def n_ifelsestmt(self, node, preprocess=False):
|
||||
if node[2].type.startswith('else_suite'):
|
||||
else_suite = node[2]
|
||||
elif node[3].type.startswith('else_suite'):
|
||||
else_suite = node[3]
|
||||
|
||||
n = else_suite[0]
|
||||
|
||||
if len(n) == 1 == len(n[0]) and n[0] == '_stmts':
|
||||
n = n[0][0][0]
|
||||
elif n[0].type in ('lastc_stmt', 'lastl_stmt'):
|
||||
@@ -868,7 +874,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
n.type = 'elifelsestmtr'
|
||||
elif n.type in ('ifelsestmt', 'ifelsestmtc', 'ifelsestmtl'):
|
||||
node.type = 'ifelifstmt'
|
||||
self.n_ifelsestmt(n, preprocess=1)
|
||||
self.n_ifelsestmt(n, preprocess=True)
|
||||
if n == 'ifelifstmt':
|
||||
n.type = 'elifelifstmt'
|
||||
elif n.type in ('ifelsestmt', 'ifelsestmtc', 'ifelsestmtl'):
|
||||
|
Reference in New Issue
Block a user