diff options
Diffstat (limited to 'util/generate-binding.lua')
| -rw-r--r-- | util/generate-binding.lua | 147 | 
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 | 
