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 script = ""
|
||||
local f = io.open(file, "r")
|
||||
local f = assert(io.open(file, "r"))
|
||||
coroutine.yield([[
|
||||
local output = {}
|
||||
output = {}
|
||||
function output:literal(x)
|
||||
table.insert(self, x)
|
||||
end
|
||||
|
|
@ -14,7 +13,7 @@ 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
|
||||
|
|
@ -46,7 +45,7 @@ end
|
|||
|
||||
local function outputmpp(file)
|
||||
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
|
||||
f:write(line)
|
||||
end
|
||||
|
|
@ -55,12 +54,14 @@ end
|
|||
function mpp.execute(files)
|
||||
local outputs = {}
|
||||
for i,file in ipairs(files) do
|
||||
outputmpp(file .. ".mpp")
|
||||
print("executing file " .. file)
|
||||
-- outputmpp(file .. ".mpp")
|
||||
outputs[i] = loadmpp(file .. ".mpp")()
|
||||
end
|
||||
for i,output in ipairs(outputs) do
|
||||
local file = io.open(files[i], "w")
|
||||
for j, o in ipairs(output) 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
|
||||
|
|
@ -71,6 +72,33 @@ function mpp.execute(files)
|
|||
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{ "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