local h = io.open("types.h", "w")
local c = io.open("types.c", "w")
-local def = io.open("types.def", "r")
+local def = io.open(arg[1] or "types.def", "r")
local function emit_h(str)
h:write(str)
typedef char *String;
typedef struct {
- size_t siz;
+ uint64_t siz;
unsigned char *data;
} ]] .. struct_prefix .. [[Blob;
#include <dragonnet/recv.h>
#endif
-#include <endian.h/endian.h>
+#include <endian.h>
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
return true;
if (buffer->siz < len) {
- fprintf(stderr, "[warning] buffer exhausted (requested bytes: %lu, remaining bytes: %lu)\n", len, buffer->siz);
+ fprintf(stderr, "[warning] buffer exhausted (requested bytes: %zu, remaining bytes: %" PRIu64 ")\n", len, buffer->siz);
return false;
}
-- numeric types
+local numeric_types = {}
+
local function emit_vector(type, l)
local name = "v" .. l .. type
local box = "aabb" .. l .. type
existing_types[box] = true
has_deallocator[box] = false
- local typedef, equals, add, clamp, cmp, scale, mix, write, read, send, recv =
- "", "", "", "", "", "", "", "", "", "", ""
-
- typedef = typedef .. "\t" .. type .. " "
- equals = equals .. "\treturn "
- add = add .. "\treturn (" .. name .. ") {"
- clamp = clamp .. "\treturn (" .. name .. ") {"
- cmp = cmp .. "\tint i;\n"
- scale = scale .. "\treturn (" .. name .. ") {"
- mix = mix .. "\treturn (" .. name .. ") {"
+ local typedef, equals, add, sub, clamp, cmp, scale, mix, write, read, send, recv =
+ "", "", "", "", "", "", "", "", "", "", "", ""
for i, c in ipairs(vector_components[l]) do
local last = i == l
or ", "
)
+ sub = sub
+ .. "a." .. c .. " - "
+ .. "b." .. c ..
+ (last
+ and "};\n"
+ or ", "
+ )
+
clamp = clamp
.. type .. "_clamp("
.. "val." .. c .. ", "
.. "\tif (!" .. type .. "_recv(peer, &val->" .. c .. "))\n\t\treturn false;\n"
end
- emit_h("typedef struct {\n" .. typedef .. "} " .. struct_prefix .. name .. ";\n")
+ emit_h("typedef struct {\n\t" .. type .. " " .. typedef .. "} " .. struct_prefix .. name .. ";\n")
- emit(export_prefix .. "bool " .. name .. "_equals(" .. name .. " a, " .. name .. " b)", "{\n" .. equals .. "}\n\n")
- emit(export_prefix .. name .. " " .. name .. "_add(" .. name .. " a, " .. name .. " b)", "{\n" .. add .. "}\n\n")
- emit(export_prefix .. name .. " " .. name .. "_clamp(" .. name .. " val, " .. name .. " min, " .. name .. " max)", "{\n" .. clamp .. "}\n\n")
- emit(export_prefix .. "int " .. name .. "_cmp(const void *a, const void *b)", "{\n" .. cmp .. "\treturn 0;\n}\n\n")
- emit(export_prefix .. name .. " " .. name .. "_scale(" .. name .. " v, " .. type .. " s)", "{\n" .. scale .. "}\n\n")
+ emit(export_prefix .. "bool " .. name .. "_equals(" .. name .. " a, " .. name .. " b)", "{\n\treturn " .. equals .. "}\n\n")
+ emit(export_prefix .. name .. " " .. name .. "_add(" .. name .. " a, " .. name .. " b)", "{\n\treturn (" .. name .. ") {" .. add .. "}\n\n")
+ emit(export_prefix .. name .. " " .. name .. "_sub(" .. name .. " a, " .. name .. " b)", "{\n\treturn (" .. name .. ") {" .. sub .. "}\n\n")
+ emit(export_prefix .. name .. " " .. name .. "_clamp(" .. name .. " val, " .. name .. " min, " .. name .. " max)", "{\n\treturn (" .. name .. ") {" .. clamp .. "}\n\n")
+ emit(export_prefix .. "int " .. name .. "_cmp(const void *a, const void *b)", "{\n\tint i;\n" .. cmp .. "\treturn 0;\n}\n\n")
+ emit(export_prefix .. name .. " " .. name .. "_scale(" .. name .. " v, " .. type .. " s)", "{\n\treturn (" .. name .. ") {" .. scale .. "}\n\n")
if type:sub(1, 1) == "f" then
- emit(export_prefix .. name .. " " .. name .. "_mix(" .. name .. " a, " .. name .. " b, " .. type .. " f)", "{\n" .. mix .. "}\n\n")
+ emit(export_prefix .. name .. " " .. name .. "_mix(" .. name .. " a, " .. name .. " b, " .. type .. " f)", "{\n\treturn (" .. name .. ") {" .. mix .. "}\n\n")
end
emit(export_prefix .. "void " .. name .. "_write(Blob *buffer, " .. name .. " *val)", "{\n" .. write .. "}\n\n")
local function emit_numeric(class, bits, alias)
local name = class .. bits
+ table.insert(numeric_types, name)
existing_types[name] = true
has_deallocator[name] = false
end
end
+local converters = {}
+
+for l = 2, 4 do
+ converters[l] = ""
+
+ for i, c in ipairs(vector_components[l]) do
+ converters[l] = converters[l]
+ .. "v." .. c ..
+ ((i == l)
+ and "};\n"
+ or ", "
+ )
+ end
+end
+
+for _, from in ipairs(numeric_types) do
+ for _, to in ipairs(numeric_types) do
+ if from ~= to then
+ for i = 2, 4 do
+ local v_from = "v" .. i .. from
+ local v_to = "v" .. i .. to
+
+ emit(export_prefix .. v_to .. " " .. v_from .. "_to_" .. to .. "(" .. v_from .. " v)", "{\n\treturn (" .. v_to .. ") {" .. converters[i] .. "}\n\n")
+ end
+ end
+ end
+end
+
+emit_h("\n")
+
-- string
existing_types.String = true
"", "", "", "", "", ""
for ic, c in ipairs(t.components) do
- typedef = typedef
- .. "\t" .. c.type .. " " .. c.name
+ local type = c.type
+ local type_end = ""
if c.array then
- typedef = typedef
- .. "[" .. table.concat(c.array, "][") .. "]"
+ local indices = {}
+
+ for _, a in ipairs(c.array) do
+ table.insert(indices, 1, a)
+ end
+
+ for _, a in ipairs(indices) do
+ if a == "" then
+ type = "struct { size_t siz; " .. type .. " (*ptr)" .. type_end .. "; }"
+ type_end = ""
+ else
+ type_end = "[" .. a .. "]" .. type_end
+ end
+ end
end
typedef = typedef
- .. ";\n"
+ .. "\t" .. type .. " " .. c.name .. type_end .. ";\n"
local compressed = false
end
end
- local indent = "\t"
- local loop = ""
+ local indent = {
+ free = "\t",
+ write = "\t",
+ read = "\t",
+ send = "\t",
+ recv = "\t",
+ }
+ local loop = {
+ free = "",
+ write = "",
+ read = "",
+ send = "",
+ recv = ""
+ }
+ local loop_end = {
+ free = "",
+ write = "",
+ read = "",
+ send = "",
+ recv = ""
+ }
local index = ""
local array_submit = ""
if c.array then
for ia, a in ipairs(c.array) do
local it = "i" .. ia
+ local siz = a
- loop = loop .. indent .. "for (int " .. it .. " = 0; " .. it .. " < " .. a .. "; " .. it .. "++)\n"
- indent = indent .. "\t"
+ if a == "" then
+ local var = "val->" .. c.name .. index
+ local ptr = var .. ".ptr"
+ siz = var .. ".siz"
- index = index .. "[" .. it .. "]"
+ loop.free = loop.free .. indent.free .. "if (" .. ptr .. ") {\n"
+ loop_end.free = indent.free .. "}\n" .. loop_end.free
+ indent.free = indent.free .. "\t"
+ loop_end.free = indent.free .. "free(" .. ptr .. ");\n" .. loop_end.free
+
+ loop.write = loop.write .. indent.write .. "u64_write(buffer, &" .. siz .. ");\n"
+
+ loop.send = loop.send .. indent.send .. "if (!u64_send(peer, &" .. siz .. ", false))\n"
+ .. indent.send .. "\treturn false;\n"
- array_submit = array_submit .. " && " .. it .. " == " .. a
+ loop.read = loop.read .. indent.read .. "if (!u64_read(buffer, &" .. siz .. "))\n"
+ .. indent.read .. "\treturn false;\n"
+ .. indent.read .. ptr .. " = calloc(" .. siz .. ", sizeof *" .. ptr .. ");\n"
+
+ loop.recv = loop.recv .. indent.recv .. "if (!u64_recv(peer, &" .. siz .. "))\n"
+ .. indent.recv .. "\treturn false;\n"
+ .. indent.recv .. ptr .. " = calloc(" .. siz .. ", sizeof *" .. ptr .. ");\n"
+
+ index = index .. ".ptr"
+ end
+
+ for f in pairs(loop) do
+ loop[f] = loop[f] .. indent[f] .. "for (size_t " .. it .. " = 0; " .. it .. " < " .. siz .. "; " .. it .. "++) {\n"
+ loop_end[f] = indent[f] .. "}\n" .. loop_end[f]
+ indent[f] = indent[f] .. "\t"
+ end
+
+ index = index .. "[" .. it .. "]"
+ array_submit = array_submit .. " && " .. it .. " == " .. siz .. " - 1"
end
end
if has_deallocator[c.type] then
free = free
- .. loop .. indent .. c.type .. "_free(" .. addr .. ");\n"
+ .. loop.free .. indent.free .. c.type .. "_free(" .. addr .. ");\n" .. loop_end.free
end
write = write
- .. loop .. indent .. (compressed
+ .. loop.write .. indent.write .. (compressed
and "raw_write_compressed(buffer, " .. addr .. ", (void *) &" .. c.type .. "_write);\n"
or c.type .. "_write(buffer, " .. addr .. ");\n"
- )
+ ) .. loop_end.write
read = read
- .. loop .. indent .. "if (!" .. (compressed
+ .. loop.read .. indent.read .. "if (!" .. (compressed
and "raw_read_compressed(buffer, " .. addr .. ", (void *) &" .. c.type .. "_read)"
or c.type .. "_read(buffer, " .. addr .. ")"
- ) .. ")\n" .. indent .. "\treturn false;\n"
+ ) .. ")\n" .. indent.read .. "\treturn false;\n" .. loop_end.read
local submit = ic == #t.components and "submit" .. array_submit or "false"
send = send
- .. loop .. indent .. "if (!" .. (compressed
+ .. loop.send .. indent.send .. "if (!" .. (compressed
and "raw_send_compressed(peer, " .. submit .. ", " .. addr .. ", (void *) &" .. c.type .. "_write)"
or c.type .. "_send(peer, " .. submit .. ", " .. addr .. ")"
- ) .. ")\n" .. indent .. "\treturn false;\n"
+ ) .. ")\n" .. indent.send .. "\treturn false;\n" .. loop_end.send
recv = recv
- .. loop .. indent .. "if (!" .. (compressed
+ .. loop.recv .. indent.recv .. "if (!" .. (compressed
and "raw_recv_compressed(peer, " .. addr .. ", (void *) &" .. c.type .. "_read)"
or c.type .. "_recv(peer, " .. addr .. ")"
- ) .. ")\n" .. indent .. "\treturn false;\n"
+ ) .. ")\n" .. indent.recv .. "\treturn false;\n" .. loop_end.recv
end
emit_h("typedef struct {\n" .. typedef .. "} " .. struct_prefix .. t.name .. ";\n")