lua-users home
lua-l archive

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

On 4-Oct-05, at 11:18 AM, Diego Nehab wrote:


The problem with the hypothetical continue is not that "done" is "left
uninitialized" in the sense that it is "still nil". It doesn't exist
at all; the slot which it will occupy has been used by Lua as a
temporary in the call to l:match, and consequently it will have a
random value (which is probably *not* a false value) so that the
loop will exit prematurely. You'd have to actually install the
continue patch to see that happen, I supppose.

I don't see this as a fundamental problem. More like an implementation
bug with the continue patch now that the scoping rule of the repeat
loop has been changed. Surely it wouldn't be impossible to make sure the
slots of locals used in the until expression were reserved a priori if
there is a continue statement that can jump across their declarations.
Would this be more complicated? Yes. But still, it's the continue's
implementation's problem, not the scoping rule's problem.

What is the semantics of 'continue'? The whole point of using "structured" exits like 'break' and 'continue' instead of 'goto' is that it syntactically prevents the error of jumping around initialization of a variable. So 'continue' must mean to go to the end of the scope, at which point the loop will be repeated. If the 'until' clause is inside the scope, 'continue' should continue to after the 'until' clause. That would be more apparent if the loop were written:

  local l ="*l" or "quit"
  if l:match"^#" then continue end
  local g, rest = l:match"(%S+)%s*(.*)"
  local done = handle[g](g, words(rest))
  until done

which was obviously the intention. (In fact, in this particular case you could eliminate the local altogether.) That's what I suggested earlier in the thread, and the more I look at it, the more sense it makes to me.

Nothing is impossible. But the reservation of locals "a priori" in a one-pass compiler like Lua is pretty close. It's not really a priori -- when the block starts, none of the locals have been seen yet, so Lua cannot know how many locals to pre-allocate. Furthermore, locals cannot be in arbitrary places on the stack: if they are assigned in sequence as the multiple results of a function call, for example, they need to be allocated in sequence. So the only way to accomplish it would be either to defer compilation of the entire loop (which could be arbitrarily long) until the whole loop had been read, which defeats the point of having a one-pass compiler, or to preallocate some number of locals, whether needed or not, initialise them all to nil, and then hope for the best.