diff --git a/test/bytecode_2.3/08_while1_if_continue.pyc b/test/bytecode_2.3/08_while1_if_continue.pyc new file mode 100644 index 00000000..a2d50a56 Binary files /dev/null and b/test/bytecode_2.3/08_while1_if_continue.pyc differ diff --git a/test/bytecode_2.4/08_while1_if_continue.pyc b/test/bytecode_2.4/08_while1_if_continue.pyc index 96166f79..9cf18747 100644 Binary files a/test/bytecode_2.4/08_while1_if_continue.pyc and b/test/bytecode_2.4/08_while1_if_continue.pyc differ diff --git a/test/bytecode_2.6/08_while1_if_continue.pyc b/test/bytecode_2.6/08_while1_if_continue.pyc index 5c87045d..7d47699d 100644 Binary files a/test/bytecode_2.6/08_while1_if_continue.pyc and b/test/bytecode_2.6/08_while1_if_continue.pyc differ diff --git a/test/bytecode_2.7/08_while1_if_continue.pyc b/test/bytecode_2.7/08_while1_if_continue.pyc index eb9a7df4..03aa5493 100644 Binary files a/test/bytecode_2.7/08_while1_if_continue.pyc and b/test/bytecode_2.7/08_while1_if_continue.pyc differ diff --git a/test/simple_source/looping/08_while1_if_continue.py b/test/simple_source/looping/08_while1_if_continue.py index 3d72a7e8..eba6ead7 100644 --- a/test/simple_source/looping/08_while1_if_continue.py +++ b/test/simple_source/looping/08_while1_if_continue.py @@ -7,3 +7,13 @@ def readline (self): continue return + +# From 2.4.6 sre.py +# Bug in 2.4 and 2.3 was parsing the nested "while 1" with a "break" in it +def _parse(a, b, source, state): + while 1: + if b: + while 1: + break + else: + raise diff --git a/uncompyle6/parsers/parse23.py b/uncompyle6/parsers/parse23.py index 166de860..a9f3b5c2 100644 --- a/uncompyle6/parsers/parse23.py +++ b/uncompyle6/parsers/parse23.py @@ -32,8 +32,19 @@ class Python23Parser(Python24Parser): while1stmt ::= _while1test l_stmts_opt JUMP_BACK POP_TOP POP_BLOCK COME_FROM - while1stmt ::= _while1test l_stmts_opt JUMP_BACK - COME_FROM POP_TOP POP_BLOCK COME_FROM + while1stmt ::= _while1test l_stmts_opt JUMP_BACK COME_FROM + POP_TOP POP_BLOCK COME_FROM + + # Python 2.3 + # The following has no "JUMP_BACK" after l_stmts because + # l_stmts ends in a "break", "return", or "continue" + while1stmt ::= _while1test l_stmts + POP_TOP POP_BLOCK + + # The following has a "COME_FROM" at the end which comes from + # a "break" inside "l_stmts". + while1stmt ::= _while1test l_stmts COME_FROM JUMP_BACK + POP_TOP POP_BLOCK COME_FROM list_comp ::= BUILD_LIST_0 DUP_TOP LOAD_ATTR store list_iter del_stmt list_for ::= expr for_iter store list_iter JUMP_BACK come_froms POP_TOP JUMP_BACK diff --git a/uncompyle6/parsers/parse24.py b/uncompyle6/parsers/parse24.py index b758c52a..411daaad 100644 --- a/uncompyle6/parsers/parse24.py +++ b/uncompyle6/parsers/parse24.py @@ -38,8 +38,21 @@ class Python24Parser(Python25Parser): _ifstmts_jump24 ::= c_stmts_opt JUMP_FORWARD POP_TOP # Python 2.5+ omits POP_TOP POP_BLOCK - while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_TOP POP_BLOCK COME_FROM - while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_TOP POP_BLOCK + while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK + POP_TOP POP_BLOCK COME_FROM + while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK + POP_TOP POP_BLOCK + + # Python 2.4 + # The following has no "JUMP_BACK" after l_stmts because + # l_stmts ends in a "break", "return", or "continue" + while1stmt ::= SETUP_LOOP l_stmts + POP_TOP POP_BLOCK + + # The following has a "COME_FROM" at the end which comes from + # a "break" inside "l_stmts". + while1stmt ::= SETUP_LOOP l_stmts COME_FROM JUMP_BACK + POP_TOP POP_BLOCK COME_FROM # Python 2.5+: # call_stmt ::= expr POP_TOP