From d6429e84dd00c891a49261902c84bc6380794e42 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 30 Mar 2024 23:05:39 -0400 Subject: [PATCH] 3.7 ifstmt with "and" bool --- decompyle3/parsers/p37/full.py | 1 + decompyle3/parsers/reduce_check/ifstmt.py | 11 ++++++++--- decompyle3/scanner.py | 6 ++++++ decompyle3/semantics/consts.py | 4 +++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/decompyle3/parsers/p37/full.py b/decompyle3/parsers/p37/full.py index 0a9d31ff..93cae193 100644 --- a/decompyle3/parsers/p37/full.py +++ b/decompyle3/parsers/p37/full.py @@ -579,6 +579,7 @@ def p_grammar(self, args): # empty they have to be reasonable, e.g. testexpr has to # jump to one of the COME_FROMS ifstmt ::= testexpr stmts _come_froms + ifstmt ::= bool_op stmts _come_froms ifstmt ::= testexpr ifstmts_jump _come_froms stmt ::= ifstmt_bool diff --git a/decompyle3/parsers/reduce_check/ifstmt.py b/decompyle3/parsers/reduce_check/ifstmt.py index 6d9fe39e..e228274c 100644 --- a/decompyle3/parsers/reduce_check/ifstmt.py +++ b/decompyle3/parsers/reduce_check/ifstmt.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020, 2022-2023 Rocky Bernstein +# Copyright (c) 2020, 2022-2024 Rocky Bernstein # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -27,11 +27,14 @@ def ifstmt( self, lhs: str, n: int, rule, tree, tokens: list, first: int, last: int ) -> bool: - # print("XXX", first, last, rule) + # print("XXX", tokens[first].offset , tokens[last].offset, rule) # for t in range(first, last): # print(tokens[t]) # print("=" * 40) + if rule == ("ifstmt", ("bool_op", "stmts", "\\e__come_froms")): + return False + ltm1_index = last - 1 while tokens[ltm1_index] == "COME_FROM": ltm1_index -= 1 @@ -182,7 +185,7 @@ def ifstmt( pass # If there is a final COME_FROM and that test jumps to that, this is a strong - # indication that this is ok, s we'll skip jumps jumping too far test. + # indication that this is ok, so we'll skip jumps jumping too far test. if ( pop_jump_if is not None and ltm1 == "COME_FROM" @@ -221,5 +224,7 @@ def ifstmt( # been a prior reduction that doesn't include the last COME_FROM. if ltm1 == "COME_FROM": return ltm1.attr < first_offset + elif tokens[last] == "COME_FROM": + return tokens[last].attr < first_offset return False diff --git a/decompyle3/scanner.py b/decompyle3/scanner.py index 2b1fbf85..69c5edc6 100755 --- a/decompyle3/scanner.py +++ b/decompyle3/scanner.py @@ -116,6 +116,12 @@ def build_instructions(self, co): self.offset2inst_index = {} for i, inst in enumerate(self.insts): self.offset2inst_index[inst.offset] = i + offset = inst.offset + inst_size = inst.inst_size + while inst_size > 0: + self.offset2inst_index[offset] = i + offset += 2 + inst_size -= 2 return bytecode diff --git a/decompyle3/semantics/consts.py b/decompyle3/semantics/consts.py index 429dedf8..85b271dc 100644 --- a/decompyle3/semantics/consts.py +++ b/decompyle3/semantics/consts.py @@ -487,7 +487,9 @@ # "yield": ( "yield %c", 0), # "return": ( "%|return %c\n", 0), "return_if_stmt": ("return %c\n", 0), - "ifstmt": ("%|if %c:\n%+%c%-", (0, "testexpr"), (1, ("ifstmts_jump", "stmts"))), + "ifstmt": ( + "%|if %c:\n%+%c%-", (0, ("testexpr", "bool_op")), (1, ("ifstmts_jump", "stmts")) + ), "iflaststmt": ("%|if %c:\n%+%c%-", 0, 1), "iflaststmtc": ("%|if %c:\n%+%c%-", 0, 1), "testtrue": ("not %p", (0, PRECEDENCE["unary_not"])),