diff options
Diffstat (limited to 'ThirdParty/tolua-5.2.4/src/bin/lua-5.0/function.lua')
-rw-r--r-- | ThirdParty/tolua-5.2.4/src/bin/lua-5.0/function.lua | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/ThirdParty/tolua-5.2.4/src/bin/lua-5.0/function.lua b/ThirdParty/tolua-5.2.4/src/bin/lua-5.0/function.lua new file mode 100644 index 0000000..d748bc0 --- /dev/null +++ b/ThirdParty/tolua-5.2.4/src/bin/lua-5.0/function.lua @@ -0,0 +1,363 @@ +-- tolua: function class +-- Written by Waldemar Celes +-- TeCGraf/PUC-Rio +-- Jul 1998 +-- $Id: function.lua,v 1.1 2009-07-09 13:44:04 fabraham Exp $ + +-- 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. + + + +-- 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%s*','') + 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 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 + output("/* method:",self.name," of class ",class," */") + else + output("/* function:",self.name," */") + end + output("static int",self.cname,"(lua_State* tolua_S)") + 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.const ~= '' then + type = self.const .. " " .. type + end + if self.name=='new' or static~=nil then + func = 'tolua_isusertable' + type = self.parent.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 ~= 'state' then + output(' !'..self.args[i]:outchecktype(narg,false)..' ||\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 + + -- call function + if class and self.name=='delete' then + output(' tolua_release(tolua_S,self);') + output(' delete self;') + elseif class and self.name == 'operator&[]' then + output(' self->operator[](',self.args[1].name,'-1) = ',self.args[2].name,';') + else + output(' {') + if self.type ~= '' and self.type ~= 'void' then + local ctype = self.type + if ctype == 'value' or ctype == 'function' then + ctype = 'int' + end + output(' ',self.mod,ctype,self.ptr,'tolua_ret = ') + if isbasic(self.type) or self.ptr ~= '' then + output('(',self.mod,ctype,self.ptr,') ') + end + else + output(' ') + end + if class and self.name=='new' then + output('new',self.type,'(') + elseif class and static then + output(class..'::'..self.name,'(') + elseif class then + output('self->'..self.name,'(') + else + output(self.name,'(') + 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[]' 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 t=='function' then t='value' end + output(' tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);') + else + t = self.type + if self.ptr == '' then + output(' {') + output('#ifdef __cplusplus\n') + output(' void* tolua_obj = new',t,'(tolua_ret);') + output(' tolua_pushusertype(tolua_S,tolua_clone(tolua_S,tolua_obj,'.. (_collect[t] or 'NULL') ..'),"',t,'");') + output('#else\n') + output(' void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));') + output(' tolua_pushusertype(tolua_S,tolua_clone(tolua_S,tolua_obj,NULL),"',t,'");') + output('#endif\n') + output(' }') + elseif self.ptr == '&' then + output(' tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");') + else + output(' tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");') + end + end + end + local i=1 + while self.args[i] do + nret = nret + self.args[i]:retvalue() + i = i+1 + end + output(' }') + + -- 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 + output('tolua_lerror:\n') + output(' return '..strsub(self.cname,1,-3)..format("%02d",overload)..'(tolua_S);') + end + output('}') + output('\n') +end + + +-- register function +function classFunction:register () + output(' tolua_function(tolua_S,"'..self.lname..'",'..self.cname..');') +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 a 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_" .. gsub(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 + + + +-- 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 + if t.name == t.parent.name then + t.name = 'new' + t.lname = 'new' + t.type = t.parent.name + t.ptr = '*' + elseif t.name == '~'..t.parent.name 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 i=1 + local l = {n=0} + while t[i] do + l.n = l.n+1 + l[l.n] = Declaration(t[i],'var') + i = i+1 + end + local f = Declaration(d,'func') + f.args = l + f.const = c + return _Function(f) +end + + |