Add hooks and C structs
This commit is contained in:
parent
68e979fcec
commit
19111b5aeb
|
|
@ -0,0 +1,30 @@
|
||||||
|
local c = {}
|
||||||
|
|
||||||
|
function c.struct(name, fields_init)
|
||||||
|
local fields = fields_init or {}
|
||||||
|
local struct = {}
|
||||||
|
output:expression(function()
|
||||||
|
local s = "struct " .. name .. " {\n"
|
||||||
|
for _,v in pairs(fields) do
|
||||||
|
s = s .. "\t" .. v .. ";\n"
|
||||||
|
end
|
||||||
|
return s.. "};\n"
|
||||||
|
end)
|
||||||
|
setmetatable(struct, {
|
||||||
|
__index = fields,
|
||||||
|
__newindex = function(self, key, value)
|
||||||
|
if self[key] and self[key] ~= value then
|
||||||
|
error("Conflicting defintions of " .. name .. "." .. key .. ":\n\t'" .. self[key] .. "'\n\t'" .. value .. "'");
|
||||||
|
else
|
||||||
|
fields[key] = value
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
__tostring = function()
|
||||||
|
return "struct " .. name
|
||||||
|
end
|
||||||
|
})
|
||||||
|
_G[name] = struct
|
||||||
|
return struct
|
||||||
|
end
|
||||||
|
|
||||||
|
return c
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@function linkedlist(T, plugins)
|
||||||
|
@local l = mpp.c.struct("linkedlist_" .. T)
|
||||||
|
@local hooks = mpp.hooks()
|
||||||
|
@l.value = T.." value"
|
||||||
|
@l.next = tostring(l) .. " *next"
|
||||||
|
|
||||||
|
$T$ *ll_$T$_index(struct linkedlist_$T$ *list, size_t index) {
|
||||||
|
while(index > 0) {
|
||||||
|
if(!list->next) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &list->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct linkedlist_$T$ ll_$T$_cons($T$ value, struct linkedlist_$T$ *tail) {
|
||||||
|
struct linkedlist_$T$ l;
|
||||||
|
l.value = value;
|
||||||
|
l.next = tail;
|
||||||
|
@hooks("cons")
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
@for _,plugin in ipairs(plugins or {}) do plugin(T, l, hooks) end
|
||||||
|
@end
|
||||||
|
|
||||||
|
@function linkedlist_len_naive(T, l, hooks)
|
||||||
|
size_t ll_$T$_len(struct linkedlist_$T$ *list) {
|
||||||
|
size_t len = 0;
|
||||||
|
for(; list; len++) {
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@function linkedlist_len_cached(T, l, hooks)
|
||||||
|
@l.size = "size_t size"
|
||||||
|
@hooks.cons("l.size = tail ? tail->size + 1 : 1;")
|
||||||
|
size_t ll_$T$_len(struct linkedlist_$T$ *list) {
|
||||||
|
return list->size;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@linkedlist("int", {linkedlist_len_naive})
|
||||||
|
@linkedlist("float", {linkedlist_len_cached})
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
@mpp.c.struct("stats")
|
||||||
|
@function counter(name) stats[name] = "size_t " .. name end
|
||||||
|
struct stats stats;
|
||||||
|
|
||||||
|
@function sum_t(type, base)
|
||||||
|
@local base = base or 0
|
||||||
|
$type$ sum_$type$($type$ *xs, size_t len) {
|
||||||
|
$type$ sum = $base$;
|
||||||
|
for(size_t i = 0; i < len; i++) {
|
||||||
|
@counter("summed" .. type)
|
||||||
|
stats.summed$type$++;
|
||||||
|
sum += xs[i];
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@sum_t("int")
|
||||||
|
@sum_t("float")
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int xs[3] = {1, strlen("foo"), strlen("bar")};
|
||||||
|
int x = sum_int(xs, 3);
|
||||||
|
float ys[3] = {1.0, 3.14, 9.81};
|
||||||
|
float y = sum_float(ys, 3);
|
||||||
|
printf("%i %f\n", x, y);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
50
init.lua
50
init.lua
|
|
@ -1,12 +1,11 @@
|
||||||
local mpp = {}
|
mpp = {}
|
||||||
|
|
||||||
local output = {}
|
mpp.c = require "c"
|
||||||
|
|
||||||
local function process(file)
|
local function process(file)
|
||||||
local script = ""
|
local f = assert(io.open(file, "r"))
|
||||||
local f = io.open(file, "r")
|
|
||||||
coroutine.yield([[
|
coroutine.yield([[
|
||||||
local output = {}
|
output = {}
|
||||||
function output:literal(x)
|
function output:literal(x)
|
||||||
table.insert(self, x)
|
table.insert(self, x)
|
||||||
end
|
end
|
||||||
|
|
@ -14,7 +13,7 @@ function output:expression(f)
|
||||||
table.insert(self, f)
|
table.insert(self, f)
|
||||||
end
|
end
|
||||||
]])
|
]])
|
||||||
|
|
||||||
for line in f:lines() do
|
for line in f:lines() do
|
||||||
if line:find("^%s-" .. mpp.directive) then
|
if line:find("^%s-" .. mpp.directive) then
|
||||||
-- Line starts with MPP directive
|
-- Line starts with MPP directive
|
||||||
|
|
@ -46,7 +45,7 @@ end
|
||||||
|
|
||||||
local function outputmpp(file)
|
local function outputmpp(file)
|
||||||
local generator = coroutine.wrap(function() process(file) end)
|
local generator = coroutine.wrap(function() process(file) end)
|
||||||
local f = io.open(file .. ".lua", "w")
|
local f = assert(io.open(file .. ".lua", "w"))
|
||||||
for line in generator do
|
for line in generator do
|
||||||
f:write(line)
|
f:write(line)
|
||||||
end
|
end
|
||||||
|
|
@ -55,12 +54,14 @@ end
|
||||||
function mpp.execute(files)
|
function mpp.execute(files)
|
||||||
local outputs = {}
|
local outputs = {}
|
||||||
for i,file in ipairs(files) do
|
for i,file in ipairs(files) do
|
||||||
outputmpp(file .. ".mpp")
|
print("executing file " .. file)
|
||||||
|
-- outputmpp(file .. ".mpp")
|
||||||
outputs[i] = loadmpp(file .. ".mpp")()
|
outputs[i] = loadmpp(file .. ".mpp")()
|
||||||
end
|
end
|
||||||
for i,output in ipairs(outputs) do
|
for i,output in ipairs(outputs) do
|
||||||
local file = io.open(files[i], "w")
|
print("outputting file " .. files[i])
|
||||||
for j, o in ipairs(output) do
|
local file = assert(io.open(files[i], "w"))
|
||||||
|
for _, o in ipairs(output) do
|
||||||
if type(o) == "string" then
|
if type(o) == "string" then
|
||||||
file:write(o)
|
file:write(o)
|
||||||
elseif type(o) == "function" then
|
elseif type(o) == "function" then
|
||||||
|
|
@ -71,6 +72,33 @@ function mpp.execute(files)
|
||||||
end
|
end
|
||||||
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.directive = "@"
|
||||||
mpp.execute{ "template.c" }
|
-- mpp.execute{ "examples/template.c" }
|
||||||
|
mpp.execute{"examples/linkedlist.c"}
|
||||||
|
|
|
||||||
18
template.c
18
template.c
|
|
@ -1,18 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int sum_int(int *xs, size_t len) {
|
|
||||||
int sum = 0;
|
|
||||||
for(size_t i = 0; i < len; i++) {
|
|
||||||
sum += xs[i];
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x = sum_int({strlen("foo"), strlen("bar")});
|
|
||||||
printf("%i\n", x)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
@print("foo")
|
|
||||||
|
|
||||||
@function sum_t(type, base)
|
|
||||||
@local base = base or 0
|
|
||||||
int sum_$type$($type$ *xs, size_t len) {
|
|
||||||
$type$ sum = $base$;
|
|
||||||
for(size_t i = 0; i < len; i++) {
|
|
||||||
sum += xs[i];
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@sum_t("int")
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int x = sum_int({strlen("foo"), strlen("bar")});
|
|
||||||
printf("%i\n", x)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue