105 lines
2.6 KiB
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"}
|