mpp/init.lua

105 lines
2.6 KiB
Lua

mpp = {}
mpp.c = require "c"
local function process(file)
local f = assert(io.open(file, "r"))
coroutine.yield([[
output = {}
function output:literal(x)
table.insert(self, x)
end
function output:expression(f)
table.insert(self, f)
end
]])
for line in f:lines() do
if line:find("^%s-" .. mpp.directive) then
-- Line starts with MPP directive
-- as such, it contains Lua code.
coroutine.yield(
line:gsub("^(%s-)" .. mpp.directive, " %1", 1))
else
-- Line contains host code
-- do replace inline evaluations
coroutine.yield(
'output:literal("' ..
line
:gsub('\\', '\\\\')
:gsub('"', '\\"')
:gsub('%$(.-)%$', '") output:expression(function() return %1 end) output:literal("')
.. '\\n")'
)
end
coroutine.yield("\n")
end
coroutine.yield("return output")
end
local function loadmpp(file)
local generator = coroutine.wrap(function() process(file) end)
local func = assert(load(generator, file))
return func
end
local function outputmpp(file)
local generator = coroutine.wrap(function() process(file) end)
local f = assert(io.open(file .. ".lua", "w"))
for line in generator do
f:write(line)
end
end
function mpp.execute(files)
local outputs = {}
for i,file in ipairs(files) do
print("executing file " .. file)
-- outputmpp(file .. ".mpp")
outputs[i] = loadmpp(file .. ".mpp")()
end
for i,output in ipairs(outputs) do
print("outputting file " .. files[i])
local file = assert(io.open(files[i], "w"))
for _, o in ipairs(output) do
if type(o) == "string" then
file:write(o)
elseif type(o) == "function" then
file:write(o())
end
end
file:close()
end
end
function mpp.hook()
local hook = {}
setmetatable(hook, {
__call = function(self, code)
table.insert(self, code .. "\n")
end
})
return hook
end
function mpp.hooks()
local hooks = {}
setmetatable(hooks, {
__index = function(self, key)
self[key] = mpp.hook()
return self[key]
end,
__call = function(self, key)
output:expression(function()
return table.concat(self[key])
end)
end,
})
return hooks
end
mpp.directive = "@"
-- mpp.execute{ "examples/template.c" }
mpp.execute{"examples/linkedlist.c"}