mirror of
https://github.com/minetest-mods/i3.git
synced 2025-07-04 17:40:23 +02:00
Improve preprocessor a bit
This commit is contained in:
90
src/preprocessor.lua
Normal file
90
src/preprocessor.lua
Normal file
@ -0,0 +1,90 @@
|
||||
--[[ All source files have to be preprocessed before loading.
|
||||
This allows implementing custom operators like bitwise ones. ]]
|
||||
|
||||
local fmt, split = string.format, string.split
|
||||
local var = "[%w%.%[%]\"\'_]"
|
||||
local modpath = core.get_modpath"i3"
|
||||
local _,_, fs_elements = dofile(modpath .. "/src/styles.lua")
|
||||
|
||||
local operators = {
|
||||
["([%+%-%*%^/&|])="] = function(a, b, c)
|
||||
return fmt("%s = %s %s %s", a, a, b, c)
|
||||
end,
|
||||
|
||||
["+%+"] = function(a, b)
|
||||
return fmt("%s = %s + 1\n%s", a, a, b)
|
||||
end,
|
||||
|
||||
["&"] = function(a, b)
|
||||
return fmt("bit.band(%s, %s)", a, b)
|
||||
end,
|
||||
|
||||
["|"] = function(a, b)
|
||||
return fmt("bit.bor(%s, %s)", a, b)
|
||||
end,
|
||||
|
||||
["<<"] = function(a, b)
|
||||
return fmt("bit.lshift(%s, %s)", a, b)
|
||||
end,
|
||||
|
||||
[">>"] = function(a, b)
|
||||
return fmt("bit.rshift(%s, %s)", a, b)
|
||||
end,
|
||||
|
||||
["<<="] = function(a, b)
|
||||
return fmt("%s = bit.lshift(%s, %s)", a, a, b)
|
||||
end,
|
||||
|
||||
[">>="] = function(a, b)
|
||||
return fmt("%s = bit.rshift(%s, %s)", a, a, b)
|
||||
end,
|
||||
}
|
||||
|
||||
local function compile(data)
|
||||
data = data:gsub("IMPORT%((.-)%)", function(a)
|
||||
return "local " .. a:gsub("\"", "") .. " = i3.get(" .. a .. ")"
|
||||
end)
|
||||
|
||||
data = data:gsub("([%w_]+)%(", function(a)
|
||||
if fs_elements[a] then
|
||||
return fmt("fs('%s',", a)
|
||||
end
|
||||
end)
|
||||
|
||||
for op, func in pairs(operators) do
|
||||
data = data:gsub("(" .. var .. "+)%s?" .. op .. "%s?(" .. var .. "*)", func)
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
local function _load(path, line, data, t)
|
||||
if line then
|
||||
if not t then
|
||||
t = split(data, "\n")
|
||||
end
|
||||
t[line] = t[line]:gsub("(" .. var .. "+)%s?=%s?(" .. var .. "*)", "%2")
|
||||
data = table.concat(t, "\n")
|
||||
else
|
||||
local file = assert(io.open(path, "r"))
|
||||
data = file:read"*a"
|
||||
file:close()
|
||||
data = compile(data)
|
||||
end
|
||||
|
||||
local l, err = loadstring(data)
|
||||
|
||||
if not l then
|
||||
local err_line = tonumber(err:match(":(%d+):"))
|
||||
|
||||
if line ~= err_line then
|
||||
return _load(path, err_line, data, t)
|
||||
end
|
||||
end
|
||||
|
||||
return l, err
|
||||
end
|
||||
|
||||
return function(path)
|
||||
return _load(path) or loadfile(path)
|
||||
end
|
Reference in New Issue
Block a user