71 lines
1.6 KiB
Lua
71 lines
1.6 KiB
Lua
local function unresolve_require(paths, f)
|
|
for _, pattern in ipairs(paths) do
|
|
local path = f:match(pattern);
|
|
if path then
|
|
return path:gsub("%/", ".");
|
|
end
|
|
end
|
|
|
|
error("path " .. f .. " couldn't be resolved to any valid module");
|
|
end
|
|
|
|
local function all_loader(paths, ...)
|
|
local files = { ... };
|
|
|
|
return coroutine.wrap(function ()
|
|
for _, f in ipairs(files) do
|
|
local name = unresolve_require(paths, f);
|
|
local bytecode = string.dump(assert(load(io.lines(f, 1024), "@" .. f, "t", nil)));
|
|
|
|
coroutine.yield(("package.preload[%q] = load(%q, %q, 'b');"):format(name, bytecode, f));
|
|
end
|
|
|
|
coroutine.yield("require 'init' (...);");
|
|
end);
|
|
end
|
|
|
|
local function escape(str)
|
|
return "\"" .. str:gsub(".", function (c)
|
|
local b = string.byte(c);
|
|
|
|
if c == "\n" then
|
|
return "\\n";
|
|
elseif c == "\\" then
|
|
return "\\\\";
|
|
elseif c == "\"" then
|
|
return "\\\"";
|
|
elseif b >= 32 and b <= 126 then
|
|
return c;
|
|
else
|
|
return ("\\%.3o"):format(b);
|
|
end
|
|
end) .. "\"";
|
|
end
|
|
|
|
local function main(root, out, ...)
|
|
local paths = { root .. "/(.+).lua", root .. "/(.+)/init.lua" };
|
|
|
|
for el in package.path:gmatch "[^;]+" do
|
|
paths[#paths + 1] = el:gsub("?", "(.+)");
|
|
end
|
|
|
|
local res = string.dump(assert(load(all_loader(paths, ...), "@<entry>", "t", nil)));
|
|
|
|
local f = assert(io.open(out, "w"));
|
|
f:write "#include <stdint.h>\n";
|
|
f:write "#define BYTECODE entry_bytecode\n";
|
|
f:write "#define BYTECODE_SIZE (sizeof entry_bytecode - 1)\n";
|
|
f:write "static const uint8_t entry_bytecode[] = ";
|
|
|
|
for i = 1, math.ceil(#res / 64) do
|
|
f:write(escape(res:sub((i - 1) * 64 + 1, i * 64)));
|
|
f:write"\n";
|
|
end
|
|
|
|
f:write ";";
|
|
|
|
assert(f:close());
|
|
end
|
|
|
|
main(...);
|