A thin wrapper over Lua 5.5, providing all the goodies of it ! The zig version is the one on the master branch.
To link / get a module of the Lua Wrapper, one can do the following :
$ zig fetch --save=lua.zig https://codeberg.org/mathieu_cayeux/lua.zigAnd in your build.zig.zon:
const lua_zig = b.dependency("lua.zig");
YOUR_MODULE.addImport("lua-zig", lua_zig.module("lua.zig"));If you want solely the C API :
YOUR_MODULE.addImport("lua-c", lua_zig.module("lua.c"));Then, you can check out the examples/ folder. An overview of the API is :
// functions can take a struct as
// an argument !
fn functor(value: struct {
internal: u32
}) u32 {
std.log.debug("functor({})", .{value});
return value.internal * value.internal;
}
const LUA_PROGRAM =
\\function multiply(x, y)
\\ local z = x * y
\\ z = functor({ internal = z })
\\ return z
\\end
;
pub fn main(init: std.process.Init) !void {
var state: lua.Lua = try .init(init.gpa, .{});
defer state.deinit();
defer {
if (state.diag.hasErr()) {
std.log.err("{}: {s}", .{ state.diag.err.?, state.diag.message });
}
}
try state.setGlobal("functor", functor);
const reader = std.Io.Reader.fixed(LUA_PROGRAM);
try state.loadFromReader(reader);
// The program must be ran once to load symbols
try state.run();
// Return value (here `u32`) can be a struct, string, etc.
// If it is a string or a struct containing one, don't forget to call
// state.free(#) on it !
const ret = try state.call("multiply", .{ 2, 3 }, u32);
std.log.debug("functor(2 * 3) = {}", .{ret});
}Now, the build.zig can be used to generate an exact copy of official repo's Lua libraries ! In particular,
it will create a one-to-one equivalent of what would be generated by make :
PREFIX/
include/*
lib/*
man/man1/*
bin/*To generate the above, do :
$ git clone https://codeberg.org/mathieu_cayeux/lua.zig
$ cd lua.zig
$ zig build install -Dskip-zigNote that skip-zig will skip any TranslateC steps, module creation etc. It should be used
only if you want to create a standard Lua library.
You can also add the option skip-lua-exes which will skip creating the bin and man/man1 folder as well as
what it contains, namely the lua and luac executables and their manpages.
$ zig build install -Dskip-zig -Dskip-lua-exes
$ file zig-out/bin/
zig-out/bin/: cannot open `zig-out/bin/' (No such file or directory)The build toolchain uses the Translate C API to generate the bindings.
This is equivalent on older zig build to doing a @cImport, but the latter will be removed on later versions.
Note that because lua makes heavy use of macros to make inline calls of functions, some translated call will not work, namely because of #164 which is a current bug that doesn't coerce NULL (the macro) to a pointer's null.
As such, some of the following code will get a compile-time error :
const my_str = lua.lua_tostring(L, -1);will get :
// ERROR: error: expected type '[*c]usize', found '?*anyopaque'
pub inline fn lua_tostring(L: anytype, i: anytype) @TypeOf(lua_tolstring(L, i, NULL));
// ^~~~
// -- snip --
// note: generic function instantiated here
const my_str = lua.lua_tostring(new_state, -1);The fix is as follows :
const my_str = lua.lua_tostring(new_state, -1);
// TO
const my_str = lua.lua_tolstring(new_state, -1, null);aka. copying what is after the @TypeOf in the declaration and swapping the values NULL to null where applicable.
I'm using MIT.