|
Several people, I'm sure, use the convention that the label
::continue:: is only used right before the loop's "end" or
"until".
Try the following experiment: in llex.c, find "break" (complete
with quotes) and change it to something else, say "BREAK",
so that `break` is no longer a keyword. Rebuild.
Then this works:
> local k=0; while true do k=k+1 if k==7 then goto break end end print(k)
7
I.e. the statement "break" is mere syntactic sugar for "goto break",
where the label "break" is predefined.
One could do that with `continue` too. t's just within my patching skills
make it work with `while`, `for` (both versions), and `repeat`...`until false`.
In lparser.c, change the function `breaklabel` to:
static void breaklabel (LexState *ls) {
TString *n = luaS_new(ls->L, "break"), *c = luaS_new(ls->L, "continue");
int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc),
m = newlabelentry(ls, &ls->dyd->label, c, 0, ls->fs->pc-1);
findgotos(ls, &ls->dyd->label.arr[l]);
findgotos(ls, &ls->dyd->label.arr[m]);
}
Then (patching a superseded Lua version):
Lua 5.3.0 (work2) Copyright (C) 1994-2014 Lua.org, PUC-Rio
> k=0; repeat
>> k=k+1
>> if k<5 then goto continue end
>> print(k)
>> if k>5 then goto break end
>> until false
5
6
For any other `repeat`, `pc-1` is wrong since it bypasses the test.
Maybe a better programmer than me can take up the challenge
of patching lparser.c to handle `repeat` correctly too and to do
`goto restart` (as if ::restart:: sits just before `while` etc.) and
`goto resume` (as if ::resume sits just after `do` etc).