#!/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 #include #include ]]) supportedTarget = true end if os.getenv("target_os") == "openbsd" then ofile:write([[ #include #include #include ]]) supportedTarget = true end if os.getenv("target_os") == "windows" then ofile:write([[ #include #include #include ]]) 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()