Skip to content

Commit

Permalink
feat: add registerFns to 5.1 api
Browse files Browse the repository at this point in the history
This is for the luaL_register function
  • Loading branch information
natecraddock committed Feb 18, 2023
1 parent b6dec0d commit 837048b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 21 deletions.
41 changes: 20 additions & 21 deletions src/ziglua-5.1/lib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub const Event = enum(u3) {
/// Type for arrays of functions to be registered
pub const FnReg = struct {
name: [:0]const u8,
func: ?CFn,
func: CFn,
};

/// The index of the global environment table
Expand Down Expand Up @@ -1407,28 +1407,27 @@ pub const Lua = struct {
}

/// Opens a library
/// TODO: finish this function
// pub fn registerFns(lua: *Lua, libname: ?[:0]const u8, funcs: []const FnReg) void {
// if (libname) |name| {
// lua.findTable
// }

// }

/// Registers all functions in the array `fns` into the table on the top of the stack
/// All functions are created with `num_upvalues` upvalues
pub fn setFuncs(lua: *Lua, funcs: []const FnReg, num_upvalues: i32) void {
lua.checkStackAux(num_upvalues, "too many upvalues");
pub fn registerFns(lua: *Lua, libname: ?[:0]const u8, funcs: []const FnReg) void {
// translated from the implementation of luaI_openlib so we can use a slice of
// FnReg without requiring a sentinel end value
if (libname) |name| {
_ = c.luaL_findtable(lua.state, registry_index, "_LOADED", 1);
lua.getField(-1, name);
if (!lua.isTable(-1)) {
lua.pop(1);
if (c.luaL_findtable(lua.state, globals_index, name, @intCast(c_int, funcs.len))) |_| {
lua.raiseErrorAux("name conflict for module " ++ c.LUA_QS, .{name.ptr});
}
lua.pushValue(-1);
lua.setField(-3, name);
}
lua.remove(-2);
lua.insert(-1);
}
for (funcs) |f| {
if (f.func) |func| {
var i: i32 = 0;
// copy upvalues to the top
while (i < num_upvalues) : (i += 1) lua.pushValue(-num_upvalues);
lua.pushClosure(func, num_upvalues);
} else lua.pushBoolean(false); // register a placeholder
lua.setField(-(num_upvalues + 2), f.name);
lua.pushFunction(f.func);
lua.setField(-2, f.name);
}
lua.pop(num_upvalues);
}

/// Raises a type error for the argument `arg` of the C function
Expand Down
30 changes: 30 additions & 0 deletions src/ziglua-5.1/tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,36 @@ test "string buffers" {
lua.pop(1);
}

test "function registration" {
var lua = try Lua.init(testing.allocator);
defer lua.deinit();

// register all functions as part of a table
const funcs = [_]ziglua.FnReg{
.{ .name = "add", .func = ziglua.wrap(add) },
};
lua.newTable();
lua.registerFns(null, &funcs);

lua.getField(-1, "add");
lua.pushInteger(1);
lua.pushInteger(2);
try lua.protectedCall(2, 1, 0);
try expectEqual(@as(Integer, 3), lua.toInteger(-1));
lua.setTop(0);

// register functions as globals in a library table
lua.registerFns("testlib", &funcs);

// testlib.add(1, 2)
lua.getGlobal("testlib");
lua.getField(-1, "add");
lua.pushInteger(1);
lua.pushInteger(2);
try lua.protectedCall(2, 1, 0);
try expectEqual(@as(Integer, 3), lua.toInteger(-1));
}

test "panic fn" {
var lua = try Lua.init(testing.allocator);
defer lua.deinit();
Expand Down

0 comments on commit 837048b

Please sign in to comment.