Allocations occur when executed, since Lua is an imperative language.
There ARE languages which do some of the things you are discussing, but one reason Lua doesn't is a very pragmatic one: it's hard to make such languages efficient (in size, compile speed and runtime speed). A number in Lua is stored compactly and does not incur any memory-management overhead to speak of, while a table-driven model is FAR more expensive. You are correct that Lua stores "globals" in a table, and in fact it is well-known that Lua access to locals is more efficient than global access, which is why you will sometimes find this idiom in Lua:
local foo = foo
Which copies a global into a local for faster subsequent access.
If you go down this path you are creating a language much more focused on meta-pogramming, and this cane get very complex very quickly. In some ways, much of the complexity of C++ is directly traceable to its attempt to be both a general purpose language and a meta-language. I think it's a tribute to the Lua designers that they created a language that is both compact and yet still gives 80% of a meta-language (and, imho, the other 20% is the "dangerous" 20%).