summaryrefslogtreecommitdiff
path: root/util/generate-binding.lua
diff options
context:
space:
mode:
Diffstat (limited to 'util/generate-binding.lua')
-rw-r--r--util/generate-binding.lua147
1 files changed, 109 insertions, 38 deletions
diff --git a/util/generate-binding.lua b/util/generate-binding.lua
index 1c5359f..23aa057 100644
--- a/util/generate-binding.lua
+++ b/util/generate-binding.lua
@@ -1,61 +1,132 @@
local b = {}
-setmetatable(b, {__index=G})
+setmetatable(b, {__index=_G})
setfenv(1, b)
---===== enums =====--
-local Enum = {}
--- create a single enum element
-function Enum.new(name, id)
- local self = {
- name = string.upper(name),
- id = id,
- }
- setmetatable(self, Enum)
- return self
-end
--- create multiple enums
-function Enum.new_multi(tbl)
- local enums = {}
- for id, name in ipairs(tbl) do
- table.insert(enums, Enum.new(name, id))
- end
- return enums
+function ExtractFunctionName(signature)
+ return string.match(signature, "([%w_][%w_]*)%s-%(.*%)")
+end
+
+
+function ExtractFunctionType(signature)
+ return string.match(signature, "(.+)%s%s-[%w_]+%s-%(.*%)")
+end
+
+
+local function trimWhitespace(s)
+ s = string.gsub(s, "^%s*", "")
+ s = string.gsub(s, "%s+$", "")
+ return s
end
--- make enums read-only
-function Enum.__newindex(self)
- error("Attempted to set index on Enum")
+
+
+function ExtractFunctionArgs(signature)
+ local args = {}
+ local argStr = string.match(signature, "%((.*)%)")
+ for arg in string.gmatch(argStr, "([^,][^,]*),?") do
+ -- handle pointers (e.g. void *q)
+ arg = string.gsub(arg, "%*", " * ")
+
+ local type = string.match(arg, "(.+)%s%s-[%w_]+")
+ type = string.gsub(type, "%s%s+", " ")
+ type = string.gsub(type, "%* %*", "**")
+ type = trimWhitespace(type)
+
+ local name = string.match(arg, "([%w_]+)%s-,?$")
+ name = trimWhitespace(name)
+ table.insert(args, { type=type, name=name })
+ end
+ return args
end
--- make enums print nicely
-function Enum.__tostring(self)
- return self.name
+
+
+function GetPointerLevel(ctype)
+ local level = 0
+ for _ in string.gmatch(ctype, "%*") do
+ level = level + 1
+ end
+ return level
end
--- allow comparinge enums
-function Enum.__eq(self, other)
- return self.id == other.id
+
+
+function GetLuaType(ctype)
+ -- double (triple, etc) pointers
+ if GetPointerLevel(ctype) > 1 then return "unknown"
+ -- regular pointers
+ elseif GetPointerLevel(ctype) == 1 then
+ -- strings
+ if string.match(ctype, "char") then return "string"
+ else return "unknown" end
+ -- ordinary variables
+ else
+ -- numbers
+ if string.match(ctype, "float$") then return "number"
+ elseif string.match(ctype, "double$") then return "number"
+ -- integers
+ elseif string.match(ctype, "char$") then return "integer"
+ elseif string.match(ctype, "int$") then return "integer"
+ elseif string.match(ctype, "long$") then return "integer"
+ -- void
+ elseif string.match(ctype, "void$") then return "void"
+ -- unknown
+ else return "unknown" end
+ end
end
-local function check_match(string, pattern, rule)
- local match = string.match(string, '^' .. pattern)
- if match then
- return match, rule(match)
+function PullArg(arg, index)
+ local ltype = GetLuaType(arg.type)
+
+ local pull
+ if ltype == "unknown" then
+ pull = string.format("/* get: %s */", arg.type)
+ else
+ pull = string.format("luaL_check%s(L, %d);", ltype, index)
end
+
+ return string.format("%s %s = %s", arg.type, arg.name, pull)
end
-local function append_match(string, pattern, rule,
+function Call(ftype, fname, args)
+ local callArgs = "("
+ for index, arg in ipairs(args) do
+ callArgs = callArgs .. arg.name
+ if index ~= #args then
+ callArgs = callArgs .. ", "
+ end
+ end
+ callArgs = callArgs .. ")"
-local function lex(string)
- for _, typename in ipairs(c_int_types) do
- if (string.sub(string, 1, #typename) == typename) then
- return
+ local ltype = GetLuaType(ftype)
+ if ltype == "void" then
+ return string.format("%s%s;\n\treturn 0;", fname, callArgs)
+ elseif ltype == "unknown" then
+ return string.format(
+ "%s bind_result = %s%s;\n\t/* push result */\n\treturn /* count */;",
+ ftype, fname, callArgs
+ )
+ else
+ return string.format(
+ "%s bind_result = %s%s;\n\tlua_push%s(L, bind_result);\n\treturn 1;",
+ ftype, fname, callArgs, ltype
+ )
end
end
function bind(signature)
-
+ local ftype = ExtractFunctionType(signature)
+ local fname = ExtractFunctionName(signature)
+ local args = ExtractFunctionArgs(signature)
+
+ local result = string.format("int %s_bind(lua_State *L)\n{\n", fname)
+ for index, arg in ipairs(args) do
+ result = result .. "\t" .. PullArg(arg, index) .. "\n"
+ end
+
+ result = result .. "\t" .. Call(ftype, fname, args) .. "\n}"
+ return result
end