init
This commit is contained in:
745
sdk/tolua++/lua/function.lua
Normal file
745
sdk/tolua++/lua/function.lua
Normal file
@@ -0,0 +1,745 @@
|
||||
-- tolua: function class
|
||||
-- Written by Waldemar Celes
|
||||
-- TeCGraf/PUC-Rio
|
||||
-- Jul 1998
|
||||
-- $Id: function.lua 997 2006-02-23 19:12:50Z lindquist $
|
||||
|
||||
-- This code is free software; you can redistribute it and/or modify it.
|
||||
-- The software provided hereunder is on an "as is" basis, and
|
||||
-- the author has no obligation to provide maintenance, support, updates,
|
||||
-- enhancements, or modifications.
|
||||
|
||||
|
||||
-- CEGUILua mod
|
||||
-- exception handling
|
||||
-- patch from Tov
|
||||
-- modded by Lindquist
|
||||
exceptionDefs = exceptionDefs or {}
|
||||
exceptionDefs["std::exception"] = {}
|
||||
exceptionDefs["std::exception"]["var"] = "&e"
|
||||
exceptionDefs["std::exception"]["c_str"] = "e.what()"
|
||||
|
||||
exceptionDefs["any"] = {}
|
||||
exceptionDefs["any"]["var"] = ""
|
||||
exceptionDefs["any"]["c_str"] = '"Unknown"'
|
||||
|
||||
exceptionMessageBufferSize = 512
|
||||
|
||||
function outputExceptionError(f,e,errBuf)
|
||||
-- if the exception is not "..." then use the "c_str" info the get a real exception message
|
||||
local messageC_str = true
|
||||
if e.name == "any" then
|
||||
messageC_str = false
|
||||
end
|
||||
|
||||
-- make a default e.ret if empty
|
||||
if not e.ret or e.ret == "" then
|
||||
e.ret = "nil,message"
|
||||
end
|
||||
|
||||
-- create a default exceptionDef if we dont have one
|
||||
if not exceptionDefs[e.name] then
|
||||
exceptionDefs[e.name] = {}
|
||||
exceptionDefs[e.name].var = "&e"
|
||||
exceptionDefs[e.name].c_str = '"Unknown"'
|
||||
end
|
||||
|
||||
-- print catch header
|
||||
local nameToEcho = e.name
|
||||
if nameToEcho == "any" then
|
||||
nameToEcho = "..."
|
||||
end
|
||||
output("catch(",nameToEcho,exceptionDefs[e.name].var,")\n{\n")
|
||||
|
||||
-- if just a nil
|
||||
if e.ret == "nil" then
|
||||
output("return 0;\n")
|
||||
-- if error should be raised
|
||||
elseif string.find(e.ret,"error") then
|
||||
if messageC_str then
|
||||
output("snprintf(errorBuffer,"..exceptionMessageBufferSize..",\"Exception of type '"..e.name.."' was thrown by function '"..f.."'\\nMessage: %s\","..exceptionDefs[e.name].c_str..");\n")
|
||||
else
|
||||
output("snprintf(errorBuffer,"..exceptionMessageBufferSize..",\"Unknown exception thrown by function '"..f.."'\");\n")
|
||||
end
|
||||
output("errorDoIt = true;\n")
|
||||
-- else go through the returns
|
||||
else
|
||||
-- buffer for message
|
||||
if string.find(e.ret,"message") and messageC_str and errBuf == false then
|
||||
output("char errorBuffer["..exceptionMessageBufferSize.."];\n")
|
||||
end
|
||||
local numrets = 0
|
||||
local retpat = "(%w+),?"
|
||||
local i,j,retval = string.find(e.ret,retpat)
|
||||
while i do
|
||||
local code = ""
|
||||
|
||||
-- NIL
|
||||
if retval == "nil" then
|
||||
code = "tolua_pushnil(tolua_S);\n"
|
||||
|
||||
-- MESSAGE
|
||||
elseif retval == "message" then
|
||||
if messageC_str then
|
||||
code = "snprintf(errorBuffer,"..exceptionMessageBufferSize..",\"Exception of type '"..e.name.."' was thrown by function '"..f.."'\\nMessage: %s\","..exceptionDefs[e.name].c_str..");\ntolua_pushstring(tolua_S,errorBuffer);\n"
|
||||
else
|
||||
code = "tolua_pushstring(tolua_S,\"Unknown exception thrown by function '"..f.."'\");\n"
|
||||
end
|
||||
|
||||
-- TRUE
|
||||
elseif retval == "true" then
|
||||
code = "tolua_pushboolean(tolua_S, 1);\n"
|
||||
|
||||
-- FALSE
|
||||
elseif retval == "false" then
|
||||
code = "tolua_pushboolean(tolua_S, 0);\n"
|
||||
end
|
||||
|
||||
-- print code for this return value
|
||||
if code ~= "" then
|
||||
output(code)
|
||||
numrets = numrets + 1
|
||||
end
|
||||
|
||||
-- next return value
|
||||
i,j,retval = string.find(e.ret,retpat,j+1)
|
||||
end
|
||||
output("return ",numrets,";\n")
|
||||
end
|
||||
|
||||
-- print catch footer
|
||||
output("}\n")
|
||||
end
|
||||
|
||||
function outputExceptionCatchBlocks(func,throws,err)
|
||||
for i=1,table.getn(throws) do
|
||||
outputExceptionError(func, throws[i], err)
|
||||
end
|
||||
|
||||
-- if an error should be raised, we do it here
|
||||
if err then
|
||||
output("if (errorDoIt) {\n")
|
||||
output("luaL_error(tolua_S,errorBuffer);\n")
|
||||
output("}\n")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Function class
|
||||
-- Represents a function or a class method.
|
||||
-- The following fields are stored:
|
||||
-- mod = type modifiers
|
||||
-- type = type
|
||||
-- ptr = "*" or "&", if representing a pointer or a reference
|
||||
-- name = name
|
||||
-- lname = lua name
|
||||
-- args = list of argument declarations
|
||||
-- const = if it is a method receiving a const "this".
|
||||
classFunction = {
|
||||
mod = '',
|
||||
type = '',
|
||||
ptr = '',
|
||||
name = '',
|
||||
args = {n=0},
|
||||
const = '',
|
||||
}
|
||||
classFunction.__index = classFunction
|
||||
setmetatable(classFunction,classFeature)
|
||||
|
||||
-- declare tags
|
||||
function classFunction:decltype ()
|
||||
self.type = typevar(self.type)
|
||||
if strfind(self.mod,'const') then
|
||||
self.type = 'const '..self.type
|
||||
self.mod = gsub(self.mod,'const','')
|
||||
end
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
self.args[i]:decltype()
|
||||
i = i+1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Write binding function
|
||||
-- Outputs C/C++ binding function.
|
||||
function classFunction:supcode (local_constructor)
|
||||
|
||||
local overload = strsub(self.cname,-2,-1) - 1 -- indicate overloaded func
|
||||
local nret = 0 -- number of returned values
|
||||
local class = self:inclass()
|
||||
local _,_,static = strfind(self.mod,'^%s*(static)')
|
||||
if class then
|
||||
|
||||
if self.name == 'new' and self.parent.flags.pure_virtual then
|
||||
-- no constructor for classes with pure virtual methods
|
||||
return
|
||||
end
|
||||
|
||||
if local_constructor then
|
||||
output("/* method: new_local of class ",class," */")
|
||||
else
|
||||
output("/* method:",self.name," of class ",class," */")
|
||||
end
|
||||
else
|
||||
output("/* function:",self.name," */")
|
||||
end
|
||||
|
||||
if local_constructor then
|
||||
output("#ifndef TOLUA_DISABLE_"..self.cname.."_local")
|
||||
output("\nstatic int",self.cname.."_local","(lua_State* tolua_S)")
|
||||
else
|
||||
output("#ifndef TOLUA_DISABLE_"..self.cname)
|
||||
output("\nstatic int",self.cname,"(lua_State* tolua_S)")
|
||||
end
|
||||
|
||||
--
|
||||
-- modify tolua++, miros 2011-03-04
|
||||
-- suport function raw export directly
|
||||
--
|
||||
if #self.args == 1 and self.type == "int" and self.args[1].type == "lua_State*" then
|
||||
output("{\n\treturn "..self.name.."(tolua_S);\n}\n#endif //#ifndef TOLUA_DISABLE\n\n")
|
||||
return
|
||||
end
|
||||
--
|
||||
-- end modify
|
||||
--
|
||||
|
||||
output("{")
|
||||
|
||||
-- check types
|
||||
if overload < 0 then
|
||||
output('#ifndef TOLUA_RELEASE\n')
|
||||
end
|
||||
output(' tolua_Error tolua_err;')
|
||||
output(' if (\n')
|
||||
-- check self
|
||||
local narg
|
||||
if class then narg=2 else narg=1 end
|
||||
if class then
|
||||
local func = 'tolua_isusertype'
|
||||
local type = self.parent.type
|
||||
if self.name=='new' or static~=nil then
|
||||
func = 'tolua_isusertable'
|
||||
type = self.parent.type
|
||||
end
|
||||
if self.const ~= '' then
|
||||
type = "const "..type
|
||||
end
|
||||
output(' !'..func..'(tolua_S,1,"'..type..'",0,&tolua_err) ||\n')
|
||||
end
|
||||
-- check args
|
||||
if self.args[1].type ~= 'void' then
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
local btype = isbasic(self.args[i].type)
|
||||
if btype ~= 'value' and btype ~= 'state' then
|
||||
output(' !'..self.args[i]:outchecktype(narg)..' ||\n')
|
||||
end
|
||||
if btype ~= 'state' then
|
||||
narg = narg+1
|
||||
end
|
||||
i = i+1
|
||||
end
|
||||
end
|
||||
-- check end of list
|
||||
output(' !tolua_isnoobj(tolua_S,'..narg..',&tolua_err)\n )')
|
||||
output(' goto tolua_lerror;')
|
||||
|
||||
output(' else\n')
|
||||
if overload < 0 then
|
||||
output('#endif\n')
|
||||
end
|
||||
output(' {')
|
||||
|
||||
-- declare self, if the case
|
||||
local narg
|
||||
if class then narg=2 else narg=1 end
|
||||
if class and self.name~='new' and static==nil then
|
||||
output(' ',self.const,self.parent.type,'*','self = ')
|
||||
output('(',self.const,self.parent.type,'*) ')
|
||||
output('tolua_tousertype(tolua_S,1,0);')
|
||||
elseif static then
|
||||
_,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
|
||||
end
|
||||
-- declare parameters
|
||||
if self.args[1].type ~= 'void' then
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
self.args[i]:declare(narg)
|
||||
if isbasic(self.args[i].type) ~= "state" then
|
||||
narg = narg+1
|
||||
end
|
||||
i = i+1
|
||||
end
|
||||
end
|
||||
|
||||
-- check self
|
||||
if class and self.name~='new' and static==nil then
|
||||
output('#ifndef TOLUA_RELEASE\n')
|
||||
output(' if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
|
||||
output('#endif\n')
|
||||
end
|
||||
|
||||
-- get array element values
|
||||
if class then narg=2 else narg=1 end
|
||||
if self.args[1].type ~= 'void' then
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
self.args[i]:getarray(narg)
|
||||
narg = narg+1
|
||||
i = i+1
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- CEGUILua mod
|
||||
-- init exception handling
|
||||
local throws = false
|
||||
do
|
||||
local pattern = "tolua_throws|.*|"
|
||||
local i,j = string.find(self.mod, pattern)
|
||||
if i then
|
||||
throws = {}
|
||||
table.setn(throws,0)
|
||||
local excepts = string.sub(self.mod, i+12,j)
|
||||
local epattern = "|.-|"
|
||||
local i,j = string.find(excepts, epattern)
|
||||
while i do
|
||||
local e = string.sub(excepts,i+1,j-1)
|
||||
local _,_,name,rest = string.find(e, "([%w:_]+),?(.*)")
|
||||
table.insert(throws,{name=name, ret=rest})
|
||||
i,j = string.find(excepts, epattern, j)
|
||||
end
|
||||
self.mod = string.gsub(self.mod, pattern, "")
|
||||
end
|
||||
end
|
||||
local exRaiseError = false
|
||||
--------------------------------------------------
|
||||
|
||||
local out = string.find(self.mod, "tolua_outside")
|
||||
|
||||
---------------
|
||||
-- CEGUILua mod
|
||||
-- remove "tolua_outside" from self.mod
|
||||
if out then
|
||||
self.mod = string.gsub(self.mod, "tolua_outside", "")
|
||||
end
|
||||
|
||||
-- call function
|
||||
if class and self.name=='delete' then
|
||||
output(' delete self;')
|
||||
elseif class and self.name == 'operator&[]' then
|
||||
if flags['1'] then -- for compatibility with tolua5 ?
|
||||
output(' self->operator[](',self.args[1].name,'-1) = ',self.args[2].name,';')
|
||||
else
|
||||
output(' self->operator[](',self.args[1].name,') = ',self.args[2].name,';')
|
||||
end
|
||||
else
|
||||
-- CEGUILua mod begin- throws
|
||||
if throws then
|
||||
for i=1,table.getn(throws) do
|
||||
if string.find(throws[i].ret, "error") then
|
||||
output("char errorBuffer["..exceptionMessageBufferSize.."];\n")
|
||||
output("bool errorDoIt = false;\n")
|
||||
exRaiseError = true
|
||||
break
|
||||
end
|
||||
end
|
||||
output("try\n")
|
||||
end
|
||||
-- CEGUILua mod end - throws
|
||||
output(' {')
|
||||
if self.type ~= '' and self.type ~= 'void' then
|
||||
output(' ',self.mod,self.type,self.ptr,'tolua_ret = ')
|
||||
output('(',self.mod,self.type,self.ptr,') ')
|
||||
else
|
||||
output(' ')
|
||||
end
|
||||
if class and self.name=='new' then
|
||||
output('new',self.type,'(')
|
||||
elseif class and static then
|
||||
if out then
|
||||
output(self.name,'(')
|
||||
else
|
||||
output(class..'::'..self.name,'(')
|
||||
end
|
||||
elseif class then
|
||||
if out then
|
||||
output(self.name,'(')
|
||||
else
|
||||
if self.cast_operator then
|
||||
output('static_cast<',self.mod,self.type,self.ptr,'>(*self')
|
||||
else
|
||||
output('self->'..self.name,'(')
|
||||
end
|
||||
end
|
||||
else
|
||||
output(self.name,'(')
|
||||
end
|
||||
|
||||
if out and not static then
|
||||
output('self')
|
||||
if self.args[1] and self.args[1].name ~= '' then
|
||||
output(',')
|
||||
end
|
||||
end
|
||||
-- write parameters
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
self.args[i]:passpar()
|
||||
i = i+1
|
||||
if self.args[i] then
|
||||
output(',')
|
||||
end
|
||||
end
|
||||
|
||||
if class and self.name == 'operator[]' and flags['1'] then
|
||||
output('-1);')
|
||||
else
|
||||
output(');')
|
||||
end
|
||||
|
||||
-- return values
|
||||
if self.type ~= '' and self.type ~= 'void' then
|
||||
nret = nret + 1
|
||||
local t,ct = isbasic(self.type)
|
||||
if t then
|
||||
if self.cast_operator and _basic_raw_push[t] then
|
||||
output(' ',_basic_raw_push[t],'(tolua_S,(',ct,')tolua_ret);')
|
||||
elseif self.type == 'String' then
|
||||
output(' tolua_push'..t..'(tolua_S,(',ct,')tolua_ret.to_char());')
|
||||
else
|
||||
output(' tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);')
|
||||
end
|
||||
else
|
||||
t = self.type
|
||||
new_t = string.gsub(t, "const%s+", "")
|
||||
if self.ptr == '' then
|
||||
output(' {')
|
||||
output('#ifdef __cplusplus\n')
|
||||
output(' void* tolua_obj = new',new_t,'(tolua_ret);')
|
||||
output(' tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
|
||||
output('#else\n')
|
||||
output(' void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
|
||||
output(' tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
|
||||
output('#endif\n')
|
||||
output(' }')
|
||||
elseif self.ptr == '&' then
|
||||
output(' tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
|
||||
else
|
||||
if local_constructor then
|
||||
output(' tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
|
||||
else
|
||||
output(' tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
nret = nret + self.args[i]:retvalue()
|
||||
i = i+1
|
||||
end
|
||||
output(' }')
|
||||
|
||||
------------------------------------------
|
||||
-- CEGUILua mod
|
||||
-- finish exception handling
|
||||
-- catch
|
||||
if throws then
|
||||
outputExceptionCatchBlocks(self.name, throws, exRaiseError)
|
||||
end
|
||||
------------------------------------------
|
||||
|
||||
-- set array element values
|
||||
if class then narg=2 else narg=1 end
|
||||
if self.args[1].type ~= 'void' then
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
self.args[i]:setarray(narg)
|
||||
narg = narg+1
|
||||
i = i+1
|
||||
end
|
||||
end
|
||||
|
||||
-- free dynamically allocated array
|
||||
if self.args[1].type ~= 'void' then
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
self.args[i]:freearray()
|
||||
i = i+1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
output(' }')
|
||||
output(' return '..nret..';')
|
||||
|
||||
-- call overloaded function or generate error
|
||||
if overload < 0 then
|
||||
|
||||
output('#ifndef TOLUA_RELEASE\n')
|
||||
output('tolua_lerror:\n')
|
||||
output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
|
||||
output(' return 0;')
|
||||
output('#endif\n')
|
||||
else
|
||||
local _local = ""
|
||||
if local_constructor then
|
||||
_local = "_local"
|
||||
end
|
||||
output('tolua_lerror:\n')
|
||||
output(' return '..strsub(self.cname,1,-3)..format("%02d",overload).._local..'(tolua_S);')
|
||||
end
|
||||
output('}')
|
||||
output('#endif //#ifndef TOLUA_DISABLE\n')
|
||||
output('\n')
|
||||
|
||||
-- recursive call to write local constructor
|
||||
if class and self.name=='new' and not local_constructor then
|
||||
|
||||
self:supcode(1)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- register function
|
||||
function classFunction:register (pre)
|
||||
|
||||
if not self:check_public_access() then
|
||||
return
|
||||
end
|
||||
|
||||
if self.name == 'new' and self.parent.flags.pure_virtual then
|
||||
-- no constructor for classes with pure virtual methods
|
||||
return
|
||||
end
|
||||
|
||||
output(pre..'tolua_function(tolua_S,"'..self.lname..'",'..self.cname..');')
|
||||
if self.name == 'new' then
|
||||
output(pre..'tolua_function(tolua_S,"new_local",'..self.cname..'_local);')
|
||||
output(pre..'tolua_function(tolua_S,".call",'..self.cname..'_local);')
|
||||
--output(' tolua_set_call_event(tolua_S,'..self.cname..'_local, "'..self.parent.type..'");')
|
||||
end
|
||||
end
|
||||
|
||||
-- Print method
|
||||
function classFunction:print (ident,close)
|
||||
print(ident.."Function{")
|
||||
print(ident.." mod = '"..self.mod.."',")
|
||||
print(ident.." type = '"..self.type.."',")
|
||||
print(ident.." ptr = '"..self.ptr.."',")
|
||||
print(ident.." name = '"..self.name.."',")
|
||||
print(ident.." lname = '"..self.lname.."',")
|
||||
print(ident.." const = '"..self.const.."',")
|
||||
print(ident.." cname = '"..self.cname.."',")
|
||||
print(ident.." lname = '"..self.lname.."',")
|
||||
print(ident.." args = {")
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
self.args[i]:print(ident.." ",",")
|
||||
i = i+1
|
||||
end
|
||||
print(ident.." }")
|
||||
print(ident.."}"..close)
|
||||
end
|
||||
|
||||
-- check if it returns an object by value
|
||||
function classFunction:requirecollection (t)
|
||||
local r = false
|
||||
if self.type ~= '' and not isbasic(self.type) and self.ptr=='' then
|
||||
local type = gsub(self.type,"%s*const%s+","")
|
||||
t[type] = "tolua_collect_" .. clean_template(type)
|
||||
r = true
|
||||
end
|
||||
local i=1
|
||||
while self.args[i] do
|
||||
r = self.args[i]:requirecollection(t) or r
|
||||
i = i+1
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
-- determine lua function name overload
|
||||
function classFunction:overload ()
|
||||
return self.parent:overload(self.lname)
|
||||
end
|
||||
|
||||
|
||||
function param_object(par) -- returns true if the parameter has an object as its default value
|
||||
|
||||
if not string.find(par, '=') then return false end -- it has no default value
|
||||
|
||||
local _,_,def = string.find(par, "=(.*)$")
|
||||
|
||||
if string.find(par, "|") then -- a list of flags
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if string.find(par, "%*") then -- it's a pointer with a default value
|
||||
|
||||
if string.find(par, '=%s*new') then -- it's a pointer with an instance as default parameter.. is that valid?
|
||||
return true
|
||||
end
|
||||
return false -- default value is 'NULL' or something
|
||||
end
|
||||
|
||||
|
||||
if string.find(par, "[%(&]") then
|
||||
return true
|
||||
end -- default value is a constructor call (most likely for a const reference)
|
||||
|
||||
--if string.find(par, "&") then
|
||||
|
||||
-- if string.find(def, ":") or string.find(def, "^%s*new%s+") then
|
||||
|
||||
-- -- it's a reference with default to something like Class::member, or 'new Class'
|
||||
-- return true
|
||||
-- end
|
||||
--end
|
||||
|
||||
return false -- ?
|
||||
end
|
||||
|
||||
function strip_last_arg(all_args, last_arg) -- strips the default value from the last argument
|
||||
|
||||
local _,_,s_arg = string.find(last_arg, "^([^=]+)")
|
||||
last_arg = string.gsub(last_arg, "([%%%(%)])", "%%%1");
|
||||
all_args = string.gsub(all_args, "%s*,%s*"..last_arg.."%s*%)%s*$", ")")
|
||||
return all_args, s_arg
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Internal constructor
|
||||
function _Function (t)
|
||||
setmetatable(t,classFunction)
|
||||
|
||||
if t.const ~= 'const' and t.const ~= '' then
|
||||
error("#invalid 'const' specification")
|
||||
end
|
||||
|
||||
append(t)
|
||||
if t:inclass() then
|
||||
--print ('t.name is '..t.name..', parent.name is '..t.parent.name)
|
||||
if string.gsub(t.name, "%b<>", "") == string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
|
||||
t.name = 'new'
|
||||
t.lname = 'new'
|
||||
t.parent._new = true
|
||||
t.type = t.parent.name
|
||||
t.ptr = '*'
|
||||
elseif string.gsub(t.name, "%b<>", "") == '~'..string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
|
||||
t.name = 'delete'
|
||||
t.lname = 'delete'
|
||||
t.parent._delete = true
|
||||
end
|
||||
end
|
||||
t.cname = t:cfuncname("tolua")..t:overload(t)
|
||||
return t
|
||||
end
|
||||
|
||||
-- Constructor
|
||||
-- Expects three strings: one representing the function declaration,
|
||||
-- another representing the argument list, and the third representing
|
||||
-- the "const" or empty string.
|
||||
function Function (d,a,c)
|
||||
--local t = split(strsub(a,2,-2),',') -- eliminate braces
|
||||
--local t = split_params(strsub(a,2,-2))
|
||||
|
||||
if not flags['W'] and string.find(a, "%.%.%.%s*%)") then
|
||||
|
||||
warning("Functions with variable arguments (`...') are not supported. Ignoring "..d..a..c)
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
local i=1
|
||||
local l = {n=0}
|
||||
|
||||
a = string.gsub(a, "%s*([%(%)])%s*", "%1")
|
||||
local t,strip,last = strip_pars(strsub(a,2,-2));
|
||||
if strip then
|
||||
--local ns = string.sub(strsub(a,1,-2), 1, -(string.len(last)+1))
|
||||
local ns = join(t, ",", 1, last-1)
|
||||
|
||||
ns = "("..string.gsub(ns, "%s*,%s*$", "")..')'
|
||||
--ns = strip_defaults(ns)
|
||||
|
||||
Function(d, ns, c)
|
||||
for i=1,last do
|
||||
t[i] = string.gsub(t[i], "=.*$", "")
|
||||
end
|
||||
end
|
||||
|
||||
while t[i] do
|
||||
l.n = l.n+1
|
||||
l[l.n] = Declaration(t[i],'var',true)
|
||||
i = i+1
|
||||
end
|
||||
local f = Declaration(d,'func')
|
||||
f.args = l
|
||||
f.const = c
|
||||
return _Function(f)
|
||||
end
|
||||
|
||||
function join(t, sep, first, last)
|
||||
|
||||
first = first or 1
|
||||
last = last or table.getn(t)
|
||||
local lsep = ""
|
||||
local ret = ""
|
||||
local loop = false
|
||||
for i = first,last do
|
||||
|
||||
ret = ret..lsep..t[i]
|
||||
lsep = sep
|
||||
loop = true
|
||||
end
|
||||
if not loop then
|
||||
return ""
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function strip_pars(s)
|
||||
|
||||
local t = split_c_tokens(s, ',')
|
||||
local strip = false
|
||||
local last
|
||||
|
||||
for i=t.n,1,-1 do
|
||||
|
||||
if not strip and param_object(t[i]) then
|
||||
last = i
|
||||
strip = true
|
||||
end
|
||||
--if strip then
|
||||
-- t[i] = string.gsub(t[i], "=.*$", "")
|
||||
--end
|
||||
end
|
||||
|
||||
return t,strip,last
|
||||
|
||||
end
|
||||
|
||||
function strip_defaults(s)
|
||||
|
||||
s = string.gsub(s, "^%(", "")
|
||||
s = string.gsub(s, "%)$", "")
|
||||
|
||||
local t = split_c_tokens(s, ",")
|
||||
local sep, ret = "",""
|
||||
for i=1,t.n do
|
||||
t[i] = string.gsub(t[i], "=.*$", "")
|
||||
ret = ret..sep..t[i]
|
||||
sep = ","
|
||||
end
|
||||
|
||||
return "("..ret..")"
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user