Allow 'continue' inside 'try' clause
SF patch 102989 by Thomas Wouters
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 @@
 		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 @@
 		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 @@
 			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 @@
 		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 @@
 
 		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 @@
 					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 @@
 	}
 	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,