diff --git a/test/bytecode_2.6/09_whiletrue_bug.pyc b/test/bytecode_2.6/09_whiletrue_bug.pyc index d085eac1..a5cd8c59 100644 Binary files a/test/bytecode_2.6/09_whiletrue_bug.pyc and b/test/bytecode_2.6/09_whiletrue_bug.pyc differ diff --git a/test/bytecode_2.7/09_whiletrue_bug.pyc b/test/bytecode_2.7/09_whiletrue_bug.pyc new file mode 100644 index 00000000..10a6b1c4 Binary files /dev/null and b/test/bytecode_2.7/09_whiletrue_bug.pyc differ diff --git a/test/simple_source/stmts/09_whiletrue_bug.py b/test/simple_source/stmts/09_whiletrue_bug.py index 159c10cf..4d04a16e 100644 --- a/test/simple_source/stmts/09_whiletrue_bug.py +++ b/test/simple_source/stmts/09_whiletrue_bug.py @@ -1,9 +1,12 @@ -if args == ['-']: +if __file__ == ['-']: while True: try: - compile(filename, doraise=True) + compile(__file__, doraise=True) except RuntimeError: rv = 1 else: rv = 1 print(rv) + + +while 1:pass diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index 0272c57e..2c5c66d8 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -72,7 +72,7 @@ class PythonParser(GenericASTBuilder): print("Instruction context:") for i in range(start, finish): indent = ' ' if i != index else '-> ' - print("%s%s" % (indent, instructions[i].format())) + print("%s%s" % (indent, instructions[i])) raise ParserError(err_token, err_token.offset) def typestring(self, token): diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py index 2a85376c..609d88ed 100644 --- a/uncompyle6/parsers/parse2.py +++ b/uncompyle6/parsers/parse2.py @@ -40,6 +40,11 @@ class Python2Parser(PythonParser): print_nl ::= PRINT_NEWLINE ''' + def p_stmt2(self, args): + """ + while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM + """ + def p_print_to(self, args): ''' stmt ::= print_to diff --git a/uncompyle6/parsers/parse26.py b/uncompyle6/parsers/parse26.py index 25437282..7ccabe46 100644 --- a/uncompyle6/parsers/parse26.py +++ b/uncompyle6/parsers/parse26.py @@ -157,6 +157,8 @@ class Python26Parser(Python2Parser): iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK come_from_pop iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE come_from_pop + while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK COME_FROM + # Common with 2.7 while1stmt ::= SETUP_LOOP return_stmts bp_come_from while1stmt ::= SETUP_LOOP return_stmts COME_FROM diff --git a/uncompyle6/parsers/parse27.py b/uncompyle6/parsers/parse27.py index 0fd6f4df..a2442a7a 100644 --- a/uncompyle6/parsers/parse27.py +++ b/uncompyle6/parsers/parse27.py @@ -61,6 +61,8 @@ class Python27Parser(Python2Parser): POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY + while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM + # Common with 2.6 while1stmt ::= SETUP_LOOP return_stmts bp_come_from while1stmt ::= SETUP_LOOP return_stmts COME_FROM diff --git a/uncompyle6/scanners/scanner2.py b/uncompyle6/scanners/scanner2.py index 8090abd8..0d7c7645 100755 --- a/uncompyle6/scanners/scanner2.py +++ b/uncompyle6/scanners/scanner2.py @@ -218,8 +218,19 @@ class Scanner2(scan.Scanner): # in arbitrary value 0. customize[opname] = 0 elif op == self.opc.JUMP_ABSOLUTE: + # Further classify JUMP_ABSOLUTE into backward jumps + # which are used in loops, and "CONTINUE" jumps which + # may appear in a "continue" statement. The loop-type + # and continue-type jumps will help us classify loop + # boundaries The continue-type jumps help us get + # "continue" statements with would otherwise be turned + # into a "pass" statement because JUMPs are sometimes + # ignored in rules as just boundary overhead. In + # comprehensions we might sometimes classify JUMP_BACK + # as CONTINUE, but that's okay since we add a grammar + # rule for that. target = self.get_target(offset) - if target < offset: + if target <= offset: if (offset in self.stmts and self.code[offset+3] not in (self.opc.END_FINALLY, self.opc.POP_BLOCK) diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 1f5476cb..76344adc 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -259,7 +259,7 @@ class Scanner3(scan.Scanner): argval = (before_args, after_args) opname = '%s_%d+%d' % (opname, before_args, after_args) elif op == self.opc.JUMP_ABSOLUTE: - # Further classifhy JUMP_ABSOLUTE into backward jumps + # Further classify JUMP_ABSOLUTE into backward jumps # which are used in loops, and "CONTINUE" jumps which # may appear in a "continue" statement. The loop-type # and continue-type jumps will help us classify loop diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index a09e22ed..7703739b 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -431,7 +431,7 @@ class ParserError(python_parser.ParserError): def __str__(self): lines = ['--- This code section failed: ---'] - lines.extend([i.format() for i in self.tokens]) + lines.extend([str(i) for i in self.tokens]) lines.extend( ['', str(self.error)] ) return '\n'.join(lines)