diff options
Diffstat (limited to 'build/panto_lua_repl.c')
| -rw-r--r-- | build/panto_lua_repl.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/build/panto_lua_repl.c b/build/panto_lua_repl.c new file mode 100644 index 0000000..ce99cb1 --- /dev/null +++ b/build/panto_lua_repl.c @@ -0,0 +1,49 @@ +/* + * panto's hook into the upstream `lua.c` standalone interpreter. + * + * We need to call into `pmain` (the body of the standalone REPL/driver) + * with a pre-configured `lua_State` — specifically, one where panto's + * embedded-luarocks searcher and configured `package.path` have already + * been installed. Upstream `pmain` is `static`, so we can't link to it + * from Zig directly. + * + * Trick: include `lua.c` verbatim with `static` redefined to empty, so + * every static gets external linkage. We rename `main` to a stub via + * macro so it doesn't conflict with panto's own `main`. Then we expose + * a single function, `panto_lua_pmain`, that runs `pmain` against a + * caller-provided state. + * + * `lua.c` also defines its own signal handlers via `setsignal` / + * `laction`. We leave those alone — they're useful in `panto lua` too, + * giving Ctrl-C the same behavior it has in upstream `lua`. + */ + +/* Remove `static` everywhere lua.c uses it so symbols are externally + * accessible. We undef `static` back to default for any system headers + * that follow, in case they care. */ +#define static +#include "lua.c" +#undef static + +/* Forward declarations of the (now non-static) symbols we use. */ +extern int pmain(lua_State *L); + +/* + * Trampoline: push (argc, argv) onto `L` and run `pmain` in protected + * mode, mirroring `lua.c::main`'s call pattern. Returns the exit code + * appropriate for `lua` (0 on success, 1 on failure). + * + * The caller is responsible for state lifecycle (lua_close, etc.) — + * we don't open or close `L` ourselves. This is what lets panto's + * subcommand install the embedded-luarocks searcher into `L` *before* + * calling us. + */ +int panto_lua_pmain(lua_State *L, int argc, char **argv) { + lua_pushcfunction(L, &pmain); + lua_pushinteger(L, argc); + lua_pushlightuserdata(L, argv); + int status = lua_pcall(L, 2, 1, 0); + int result = lua_toboolean(L, -1); + report(L, status); + return (result && status == LUA_OK) ? 0 : 1; +} |
