diff --git a/ASTree.cpp b/ASTree.cpp index 6635808e1..6c4f58302 100644 --- a/ASTree.cpp +++ b/ASTree.cpp @@ -818,6 +818,15 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) curblock = blocks.top(); curblock->append(final.cast()); isFinally = true; + } else if (curblock->blktype() == ASTBlock::BLK_CONTAINER) { + /* Turn it into an else statement. */ + if ((curblock->end() != pos || curblock.cast()->hasFinally()) + && curblock.cast()->hasExcept()) { + PycRef elseblk = new ASTBlock(ASTBlock::BLK_ELSE, curblock->end()); + elseblk->init(); + blocks.push(elseblk); + curblock = blocks.top(); + } } else if (curblock->blktype() == ASTBlock::BLK_EXCEPT) { blocks.pop(); PycRef prev = curblock; @@ -1817,6 +1826,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) curblock->append(new ASTRaise(paramList)); if ((curblock->blktype() == ASTBlock::BLK_IF + || curblock->blktype() == ASTBlock::BLK_EXCEPT || curblock->blktype() == ASTBlock::BLK_ELSE) && stack_hist.size() && (mod->verCompare(2, 6) >= 0)) { @@ -1827,6 +1837,12 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) blocks.pop(); curblock = blocks.top(); curblock->append(prev.cast()); + // sometimes JUMP ins after raise + // so we should check the end of current block + // current not in block end, skip ins + while (prev->end() > pos && !source.atEof()) { + bc_next(source, mod, opcode, operand, pos); + } } } break; @@ -1838,6 +1854,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) curblock->append(new ASTReturn(value)); if ((curblock->blktype() == ASTBlock::BLK_IF + || curblock->blktype() == ASTBlock::BLK_EXCEPT || curblock->blktype() == ASTBlock::BLK_ELSE) && stack_hist.size() && (mod->verCompare(2, 6) >= 0)) { @@ -1848,8 +1865,9 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) blocks.pop(); curblock = blocks.top(); curblock->append(prev.cast()); - - bc_next(source, mod, opcode, operand, pos); + while (prev->end() > pos && !source.atEof()) { + bc_next(source, mod, opcode, operand, pos); + } } } break; diff --git a/tests/compiled/multiple_raise.2.7.pyc b/tests/compiled/multiple_raise.2.7.pyc new file mode 100644 index 000000000..f4801deeb Binary files /dev/null and b/tests/compiled/multiple_raise.2.7.pyc differ diff --git a/tests/compiled/test_break_in_loop.2.7.pyc b/tests/compiled/test_break_in_loop.2.7.pyc new file mode 100644 index 000000000..2b6f216b3 Binary files /dev/null and b/tests/compiled/test_break_in_loop.2.7.pyc differ diff --git a/tests/compiled/test_if_return_breaks_assign.2.7.pyc b/tests/compiled/test_if_return_breaks_assign.2.7.pyc new file mode 100644 index 000000000..9ab26172a Binary files /dev/null and b/tests/compiled/test_if_return_breaks_assign.2.7.pyc differ diff --git a/tests/compiled/test_return_in_except.2.7.pyc b/tests/compiled/test_return_in_except.2.7.pyc new file mode 100644 index 000000000..f1275243e Binary files /dev/null and b/tests/compiled/test_return_in_except.2.7.pyc differ diff --git a/tests/input/multiple_raise.py b/tests/input/multiple_raise.py new file mode 100644 index 000000000..84fcd927c --- /dev/null +++ b/tests/input/multiple_raise.py @@ -0,0 +1,6 @@ +def test(): + a = 10 + if a: + raise Exception("test123") + if a: + raise Exception("test456") diff --git a/tests/input/test_break_in_loop.py b/tests/input/test_break_in_loop.py new file mode 100644 index 000000000..6e3696a78 --- /dev/null +++ b/tests/input/test_break_in_loop.py @@ -0,0 +1,70 @@ +def test0(): + a = 0 + while a < 10: + a += 1 + if a == 5: + return 10 + b = 1 + a = 1 + +def test1(): + a = 0 + while a < 10: + a += 1 + if a == 5: + return 10 + a = 1 + +# bug +# def test2(): +# a = 0 +# while a < 10: +# a += 1 +# if a == 5: +# raise Exception("123") +# a = 1 + +def test3(): + a = 0 + while a < 10: + a += 1 + if a == 5: + raise Exception("123") + b = 1 + a = 1 + +# bug +# def test4(): +# a = 0 +# while a < 10: +# a += 1 +# if a == 5: +# break +# a = 1 + +def test5(): + a = 0 + while a < 10: + a += 1 + if a == 5: + break + b = 1 + a = 1 + +# bug +# def test6(): +# a = 0 +# while a < 10: +# a += 1 +# if a == 5: +# continue +# a = 1 + +def test7(): + a = 0 + while a < 10: + a += 1 + if a == 5: + continue + b = 1 + a = 1 diff --git a/tests/input/test_if_return_breaks_assign.py b/tests/input/test_if_return_breaks_assign.py new file mode 100644 index 000000000..71df6b16f --- /dev/null +++ b/tests/input/test_if_return_breaks_assign.py @@ -0,0 +1,6 @@ +def test(): + a = 10 + if a: + return 0 + t = 114 + return t diff --git a/tests/input/test_return_in_except.py b/tests/input/test_return_in_except.py new file mode 100644 index 000000000..12624cb59 --- /dev/null +++ b/tests/input/test_return_in_except.py @@ -0,0 +1,124 @@ +def test(): + try: + a = 1 + except ValueError: + return 0 + except Exception: + c = 1 + b = 3 + +def test1(): + a = 1 + if a: + try: + a = 1 + except ValueError: + b = 2 + return 2 + except IndexError: + b = 3 + return 3 + except Exception: + b = 4 + return 4 + finally: + b = 5 + return 5 + b = 1 + else: + a = 2 + b = 3 + +def test2(): + a = 1 + if a: + try: + a = 1 + except ValueError: + b = 2 + return 2 + except IndexError: + b = 3 + return 3 + except Exception: + b = 4 + return 4 + finally: + b = 5 + return 5 + else: + a = 2 + b = 3 + + +def test3(): + a = 1 + if a: + try: + a = 1 + except ValueError: + b = 2 + except IndexError: + b = 3 + except Exception: + b = 4 + c = 1 + else: + a = 2 + b = 114 + + +# BUG +# def test4(): +# a = 1 +# if a: +# try: +# a = 1 +# except ValueError: +# b = 2 +# except IndexError: +# b = 3 +# except Exception: +# b = 4 +# else: +# a = 2 +# b = 114 + + +def test5(): + a = 1 + if a: + try: + a = 1 + except ValueError: + b = 2 + return 2 + except IndexError: + b = 3 + return 3 + except Exception: + b = 4 + return 4 + b = 1 + else: + a = 2 + b = 3 + +# BUG +# def test6(): +# a = 1 +# if a: +# try: +# a = 1 +# except ValueError: +# b = 2 +# return 2 +# except IndexError: +# b = 3 +# return 3 +# except Exception: +# b = 4 +# return 4 +# else: +# a = 2 +# b = 3 diff --git a/tests/tokenized/multiple_raise.txt b/tests/tokenized/multiple_raise.txt new file mode 100644 index 000000000..6b615b69e --- /dev/null +++ b/tests/tokenized/multiple_raise.txt @@ -0,0 +1,10 @@ +def test ( ) : + +a = 10 +if a : + +raise Exception ( 'test123' ) + +if a : + +raise Exception ( 'test456' ) diff --git a/tests/tokenized/test_break_in_loop.txt b/tests/tokenized/test_break_in_loop.txt new file mode 100644 index 000000000..8b6f3c662 --- /dev/null +++ b/tests/tokenized/test_break_in_loop.txt @@ -0,0 +1,68 @@ +def test0 ( ) : + +a = 0 +while a < 10 : + +a += 1 +if a == 5 : + +return 10 + +b = 1 + +a = 1 + +def test1 ( ) : + +a = 0 +while a < 10 : + +a += 1 +if a == 5 : + +return 10 + + +a = 1 + +def test3 ( ) : + +a = 0 +while a < 10 : + +a += 1 +if a == 5 : + +raise Exception ( '123' ) + +b = 1 + +a = 1 + +def test5 ( ) : + +a = 0 +while a < 10 : + +a += 1 +if a == 5 : + +break + +b = 1 + +a = 1 + +def test7 ( ) : + +a = 0 +while a < 10 : + +a += 1 +if a == 5 : + +continue + +b = 1 + +a = 1 diff --git a/tests/tokenized/test_if_return_breaks_assign.txt b/tests/tokenized/test_if_return_breaks_assign.txt new file mode 100644 index 000000000..e44e6f9cc --- /dev/null +++ b/tests/tokenized/test_if_return_breaks_assign.txt @@ -0,0 +1,9 @@ +def test ( ) : + +a = 10 +if a : + +return 0 + +t = 114 +return t diff --git a/tests/tokenized/test_return_in_except.txt b/tests/tokenized/test_return_in_except.txt new file mode 100644 index 000000000..ef8241818 --- /dev/null +++ b/tests/tokenized/test_return_in_except.txt @@ -0,0 +1,149 @@ +def test ( ) : + +try : + +a = 1 + +except ValueError : + +return 0 + +except Exception : + +c = 1 + +b = 3 + +def test1 ( ) : + +a = 1 +if a : + +try : + +a = 1 + +except ValueError : + +b = 2 +return 2 + +except IndexError : + +b = 3 +return 3 + +except Exception : + +b = 4 +return 4 + +finally : + +b = 5 +return 5 + +b = 1 + +else : + +a = 2 + +b = 3 + +def test2 ( ) : + +a = 1 +if a : + +try : + +a = 1 + +except ValueError : + +b = 2 +return 2 + +except IndexError : + +b = 3 +return 3 + +except Exception : + +b = 4 +return 4 + +finally : + +b = 5 +return 5 + + +else : + +a = 2 + +b = 3 + +def test3 ( ) : + +a = 1 +if a : + +try : + +a = 1 + +except ValueError : + +b = 2 + +except IndexError : + +b = 3 + +except Exception : + +b = 4 + +c = 1 + +else : + +a = 2 + +b = 114 + +def test5 ( ) : + +a = 1 +if a : + +try : + +a = 1 + +except ValueError : + +b = 2 +return 2 + +except IndexError : + +b = 3 +return 3 + +except Exception : + +b = 4 +return 4 + +b = 1 + +else : + +a = 2 + +b = 3