terralang / terra

Terra is a low-level system programming language that is embedded in and meta-programmed by the Lua programming language.

Home Page:terralang.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using Lua libraries rarely works due to strict Lua semantics used in Terra

renatoathaydes opened this issue · comments

I have been trying to use Lua testing tools, like LuaUnit and busted, but neither works in Terra.

The reason seems related to enforcement of declaring variables before use.

Example error trying to run busted:

/usr/local/share/lua/5.1/pl/compat.lua:228: Global variable 'warn' is not declared. Global variables must be 'declared' through a regular assignment (even to nil) at global scope before being used.
stack traceback:
	[C]: in function 'error'
	/Users/runner/work/terra/terra/src/strict.lua:39: in function '__index'
	/usr/local/share/lua/5.1/pl/compat.lua:228: in main chunk
	[C]: in function 'require'
	/usr/local/share/lua/5.1/pl/utils.lua:9: in main chunk
	[C]: in function 'require'
	/usr/local/share/lua/5.1/pl/path.lua:21: in main chunk
	[C]: in function 'require'
	/usr/local/share/lua/5.1/busted/runner.lua:3: in main chunk
	[C]: in function 'require'
	testing.lua:1: in main chunk

Both frameworks work fine in Lua, of course.

Is it possible to use Lua standard semantics in the Lua code when "building" Terra code?

BTW I use Lua 5.4, and just symlinked the libs to the 5.1 directory... I think the error is unrelated to that, but would it be possible to "upgrade" Lua to 5.4 or the problem is LuaJIT is still on 5.1?

I think you're hitting this code: https://github.com/terralang/terra/blob/master/src/strict.lua

One workaround would be to try something like:

setmetatable(_G, nil)

If you prefer for this to be temporary rather than permanent, you could try:

local old_metatable = getmetatable(_G)
setmetatable(_G, nil)
require(...)
setmetatable(_G, old_metatable)

But of course that assumes the issue is only present in require on the libraries, and not in using the libraries themselves.

About your second comment: we use LuaJIT, which is compatible with Lua 5.1 (and parts of Lua 5.2 that are backwards compatible with 5.1). LuaJIT has a strong backwards compatibility policy which prevents it from ever fully upgrading to Lua 5.2+, though there is a mode you can turn on to get better (though still not full) Lua 5.2+ compatibility. As far as I know, there hasn't been any effort to adopt Lua 5.3 or 5.4 features in LuaJIT (even where backwards compatible).

As a result, any libraries you use that assume Lua 5.3-5.4 features (or some 5.2 features, depending on what they are) will not work with LuaJIT, and therefore Terra. Hopefully those libraries are maintaining support for older Lua, but you certainly need to be careful.

There is a branch of Terra that uses Lua instead of LuaJIT, but it is very, very half baked. JIT support does not work at all. That means you need to use terralib.saveobj to save a binary to be executed; you cannot do it in-process. This is not something that is likely to have a solution any time soon, because we rely heavily on LuaJIT's FFI module, which does not have a high quality alternative in Lua. The hacky version I committed into the branch is good enough to do basic stuff, but really isn't in a good place to expand to more general JIT support. In short, this work has a lot of roadblocks and I don't see it making progress any time soon.

Thanks for the information. I am a completely noobie in Lua and don't really care about Lua 5.1 VS 5.2, I just thought that, like in most other languages, the latest version if where everyone tries to stay at.

Anyway, that "busted" library does lots of funky stuff and has many deps, so I moved back to "luaunit" which has no dependencies and does the job... it works after I removed the metatable as you showed.