lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Several people, I'm sure, use the convention that the label
::continue:: is only used right before the loop's "end" or

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)

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, 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

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).