me.fier.engine/lua_translate
2023-09-01 14:30:21 +02:00

163 lines
4.0 KiB
Plaintext
Executable File

#!/usr/bin/env lua5.3
basepath = (debug.getinfo(1, "S").source:sub(2):match("(.*[/\\])") or "./"):sub(1,-2)
package.path = basepath .. "/src/?.lua;" ..basepath .. "/src/?/init.lua" .. ";" .. package.path
local toml = require "toml"
local typesIn = {
["__unknown"] = "lua_touserdata",
["char"] = "luaL_checkinteger",
["int"] = "luaL_checkinteger",
["float"] = "luaL_checknumber",
["long long"] = "luaL_checkinteger",
["unsigned char"] = "luaL_checkinteger",
["char *"] = "(char *)luaL_checkstring"
}
local typesOut = {
["__unknown"] = "lua_pushlightuserdata",
["char"] = "lua_pushinteger",
["int"] = "lua_pushinteger",
["long long"] = "lua_pushinteger",
["unsigned char"] = "lua_pushinteger",
["char *"] = "lua_pushstring"
}
local function readFile(path)
local file = io.open(path,"rb")
local output = file:read("*a")
file:close()
return output
end
local function bp(path)
return basepath .. "/" .. path
end
local function stringJoin(lst,sep)
local nstring = ""
for _,str in ipairs(lst) do
nstring = nstring .. sep .. str
end
return string.sub(nstring,1 + string.len(sep))
end
local statics = toml.parse(readFile(bp("src/values/statics.toml")))
local functions = toml.parse(readFile(bp("src/values/functions.toml")))
local ofile = io.open(bp("src/lua.c"),"wb")
local supportedTarget = false
if os.getenv("target_os") == "linux" then
ofile:write([[
#include <lua5.3/lua.h>
#include <lua5.3/lualib.h>
#include <lua5.3/lauxlib.h>
]])
supportedTarget = true
end
if os.getenv("target_os") == "openbsd" then
ofile:write([[
#include <lua-5.3/lua.h>
#include <lua-5.3/lualib.h>
#include <lua-5.3/lauxlib.h>
]])
supportedTarget = true
end
if os.getenv("target_os") == "windows" then
ofile:write([[
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
]])
supportedTarget = true
end
if supportedTarget == false then
print("Platform " ..tostring(os.getenv("target_os")).. " unsupported by lua_translate.")
os.exit(1)
end
ofile:write([[
lua_State * engine_lua_state;
#include "lua_manual.c"
]])
for func,_ in pairs(functions) do
if functions[func].lua == "no" or
functions[func].lua == "manual" then
goto continue
end
local invarCount = 1
local funcnew,_ = string.gsub(func,"engine_","",1)
funcnew = "engine_luaf_" ..funcnew
ofile:write('int ' ..funcnew.. '(lua_State *L) {\n')
for _,arg in ipairs(functions[func].arguments) do
local checkfunc = false
if typesIn[arg] == nil then
checkfunc = typesIn.__unknown
else
checkfunc = typesIn[arg]
end
ofile:write('\t' ..arg.. ' ' ..functions[func].argNames[invarCount].. ' = ' ..checkfunc.. '(L,' ..tostring(invarCount).. ');\n')
invarCount = invarCount + 1
end
local argstring = "(" ..stringJoin(functions[func].argNames,",").. ")"
local outtype = functions[func].type
if outtype == "void" then
ofile:write('\t' .. func .. argstring .. ";")
ofile:write('\n\treturn 0;')
else
local pushfunc = false
if typesOut[outtype] == nil then
pushfunc = typesOut.__unknown
else
pushfunc = typesOut[outtype]
end
ofile:write('\t' ..outtype.. ' outvar = ' ..func .. argstring.. ';')
ofile:write('\n\t' ..pushfunc.. '(L,outvar);')
ofile:write('\n\treturn 1;')
end
ofile:write('\n}\n\n')
::continue::
end
ofile:write([[
void engine_lua_init() {
engine_lua_state = luaL_newstate();
luaL_openlibs(engine_lua_state);
]])
for static,_ in pairs(statics) do
ofile:write('\tlua_pushinteger(engine_lua_state,' ..static.. ');\n')
ofile:write('\tlua_setglobal(engine_lua_state,"' ..static.. '");\n')
end
for func,_ in pairs(functions) do
if functions[func].lua == "no" or
functions[func].lua == "manual" then
goto continue
end
local funcnew,_ = string.gsub(func,"engine_","",1)
funcnew = "engine_luaf_" ..funcnew
ofile:write('\tlua_pushcfunction(engine_lua_state,' ..funcnew.. ');\n')
ofile:write('\tlua_setglobal (engine_lua_state,"' ..func.. '");\n')
::continue::
end
ofile:write([[
engine_lua_init_manual();
luaL_loadfile(engine_lua_state,"mods/main/script/main.lua");
lua_call(engine_lua_state,0,0);
}]])
ofile:close()