diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-02-01 22:48:12 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-02-01 22:48:12 (GMT) |
commit | 3faa52ecc4aeb30f8913b4dd105184f6f7bc733d (patch) | |
tree | d4c6c78e934c98ef15aaf79fae249063b5a41a1b /Python | |
parent | 1bbc04831071891c5bbeb53a2c1defbbf83245d9 (diff) | |
download | cpython-3faa52ecc4aeb30f8913b4dd105184f6f7bc733d.zip cpython-3faa52ecc4aeb30f8913b4dd105184f6f7bc733d.tar.gz cpython-3faa52ecc4aeb30f8913b4dd105184f6f7bc733d.tar.bz2 |
Allow 'continue' inside 'try' clause
SF patch 102989 by Thomas Wouters
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 28 | ||||
-rw-r--r-- | Python/compile.c | 21 |
2 files changed, 37 insertions, 12 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 8eaa8bd..264ba30 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -322,7 +322,8 @@ enum why_code { WHY_EXCEPTION, /* Exception occurred */ WHY_RERAISE, /* Exception re-raised by 'finally' */ WHY_RETURN, /* 'return' statement */ - WHY_BREAK /* 'break' statement */ + WHY_BREAK, /* 'break' statement */ + WHY_CONTINUE, /* 'continue' statement */ }; static enum why_code do_raise(PyObject *, PyObject *, PyObject *); @@ -1357,6 +1358,11 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, case BREAK_LOOP: why = WHY_BREAK; break; + + case CONTINUE_LOOP: + retval = PyInt_FromLong(oparg); + why = WHY_CONTINUE; + break; case RAISE_VARARGS: u = v = w = NULL; @@ -1419,7 +1425,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, v = POP(); if (PyInt_Check(v)) { why = (enum why_code) PyInt_AsLong(v); - if (why == WHY_RETURN) + if (why == WHY_RETURN || + why == CONTINUE_LOOP) retval = POP(); } else if (PyString_Check(v) || PyClass_Check(v)) { @@ -1834,7 +1841,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, case SETUP_EXCEPT: case SETUP_FINALLY: PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, - STACK_LEVEL()); + STACK_LEVEL()); continue; case SET_LINENO: @@ -2110,6 +2117,18 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, while (why != WHY_NOT && f->f_iblock > 0) { PyTryBlock *b = PyFrame_BlockPop(f); + + if (b->b_type == SETUP_LOOP && why == WHY_CONTINUE) { + /* For a continue inside a try block, + don't pop the block for the loop. */ + PyFrame_BlockSetup(f, b->b_type, b->b_level, + b->b_handler); + why = WHY_NOT; + JUMPTO(PyInt_AS_LONG(retval)); + Py_DECREF(retval); + break; + } + while (STACK_LEVEL() > b->b_level) { v = POP(); Py_XDECREF(v); @@ -2145,7 +2164,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, PUSH(exc); } else { - if (why == WHY_RETURN) + if (why == WHY_RETURN || + why == CONTINUE_LOOP) PUSH(retval); v = PyInt_FromLong((long)why); PUSH(v); diff --git a/Python/compile.c b/Python/compile.c index 68f9e7f..3dae4c8 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -5,7 +5,7 @@ XXX add __doc__ attribute == co_doc to code object attributes? XXX (it's currently the first item of the co_const tuple) XXX Generate simple jump for break/return outside 'try...finally' - XXX Allow 'continue' inside try-finally + XXX Allow 'continue' inside finally clause of try-finally XXX New opcode for loading the initial index for a for loop XXX other JAR tricks? */ @@ -3247,19 +3247,24 @@ com_continue_stmt(struct compiling *c, node *n) } else { int j; - for (j = 0; j <= i; ++j) { + for (j = i-1; j >= 0; --j) { if (c->c_block[j] == SETUP_LOOP) break; } - if (j < i+1) { + if (j >= 0) { /* there is a loop, but something interferes */ - for (++j; j <= i; ++j) { - if (c->c_block[i] == SETUP_EXCEPT - || c->c_block[i] == SETUP_FINALLY) { - com_error(c, PyExc_SyntaxError, - "'continue' not supported inside 'try' clause"); + for (; i > j; --i) { + if (c->c_block[i] == SETUP_EXCEPT || + c->c_block[i] == SETUP_FINALLY) { + com_addoparg(c, CONTINUE_LOOP, + c->c_begin); return; } + if (c->c_block[i] == END_FINALLY) { + com_error(c, PyExc_SyntaxError, + "'continue' not supported inside 'finally' clause"); + return; + } } } com_error(c, PyExc_SyntaxError, |