Allow empty statements (semicolons) anywhere. v3.0 backport.

Reported by Volodymyr Chernetskyi. #1519
This commit is contained in:
Mike Pall 2026-10-13 11:49:54 +02:00
parent c6ffc141a8
commit 0218af7e36
2 changed files with 10 additions and 9 deletions

View File

@ -370,8 +370,7 @@ Other features are only enabled, if LuaJIT is built with
</p>
<ul>
<li><tt>goto</tt> is a keyword and not a valid variable name anymore.</li>
<li><tt>break</tt> can be placed anywhere. Empty statements (<tt>;;</tt>)
are allowed.</li>
<li><tt>break</tt> can be placed anywhere.</li>
<li><tt>__lt</tt>, <tt>__le</tt> are invoked for mixed types.</li>
<li><tt>__len</tt> for tables. <tt>rawlen()</tt> library function.</li>
<li><tt>pairs()</tt> and <tt>ipairs()</tt> check for <tt>__pairs</tt> and
@ -427,6 +426,7 @@ LuaJIT 2.1 supports some
<li><tt>const</tt> Declaration</li>
<li>Short Function Expression</li>
<li>Underscores in Number Literals</li>
<li>Empty statements (<tt>;;</tt>) are allowed anywhere.</li>
</ul>
<p>
Not backported are:

View File

@ -2740,13 +2740,13 @@ static void parse_label(LexState *ls)
lj_lex_error(ls, 0, LJ_ERR_XLDUP, strdata(name));
idx = gola_new(ls, name, VSTACK_LABEL, fs->pc);
lex_check(ls, TK_label);
/* Recursively parse trailing statements: labels and ';' (Lua 5.2 only). */
/* Recursively parse trailing statements: labels and ';'. */
for (;;) {
if (ls->tok == TK_label) {
synlevel_begin(ls);
parse_label(ls);
synlevel_end(ls);
} else if (LJ_52 && ls->tok == ';') {
} else if (ls->tok == ';') {
lj_lex_next(ls);
} else {
break;
@ -3033,16 +3033,17 @@ static int parse_stmt(LexState *ls)
lj_lex_next(ls);
parse_break(ls);
return !LJ_52; /* Must be last in Lua 5.1. */
case TK_continue:
if (!parse_isend(lj_lex_lookahead(ls))) goto assign; /* Soft keyword. */
case TK_continue: {
LexToken tokx = lj_lex_lookahead(ls);
if (!(parse_isend(tokx) || tokx == ';'))
goto assign; /* Soft keyword. */
lj_lex_next(ls);
parse_continue(ls);
return 1; /* Must be last. */
#if LJ_52
}
case ';':
lj_lex_next(ls);
break;
#endif
case TK_label:
parse_label(ls);
break;
@ -3068,7 +3069,7 @@ static void parse_chunk(LexState *ls)
synlevel_begin(ls);
while (!islast && !parse_isend(ls->tok)) {
islast = parse_stmt(ls);
lex_opt(ls, ';');
while (ls->tok == ';') lj_lex_next(ls);
lj_assertLS(ls->fs->framesize >= ls->fs->freereg &&
ls->fs->freereg >= ls->fs->nactvar,
"bad regalloc");