diff --git a/ASTree.cpp b/ASTree.cpp index 10f507e..ebd8e81 100644 --- a/ASTree.cpp +++ b/ASTree.cpp @@ -897,7 +897,8 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) case Pyc::INSTRUMENTED_FOR_ITER_A: { PycRef iter = stack.top(); // Iterable - stack.pop(); + if (mod->verCompare(3,12) < 0) + stack.pop(); /* Pop it? Don't pop it? */ int end; @@ -1678,11 +1679,34 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) case Pyc::POP_EXCEPT: /* Do nothing. */ break; - case Pyc::POP_TOP: case Pyc::END_FOR: + { + stack.pop(); + + if ((opcode == Pyc::END_FOR) && (mod->majorVer() == 3) && (mod->minorVer() == 12)) { + // one additional pop for python 3.12 + stack.pop(); + } + + // end for loop here + if (curblock->blktype() == ASTBlock::BLK_FOR) { + PycRef prev = blocks.top(); + blocks.pop(); + + curblock = blocks.top(); + curblock->append(prev.cast()); + } + else { + fprintf(stderr, "Wrong block type %i for END_FOR\n", curblock->blktype()); + break; + } + } + break; + case Pyc::POP_TOP: { PycRef value = stack.top(); stack.pop(); + if (!curblock->inited()) { if (curblock->blktype() == ASTBlock::BLK_WITH) { curblock.cast()->setExpr(value); diff --git a/FastStack.h b/FastStack.h index 45f8ed5..3f9c2c8 100644 --- a/FastStack.h +++ b/FastStack.h @@ -30,14 +30,23 @@ public: { if (m_ptr > -1) m_stack[m_ptr--] = nullptr; + else { + #ifdef BLOCK_DEBUG + fprintf(stderr, "pop from empty stack\n"); + #endif + } } PycRef top() const { if (m_ptr > -1) return m_stack[m_ptr]; - else + else { + #ifdef BLOCK_DEBUG + fprintf(stderr, "top on empty stack\n"); + #endif return nullptr; + } } bool empty() const diff --git a/tests/compiled/test_loops3.3.12.pyc b/tests/compiled/test_loops3.3.12.pyc new file mode 100644 index 0000000..efb575c Binary files /dev/null and b/tests/compiled/test_loops3.3.12.pyc differ diff --git a/tests/input/test_loops3.py b/tests/input/test_loops3.py new file mode 100644 index 0000000..5f2c036 --- /dev/null +++ b/tests/input/test_loops3.py @@ -0,0 +1,34 @@ +def loop1(): + iterable = [1, 2, 3] + for item in iterable: + pass + +loop1() + +def loop2(): + for i in range(2): + print(i) + +loop2() + +def loop3(): + def loop(): + x = (1,2,3) + l = [] + for i in x: + l.append(i) + return l + + return loop() + +loop3() + +def loop4(): + for i in range(3): + for j in range(2): + print(i*j) + +loop4() + +for j in [1,2,3][::-1]: + print("hi", j) diff --git a/tests/tokenized/test_loops3.txt b/tests/tokenized/test_loops3.txt new file mode 100644 index 0000000..62ee5d4 --- /dev/null +++ b/tests/tokenized/test_loops3.txt @@ -0,0 +1,46 @@ +def loop1 ( ) : + +iterable = [ 1 , 2 , 3 ] +for item in iterable : + +pass + + +loop1 ( ) +def loop2 ( ) : + +for i in range ( 2 ) : + +print ( i ) + + +loop2 ( ) +def loop3 ( ) : + +def loop ( ) : + +x = ( 1 , 2 , 3 ) +l = [ ] +for i in x : + +l . append ( i ) + +return l + +return loop ( ) + +loop3 ( ) +def loop4 ( ) : + +for i in range ( 3 ) : + +for j in range ( 2 ) : + +print ( i * j ) + + + +loop4 ( ) +for j in [ 1 , 2 , 3 ] [ : : - 1 ] : + +print ( 'hi' , j )