summaryrefslogtreecommitdiff
path: root/build/panto_lua_repl.c
diff options
context:
space:
mode:
authorT <t@tjp.lol>2026-05-27 08:04:04 -0600
committerT <t@tjp.lol>2026-05-27 11:46:52 -0600
commit576891dc2ec4d917932a4c396471d4bbbad90c8e (patch)
tree0662d629cf15a2e9cbb51353f6d3abe6d2c6edb5 /build/panto_lua_repl.c
parentb72a405534d6be019573ee0a806014e2713fe55e (diff)
Finish the hard parts of the lua makeover
- bundle luarocks source in the panto binary - bootstrap process (intended for first `panto` run): - make ~/.local/share/panto/... - write out luarocks sources into it - run luarocks to install luv - new `panto bootstrap` command just runs the bootstrap - `panto bootstrap --force` removes everything and re-bootstraps - new `panto lua` command just runs panto's embedded lua
Diffstat (limited to 'build/panto_lua_repl.c')
-rw-r--r--build/panto_lua_repl.c49
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;
+}