mirror of
https://github.com/Adorable-Catgirl/Zorya-NEO.git
synced 2024-11-27 12:48:07 +11:00
Zorya config compiler and lua preprocessor added.
This commit is contained in:
parent
f1923257af
commit
c591ea1560
192
luapreproc.lua
Executable file
192
luapreproc.lua
Executable file
@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env lua5.3
|
||||
local _env = {}
|
||||
local directives = {}
|
||||
|
||||
function directives.include(env, args)
|
||||
local path, err = args.get("string", 1)
|
||||
if (not path) then
|
||||
return false, err
|
||||
end
|
||||
local nenv = {code = ""}
|
||||
setmetatable(nenv, {__index=_env})
|
||||
local data, err = nenv:process(path)
|
||||
if (not data) then
|
||||
return false, err
|
||||
end
|
||||
env.code = env.code .. "\n" .. data
|
||||
return true
|
||||
end
|
||||
|
||||
local mods = {}
|
||||
|
||||
function directives.loadmod(env, args)
|
||||
local path, err = args.get("string", 1)
|
||||
if (not path) then
|
||||
return false, err
|
||||
end
|
||||
local file = io.open(path, "rb")
|
||||
if (not file) then
|
||||
return false, "`"..path.."' not found."
|
||||
end
|
||||
local env = {}
|
||||
local copies = {{_G, env}}
|
||||
while #copies ~= 0 do
|
||||
local c = {}
|
||||
for i=1, #copies do
|
||||
for k, v in pairs(copies[i][1]) do
|
||||
if (type(v) == "table") then
|
||||
copies[i][2][k] = {}
|
||||
c[#c+1] = {v, copies[i][2][k]}
|
||||
else
|
||||
copies[i][2][k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
for i=1, #copies do
|
||||
copies[i] = nil
|
||||
end
|
||||
for i=1, #c do
|
||||
copies[i] = c[i]
|
||||
end
|
||||
end
|
||||
local dir2a = {}
|
||||
env.add_directive = function(name, func) do
|
||||
dir2a[#dir2a+1] = {name, func}
|
||||
end
|
||||
local func, err = load(file:read("*a"), "="..path, "t", env)
|
||||
if (not func) then
|
||||
return false, err
|
||||
end
|
||||
local name = func()
|
||||
if not name then
|
||||
return false, "Module did not return a name."
|
||||
end
|
||||
for i=1, #dir2a do
|
||||
directives[dir2a[i][1]] = dir2a[i][2]
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function _env:process(path)
|
||||
print("PROC", path)
|
||||
local file = io.open(path, "rb")
|
||||
local f, err = load(file:read("*a"), "="..path)
|
||||
if not f then
|
||||
io.stderr:write("ERROR: "..err.."\n")
|
||||
os.exit(1)
|
||||
end
|
||||
file:seek("set", 0)
|
||||
local ln = 0
|
||||
for line in file:lines() do
|
||||
ln = ln + 1
|
||||
line = line:gsub("^%s+", "")
|
||||
if (line:sub(1, 3) == "--#") then
|
||||
--Process directive
|
||||
local dir = line:sub(4)
|
||||
local tmp = ""
|
||||
local open_quote = false
|
||||
local escape = false
|
||||
local cmd = nil
|
||||
local args = {}
|
||||
local pos = 0
|
||||
dir = dir:gsub("^%s+", ""):gsub("%s+$", ""):gsub("%s+", " ")
|
||||
for i=1, #dir do
|
||||
local c = dir:sub(i, i)
|
||||
if (c == " " and not open_quote) then
|
||||
if (tmp ~= "") then
|
||||
if not cmd then
|
||||
cmd = tmp
|
||||
else
|
||||
args[#args+1] = tmp
|
||||
end
|
||||
end
|
||||
tmp = ""
|
||||
elseif (c == "\"" and not escape and not open_quote) then
|
||||
open_quote = true
|
||||
elseif (c == "\"" and not escape) then
|
||||
open_quote = false
|
||||
args[#args+1] = {"string", tmp}
|
||||
tmp = ""
|
||||
elseif (c == "\\" and not escape) then
|
||||
escape = true
|
||||
else
|
||||
if (escape) then escape = false end
|
||||
tmp = tmp .. c
|
||||
end
|
||||
end
|
||||
--Process arguments
|
||||
local rargs = {}
|
||||
for i=1, #args do
|
||||
if (type(args[i]) == "table") then
|
||||
if (args[i][1] == "string") then
|
||||
local str = args[i][2]
|
||||
local sp, ep = str:find("%$%([%w_]+%)")
|
||||
while sp do
|
||||
local var = str:sub(sp, ep)
|
||||
local st1, st2 = str:sub(1, sp-3), str:sub(ep+2)
|
||||
str = st1 .. var
|
||||
local nsp = #str
|
||||
str = str .. st2
|
||||
sp, ep = str:find("%$%([%w_]+%)", nsp)
|
||||
end
|
||||
args[i][2] = str
|
||||
end
|
||||
rargs[#rargs+1] = args[i]
|
||||
elseif (tonumber(args[i])) then
|
||||
rargs[#rargs+1] = {"number", args[i]}
|
||||
elseif (args == "true" or args == "false") then
|
||||
rargs[#rargs+1] = {"boolean", args[i] == "true"}
|
||||
elseif (os.getenv(args[i])) then
|
||||
rargs[#rargs+1] = {"var", args[i]}
|
||||
else
|
||||
io.stderr:write("ERROR: "..path..":"..ln..": Undefined variable.\n")
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
if (not directives[cmd]) then
|
||||
io.stderr:write("ERROR: "..path..":"..ln..": Unknown directive.\n")
|
||||
os.exit(1)
|
||||
end
|
||||
local rtn, err = directives[cmd](self, {get=function(atype, i)
|
||||
if (type(atype) == "number") then
|
||||
return rargs[i][2], rargs[i][1]
|
||||
end
|
||||
if (rargs[i] == nil) then
|
||||
return false, "argument #"..i..": expected `"..atype.."', got nil"
|
||||
end
|
||||
if (rargs[i][1] ~= atype) then
|
||||
return false, "argument #"..i..": expected `"..atype.."', got `"..rargs[i][1].."'"
|
||||
end
|
||||
return rargs[i][2]
|
||||
end})
|
||||
if (type(rtn) ~= "boolean") then
|
||||
io.stderr:write("ERROR: "..path..":"..ln..": Expected return type `boolean', got `"..type(rtn).."'.\n")
|
||||
os.exit(1)
|
||||
end
|
||||
if (not rtn) then
|
||||
err = err or "Unknown error"
|
||||
io.stderr:write("ERROR: "..path..":"..ln..": "..err..".\n")
|
||||
end
|
||||
else
|
||||
self.code = self.code .. line .. "\n"
|
||||
end
|
||||
end
|
||||
return self.code
|
||||
end
|
||||
|
||||
local env = {code = ""}
|
||||
setmetatable(env, {__index=_env})
|
||||
env:process(arg[1])
|
||||
local tmpfile = os.tmpname()
|
||||
local tmpf = io.open(tmpfile, "wb")
|
||||
tmpf:write(env.code)
|
||||
tmpf:close()
|
||||
if (os.execute("luamin -f "..tmpfile.." > "..arg[2])) then
|
||||
os.execute("stat -c \"Output: %s bytes\" "..arg[2])
|
||||
else
|
||||
io.stderr:write("Error: ")
|
||||
os.execute("cat "..arg[2].." 1>&2")
|
||||
os.remove(arg[2])
|
||||
end
|
||||
os.remove(tmpfile)
|
71
zcfg-compiler/init.lua
Normal file
71
zcfg-compiler/init.lua
Normal file
@ -0,0 +1,71 @@
|
||||
local file = arg[1]
|
||||
if (file == "-") then
|
||||
file = io.stdin
|
||||
else
|
||||
file = io.open(file, "r")
|
||||
end
|
||||
|
||||
local ast = {}
|
||||
|
||||
local current_node = ast
|
||||
|
||||
for line in file:lines() do
|
||||
if (line:sub(1, 6) ~= "entry " and line ~= "") then
|
||||
--Parse arguments
|
||||
local tmp = ""
|
||||
local open_quote = false
|
||||
local escape = false
|
||||
local cmd = nil
|
||||
local args = {}
|
||||
local pos = 0
|
||||
line = line:gsub("^%s+", ""):gsub("%s+$", ""):gsub("%s+", " ")
|
||||
for i=1, #line do
|
||||
local c = line:sub(i, i)
|
||||
if (c == " " and not open_quote) then
|
||||
if (tmp ~= "") then
|
||||
if not cmd then
|
||||
cmd = tmp
|
||||
else
|
||||
args[#args+1] = tmp
|
||||
end
|
||||
end
|
||||
tmp = ""
|
||||
elseif (c == "\"" and not escape and not open_quote) then
|
||||
open_quote = true
|
||||
elseif (c == "\"" and not escape) then
|
||||
open_quote = false
|
||||
args[#args+1] = "\""..tmp.."\""
|
||||
tmp = ""
|
||||
elseif (c == "\\" and not escape) then
|
||||
escape = true
|
||||
else
|
||||
if (escape) then escape = false end
|
||||
tmp = tmp .. c
|
||||
end
|
||||
end
|
||||
if (tmp ~= "") then
|
||||
if not cmd then
|
||||
cmd = tmp
|
||||
else
|
||||
args[#args+1] = tmp
|
||||
end
|
||||
end
|
||||
current_node[#current_node+1] = {type="call", call = cmd, args = args}
|
||||
elseif (line ~= "") then
|
||||
ast[#ast+1] = {type = "entry", name = line:sub(7)}
|
||||
current_node = ast[#ast]
|
||||
end
|
||||
end
|
||||
|
||||
print("-- WARNING: Do not edit this file. This file is autogenerated by the zcfg-compiler")
|
||||
for i=1, #ast do
|
||||
if (ast[i].type == "entry") then
|
||||
print("menu.entry(\""..ast[i].name.."\", function(env)")
|
||||
for j=1, #ast[i] do
|
||||
print("\tenv:"..ast[i][j].call.."("..table.concat(ast[i][j].args, ", ")..")")
|
||||
end
|
||||
print("end)")
|
||||
else
|
||||
print("menu."..ast[i].call.."("..table.concat(ast[i].args, ", ")..")")
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user