diff --git a/test/bytecode_2.6/03_weird.pyc b/test/bytecode_2.6/03_weird.pyc deleted file mode 100644 index f80262b8..00000000 Binary files a/test/bytecode_2.6/03_weird.pyc and /dev/null differ diff --git a/test/bytecode_2.6/03_weird26.pyc b/test/bytecode_2.6/03_weird26.pyc new file mode 100644 index 00000000..b59367d3 Binary files /dev/null and b/test/bytecode_2.6/03_weird26.pyc differ diff --git a/test/simple_source/bug26/03_weird.py b/test/simple_source/bug26/03_weird26.py similarity index 61% rename from test/simple_source/bug26/03_weird.py rename to test/simple_source/bug26/03_weird26.py index 989370ae..63e1dcc8 100644 --- a/test/simple_source/bug26/03_weird.py +++ b/test/simple_source/bug26/03_weird26.py @@ -6,5 +6,7 @@ [ x for x in range(10) if x % 2 if x % 3 ] list(x for x in range(10) if x % 2 if x % 3) -# FIXME -# (5 if 1 else max(5, 2)) +# expresion which evaluates True unconditionally, +# but leave dead code or junk around that we have to match on. +# Tests "conditional_true" rule +(5 if 1 else max(5, 2)) diff --git a/test/stdlib/runtests.sh b/test/stdlib/runtests.sh index a90bb2b1..b0f9fc80 100755 --- a/test/stdlib/runtests.sh +++ b/test/stdlib/runtests.sh @@ -63,7 +63,6 @@ case $PYVERSION in [test_ftplib.py]=1 # Control flow? [test_funcattrs.py]=1 # Control flow? [test_future4.py]=1 # Possible additional rule for future mechanism? - [test_grammar.py]=1 # Syntax error -- look at [test_grp.py]=1 # Long test - might work Control flow? [test_pwd.py]=1 # Long test - might work? Control flow? [test_queue.py]=1 # Control flow? diff --git a/uncompyle6/parsers/parse26.py b/uncompyle6/parsers/parse26.py index c5b7c35f..e0c368a4 100644 --- a/uncompyle6/parsers/parse26.py +++ b/uncompyle6/parsers/parse26.py @@ -44,7 +44,7 @@ class Python26Parser(Python2Parser): _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP except_suite ::= c_stmts_opt JUMP_FORWARD come_from_pop - except_suite ::= c_stmts_opt JUMP_FORWARD POP_TOP + except_suite ::= c_stmts_opt jf_pop except_suite ::= c_stmts_opt jmp_abs come_from_pop # This is what happens after a jump where @@ -68,6 +68,7 @@ class Python26Parser(Python2Parser): jmp_false ::= JUMP_IF_FALSE POP_TOP jb_pop ::= JUMP_BACK POP_TOP + jf_pop ::= JUMP_FORWARD POP_TOP jb_cont ::= JUMP_BACK jb_cont ::= CONTINUE @@ -266,6 +267,21 @@ class Python26Parser(Python2Parser): stmt ::= conditional_lambda conditional_lambda ::= expr jmp_false_then expr return_if_lambda return_stmt_lambda LAMBDA_MARKER + + # conditional_true are for conditions which always evaluate true + # There is dead or non-optional remnants of the condition code though, + # and we use that to match on to reconstruct the source more accurately + expr ::= conditional_true + conditional_true ::= expr jf_pop expr COME_FROM + + # This comes from + # 0 or max(5, 3) if 0 else 3 + # where there seems to be an additional COME_FROM at the + # end. Not sure if this is appropriately named or + # is the best way to handle + expr ::= conditional_false + conditional_false ::= conditional COME_FROM + """ def add_custom_rules(self, tokens, customize): @@ -299,7 +315,7 @@ class Python26Parser(Python2Parser): elif rule == ( 'list_for', ('expr', '_for', 'store', 'list_iter', - 'JUMP_ABSOLUTE', 'come_froms', 'POP_TOP', 'JUMP_BACK', 'POP_TOP')): + 'JUMP_ABSOLUTE', 'come_froms', 'POP_TOP', 'jb_pop')): # The JUMP_ABSOLUTE has to be to the last POP_TOP or this is invalid ja_attr = ast[4].attr return tokens[last].offset != ja_attr diff --git a/uncompyle6/parsers/parse27.py b/uncompyle6/parsers/parse27.py index c801336d..ce0b7de4 100644 --- a/uncompyle6/parsers/parse27.py +++ b/uncompyle6/parsers/parse27.py @@ -84,9 +84,13 @@ class Python27Parser(Python2Parser): compare_chained2 COME_FROM compare_chained2 ::= expr COMPARE_OP RETURN_VALUE - expr ::= conditionalTrue - conditionalTrue ::= expr JUMP_FORWARD expr COME_FROM - conditional ::= expr jmp_false expr JUMP_FORWARD expr COME_FROM + # conditional_true are for conditions which always evaluate true + # There is dead or non-optional remnants of the condition code though, + # and we use that to match on to reconstruct the source more accurately + expr ::= conditional_true + conditional_true ::= expr JUMP_FORWARD expr COME_FROM + + conditional ::= expr jmp_false expr JUMP_FORWARD expr COME_FROM """ def p_stmt27(self, args): diff --git a/uncompyle6/semantics/consts.py b/uncompyle6/semantics/consts.py index 1521a905..1fe26b1b 100644 --- a/uncompyle6/semantics/consts.py +++ b/uncompyle6/semantics/consts.py @@ -192,7 +192,7 @@ TABLE_DIRECT = { 'or': ( '%c or %c', 0, 2 ), 'ret_or': ( '%c or %c', 0, 2 ), 'conditional': ( '%p if %p else %p', (2, 27), (0, 27), (4, 27) ), - 'conditionalTrue': ( '%p if 1 else %p', (0, 27), (2, 27) ), + 'conditional_true': ( '%p if 1 else %p', (0, 27), (2, 27) ), 'ret_cond': ( '%p if %p else %p', (2, 27), (0, 27), (-1, 27) ), 'conditionalnot': ( '%p if not %p else %p', (2, 27), (0, 22), (4, 27) ), 'ret_cond_not': ( '%p if not %p else %p', (2, 27), (0, 22), (-1, 27) ),