Adding Barewords to Lua

250 views Asked by At

To implement a domain specific language, within lua, I want to add barewords to the language. So that print("foo") could be written as print(foo)

The way I have done this is by changing the metatable of the enviroment table _G.

mt = {__index = function(tbl,key) return key end}
setmetatable(_G, mt)

And that works, because retrieving the value of variable foo is done by _G.foo which is equivalent to _G["foo"]

Is this a good approach? Are there hidden downsides? Is there a better way? Can I do it so that barewords only work inside a certain file? (Perhaps by executing that file, from another luascript, using loadstring)

1

There are 1 answers

3
LorenzoDonati4Ukraine-OnStrike On

As soon as someone declares a local with the same name of your "keywords" it will shadow your "keyword/global var" and your mechanism will fail:

print(foo)   -- does what you think
local foo = 2
print(foo)   -- argh!

and note that you cannot prevent the definition of local variables in a script.

Edit: (answering to a comment).

Are you using a customized Lua engine? You cannot prevent entering local scope, because you are always in local scope. It is exactly the other way around: technically there is no global scope in Lua (with the same meaning as in C, for example). There is a global namespace (implemented as a table), instead. The mechanisms for accessing globals differs between Lua 5.1 (function environments) and Lua 5.2 (implicit _ENV prefixing), but the concept is almost the same.

In particular, when a Lua script is loaded, whether by the interpreter, or by load, loadstring, dofile, etc., it is interpreted as the body of an anonymous function (a closure), usually referred to as the "main chunk". Thus there is always a local scope. In standard Lua you cannot prevent the definition of a local variable when the parser encounters a local statement in the script being loaded.