Skip to content

Commit

Permalink
Error "break outside loop" made a syntax error
Browse files Browse the repository at this point in the history
Syntax errors are easier to handle than semantic errors.
  • Loading branch information
roberto-ieru committed Jan 13, 2025
1 parent 4b107a8 commit 10e931d
Showing 1 changed file with 14 additions and 11 deletions.
25 changes: 14 additions & 11 deletions lparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ typedef struct BlockCnt {
int firstgoto; /* index of first pending goto in this block */
lu_byte nactvar; /* # active locals outside the block */
lu_byte upval; /* true if some variable in the block is an upvalue */
lu_byte isloop; /* true if 'block' is a loop */
lu_byte isloop; /* 1 if 'block' is a loop; 2 if it has pending breaks */
lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */
} BlockCnt;

Expand Down Expand Up @@ -677,15 +677,10 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
** generates an error for an undefined 'goto'.
*/
static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
const char *msg;
if (eqstr(gt->name, luaS_newliteral(ls->L, "break"))) {
msg = "break outside loop at line %d";
msg = luaO_pushfstring(ls->L, msg, gt->line);
}
else {
msg = "no visible label '%s' for <goto> at line %d";
msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
}
const char *msg = "no visible label '%s' for <goto> at line %d";
msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
/* breaks are checked when created, cannot be undefined */
lua_assert(!eqstr(gt->name, luaS_newliteral(ls->L, "break")));
luaK_semerror(ls, msg);
}

Expand All @@ -699,7 +694,7 @@ static void leaveblock (FuncState *fs) {
fs->freereg = stklevel; /* free registers */
removevars(fs, bl->nactvar); /* remove block locals */
lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */
if (bl->isloop) /* has to fix pending breaks? */
if (bl->isloop == 2) /* has to fix pending breaks? */
createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0);
solvegotos(fs, bl);
if (bl->previous == NULL) { /* was it the last block? */
Expand Down Expand Up @@ -1465,6 +1460,14 @@ static void gotostat (LexState *ls, int line) {
** Break statement. Semantically equivalent to "goto break".
*/
static void breakstat (LexState *ls, int line) {
BlockCnt *bl; /* to look for an enclosing loop */
for (bl = ls->fs->bl; bl != NULL; bl = bl->previous) {
if (bl->isloop) /* found one? */
goto ok;
}
luaX_syntaxerror(ls, "break outside loop");
ok:
bl->isloop = 2; /* signal that block has pending breaks */
luaX_next(ls); /* skip break */
newgotoentry(ls, luaS_newliteral(ls->L, "break"), line);
}
Expand Down

0 comments on commit 10e931d

Please sign in to comment.