Skip to content

Commit 6864344

Browse files
committed
Fixed #5535 (Add 'continue' to lua) patch from onestone
1 parent da6b62e commit 6864344

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

src/llex.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
/* ORDER RESERVED */
3737
const char *const luaX_tokens [] = {
38-
"and", "break", "do", "else", "elseif",
38+
"and", "break", "continue", "do", "else", "elseif",
3939
"end", "false", "for", "function", "if",
4040
"in", "local", "nil", "not", "or", "repeat",
4141
"return", "then", "true", "until", "while",

src/llex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*/
2424
enum RESERVED {
2525
/* terminal symbols denoted by reserved words */
26-
TK_AND = FIRST_RESERVED, TK_BREAK,
26+
TK_AND = FIRST_RESERVED, TK_BREAK, TK_CONTINUE,
2727
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
2828
TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
2929
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,

src/lparser.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
typedef struct BlockCnt {
4141
struct BlockCnt *previous; /* chain */
4242
int breaklist; /* list of jumps out of this loop */
43+
int continuelist; /* list of jumps to the loop's test */
4344
lu_byte nactvar; /* # active locals outside the breakable structure */
4445
lu_byte upval; /* true if some variable in the block is an upvalue */
4546
lu_byte isbreakable; /* true if `block' is a loop */
@@ -284,6 +285,7 @@ static void enterlevel (LexState *ls) {
284285

285286
static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
286287
bl->breaklist = NO_JUMP;
288+
bl->continuelist = NO_JUMP;
287289
bl->isbreakable = isbreakable;
288290
bl->nactvar = fs->nactvar;
289291
bl->upval = 0;
@@ -971,6 +973,21 @@ static int cond (LexState *ls) {
971973
return v.f;
972974
}
973975

976+
977+
static void continuestat (LexState *ls) {
978+
FuncState *fs = ls->fs;
979+
BlockCnt *bl = fs->bl;
980+
int upval = 0;
981+
while (bl && !bl->isbreakable) {
982+
upval |= bl->upval;
983+
bl = bl->previous;
984+
}
985+
if (!bl)
986+
luaX_syntaxerror(ls, "no loop to continue");
987+
if (upval)
988+
luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
989+
luaK_concat(fs, &bl->continuelist, luaK_jump(fs));
990+
}
974991

975992
static void breakstat (LexState *ls) {
976993
FuncState *fs = ls->fs;
@@ -1001,6 +1018,7 @@ static void whilestat (LexState *ls, int line) {
10011018
checknext(ls, TK_DO);
10021019
block(ls);
10031020
luaK_patchlist(fs, luaK_jump(fs), whileinit);
1021+
luaK_patchlist(fs, bl.continuelist, whileinit); /* continue goes to start, too */
10041022
check_match(ls, TK_END, TK_WHILE, line);
10051023
leaveblock(fs);
10061024
luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
@@ -1017,6 +1035,7 @@ static void repeatstat (LexState *ls, int line) {
10171035
enterblock(fs, &bl2, 0); /* scope block */
10181036
luaX_next(ls); /* skip REPEAT */
10191037
chunk(ls);
1038+
luaK_patchtohere(fs, bl1.continuelist);
10201039
check_match(ls, TK_UNTIL, TK_REPEAT, line);
10211040
condexit = cond(ls); /* read condition (inside scope block) */
10221041
if (!bl2.upval) { /* no upvalues? */
@@ -1057,6 +1076,7 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
10571076
block(ls);
10581077
leaveblock(fs); /* end of scope for declared variables */
10591078
luaK_patchtohere(fs, prep);
1079+
luaK_patchtohere(fs, bl.previous->continuelist); /* continue, if any, jumps to here */
10601080
endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
10611081
luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
10621082
luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
@@ -1314,6 +1334,11 @@ static int statement (LexState *ls) {
13141334
breakstat(ls);
13151335
return 1; /* must be last statement */
13161336
}
1337+
case TK_CONTINUE: { /* stat -> continuestat */
1338+
luaX_next(ls); /* skip CONTINUE */
1339+
continuestat(ls);
1340+
return 1; /* must be last statement */
1341+
}
13171342
default: {
13181343
exprstat(ls);
13191344
return 0; /* to avoid warnings */

0 commit comments

Comments
 (0)