[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: New scoping rule for "repeat" and "continue" patch
- From: Rici Lake <lua@...>
- Date: Tue, 4 Oct 2005 12:10:16 -0500
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
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 = io.read"*l" or "quit"
if l:match"^#" then continue end
local g, rest = l:match"(%S+)%s*(.*)"
local done = handle[g](g, words(rest))
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.