Skip to content

Instantly share code, notes, and snippets.

@fmamud
Last active August 18, 2022 11:02
Show Gist options
  • Save fmamud/b35cfdb072069dd8e395fab8c5b4d42e to your computer and use it in GitHub Desktop.
Save fmamud/b35cfdb072069dd8e395fab8c5b4d42e to your computer and use it in GitHub Desktop.
Lua Dogfood
-- Marc Balmer marc@msys.ch via lists.lua.org
-- $ lua luacc.lua -o luacc luacc.lua
local outfile = 'luacc.out'
local strip = false
for k, v in pairs(arg) do
if v == '-o' then
outfile = arg[k + 1]
arg[k] = ''
arg[k + 1] = ''
elseif v == '-s' then
strip = true
arg[k] = ''
end
end
-- Load the chunks and keep the bytecodes
local bytecode = {}
for k, v in ipairs(arg) do
if v ~= '' then
bytecode[#bytecode + 1] = string.dump(loadfile(v), strip)
end
end
-- Start the compiler that expects C code on standard input
-- local c = io.popen('cc -x c -o ' .. outfile .. ' -O3 -I/usr/local/include '
-- .. '-L/usr/local/lib -llua -', 'w')
-- Lua on Homebrew
local c = io.popen('cc -x c -o ' .. outfile .. ' -O3 -I/opt/homebrew/Cellar/lua/5.4.4_1/include/lua '
.. '-L/opt/homebrew/Cellar/lua/5.4.4_1/lib -llua -', 'w')
-- Dump the bytecode to a const char array
c:write('static const char bytecode[] = {')
bytecode = table.concat(bytecode)
for n = 1, #bytecode do
c:write(string.format('0x%02x,', string.byte(bytecode, n)))
end
c:write('}; static unsigned int bytecode_len = ' .. #bytecode .. ';\n')
-- Write the glue code
c:write([[
#include <stdlib.h>
#include <strings.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
int
main(int argc, char *argv[])
{
lua_State *L;
char *prognam;
int n;
/* Create a Lua state and provide the standard ibraries to it */
if (!(L = luaL_newstate()))
fprintf(stderr, "memory allocation error\n");
luaL_openlibs(L);
/* Create the arg table */
lua_newtable(L);
for (n = 1; n < argc; n++) {
lua_pushinteger(L, n);
lua_pushstring(L, argv[n]);
lua_settable(L, -3);
}
/* Push the binary name last */
prognam = rindex(argv[0], '/');
if (!prognam)
prognam = argv[0];
else
prognam++;
lua_pushinteger(L, 0);
lua_pushstring(L, prognam);
lua_settable(L, -3);
lua_setglobal(L, "arg");
if (luaL_loadbuffer(L, bytecode, bytecode_len, "luac") != LUA_OK) {
fprintf(stderr, "load error: %s\n", lua_tostring(L, 1));
return -1;
}
if (lua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK) {
fprintf(stderr, "runtime error: %s\n", lua_tostring(L, -1));
return -1;
}
return 0;
}
]])
-- Finally close the pipe and let the compiler do it's work
c:close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment