diff --git a/uncompyle6/parsers/parse37.py b/uncompyle6/parsers/parse37.py index 9cf7c738..c0309c1e 100644 --- a/uncompyle6/parsers/parse37.py +++ b/uncompyle6/parsers/parse37.py @@ -960,6 +960,7 @@ class Python37Parser(Python37BaseParser): and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM and ::= expr JUMP_IF_FALSE expr COME_FROM + and ::= expr jmp_false expr ## FIXME: Is the below needed or is it covered above?? and ::= expr jmp_false expr COME_FROM diff --git a/uncompyle6/parsers/parse37base.py b/uncompyle6/parsers/parse37base.py index 48856279..c6f047d8 100644 --- a/uncompyle6/parsers/parse37base.py +++ b/uncompyle6/parsers/parse37base.py @@ -938,6 +938,7 @@ class Python37BaseParser(PythonParser): self.check_reduce["ifstmt"] = "AST" self.check_reduce["ifstmtl"] = "AST" self.check_reduce["annotate_tuple"] = "noAST" + self.check_reduce["or"] = "tokens" # FIXME: remove parser errors caused by the below # self.check_reduce['while1elsestmt'] = 'noAST' @@ -1043,10 +1044,13 @@ class Python37BaseParser(PythonParser): return jmp_target != jmp2_target elif rule == ("and", ("expr", "jmp_false", "expr")): if tokens[last] == "POP_JUMP_IF_FALSE": - # Ok if jump it doesn't jump to last instruction + # Ok if jump_target doesn't jump to last instruction return jmp_target != tokens[last].attr elif tokens[last] == "JUMP_IF_TRUE_OR_POP": - # Ok if jump it does jump right after last instruction + # Ok if jump_target jumps to a COME_FROM after + # the last instruction or jumps right after last instruction + if last + 1 < n and tokens[last + 1] == "COME_FROM": + return jmp_target != tokens[last + 1].off2int() return jmp_target + 2 != tokens[last].attr elif rule == ("and", ("expr", "jmp_false", "expr", "COME_FROM")): return ast[-1].attr != jmp_offset @@ -1060,6 +1064,12 @@ class Python37BaseParser(PythonParser): return True elif lhs == "annotate_tuple": return not isinstance(tokens[first].attr, tuple) + elif lhs == "or": + # FIXME: This is a cheap test. Should we do something with an AST like we + # do with "and"? + # "or"s with constants like this will have "COME_FROM" at the end + return tokens[last] in ("LOAD_ASSERT", "LOAD_STR", "LOAD_CODE", "LOAD_CONST", + "RAISE_VARARGS_1") elif lhs == "while1elsestmt": if last == n: