mirror of
https://github.com/lua/lua.git
synced 2025-02-04 06:13:04 +08:00
Error "break outside loop" made a syntax error
Syntax errors are easier to handle than semantic errors.
This commit is contained in:
parent
4b107a8776
commit
10e931da82
25
lparser.c
25
lparser.c
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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? */
|
||||
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user