diff --git a/test/simple_source/bug34/08_while_if.py b/test/simple_source/bug34/08_while_if.py new file mode 100644 index 00000000..c68da712 --- /dev/null +++ b/test/simple_source/bug34/08_while_if.py @@ -0,0 +1,34 @@ +# Testing "while 1" versus "while" handling with if/elif/else's + +def while_test(a, b, c): + while a != 2: + if b: + a += 1 + elif c: + c = 0 + else: + break + return a, b, c + + +def while1_test(a, b, c): + while 1: + if a != 2: + if b: + a = 3 + b = 0 + elif c: + c = 0 + else: + a += b + c + break + return a, b, c + + +assert while_test(2, 0, 0) == (2, 0, 0), "no while loops" +assert while_test(0, 1, 0) == (2, 1, 0), "two while loops of b branch" +assert while_test(0, 0, 0) == (0, 0, 0), "0 while loops, else branch" + +# FIXME: put this in a timer, and try with a=2 +assert while1_test(4, 1, 1) == (3, 0, 0), "three while1 loops" +assert while1_test(4, 0, 0) == (4, 0, 0), " one while1 loop" diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 34a04bf7..2f3d6dff 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -152,11 +152,8 @@ class Python3Parser(PythonParser): _ifstmts_jump ::= return_if_stmts _ifstmts_jump ::= c_stmts_opt COME_FROM - iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE - + iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK - iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK COME_FROM_LOOP - iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK POP_BLOCK # These are used to keep parse tree indices the same jump_forward_else ::= JUMP_FORWARD ELSE @@ -182,6 +179,8 @@ class Python3Parser(PythonParser): ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel ifelsestmtl ::= testexpr c_stmts_opt cf_jump_back else_suitel + ifelsestmtl ::= testexpr c_stmts_opt continue else_suitel + cf_jump_back ::= COME_FROM JUMP_BACK @@ -348,6 +347,8 @@ class Python3Parser(PythonParser): def p_loop_stmt3(self, args): """ + stmt ::= whileelsestmt2 + for ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK COME_FROM_LOOP @@ -363,6 +364,8 @@ class Python3Parser(PythonParser): whilestmt ::= SETUP_LOOP testexpr l_stmts_opt COME_FROM JUMP_BACK POP_BLOCK COME_FROM_LOOP + whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK JUMP_BACK + COME_FROM_LOOP whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM_LOOP @@ -375,6 +378,9 @@ class Python3Parser(PythonParser): whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK else_suitel COME_FROM_LOOP + whileelsestmt2 ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK + else_suitel JUMP_BACK COME_FROM_LOOP + whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM_LOOP diff --git a/uncompyle6/semantics/consts.py b/uncompyle6/semantics/consts.py index cae5c952..214b4e8f 100644 --- a/uncompyle6/semantics/consts.py +++ b/uncompyle6/semantics/consts.py @@ -377,6 +377,7 @@ TABLE_DIRECT = { 'while1stmt': ( '%|while 1:\n%+%c%-\n\n', 1 ), 'while1elsestmt': ( '%|while 1:\n%+%c%-%|else:\n%+%c%-\n\n', 1, -2 ), 'whileelsestmt': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-\n\n', 1, 2, -2 ), + 'whileelsestmt2': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-\n\n', 1, 2, -3 ), 'whileelselaststmt': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-', 1, 2, -2 ), # Note: Python 3.8+ changes this