lua-users home
lua-l archive

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


On Thu, Jun 26, 2014 at 12:55:55AM -0500, Paige DePol wrote:
> On Jun 11, 2014, at 3:29 AM, Axel Kittenberger <axkibe@gmail.com> wrote:
> 
> > But a switch statement in most script languages (like in Javascript) is
> > syntactic sugar for if/else! That has always been the argument from the
> > Lua team to why there is no switch statement in Lua. Not like for
> > example in C where it is in fact a computed goto.
> 
> I have created a switch statement patch[1] for Lua, it uses a jump table
> (aka computed goto) and is considerably faster than the standard if/else
> structures... however, applying it to vanilla Lua does present one large
> issue.
> 
> Lua itself has no support for symbolic constants, thus the case values of
> the switch statement my patch adds have to be literal constants. This
> leads to the use of magic numbers which hurts overall code quality.
> 
> This, I believe, is one of the major reasons Lua does not yet have a
> switch statement. Without symbolic constants any switch statement added to
> vanilla Lua could only ever be syntactic sugar for an if/else chain.

What about label references? That is, if Lua allowed directly taking a
reference to a label? Then you could use them directly, as when writing a
classic state machine, or build your own jump tables which mapped keys to
labels. Although you might have to add an optimization to memoize constant
tables in the latter case.

The label reference would have to be a new native type. But it might be a
little more elegant at the syntax level.

State machine example

--
-- prints "one", "two", "three" on stdout
--
function f(_, nextstate)
	if nextstate then goto nextstate end
	return A, "one"
::A::
	return B, "two"
::B::
	return Z, "three"
::Z::
end

for nextstate, n in f do
	print(n)
end


Jump table example

--
-- prints "one", "two", "three" on stdout
--
function f(v)
	local t = {
		A = A,
		B = B,
	}

	assert(t[v])
	goto t[v]
::A::
	return "one"
::B::
	return "two"
::C::
	return "three"
end

print(f"A")
print(f"B")
print(f"C")