-- tolua: operator class -- Written by Waldemar Celes -- TeCGraf/PUC-Rio -- Jul 1998 -- $Id: $ -- 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. -- Operator class -- Represents an operator function or a class operator method. -- It stores the same fields as functions do plus: -- kind = set of character representing the operator (as it appers in C++ code) classOperator = { kind = '', } classOperator.__index = classOperator setmetatable(classOperator,classFunction) -- table to transform operator kind into the appropriate tag method name _TM = { ['+'] = 'add', ['-'] = 'sub', ['*'] = 'mul', ['/'] = 'div', ['<'] = 'lt', ['<='] = 'le', ['=='] = 'eq', ['[]'] = 'geti', ['&[]'] = 'seti', --['->'] = 'flechita', } -- Print method function classOperator:print (ident,close) print(ident.."Operator{") print(ident.." kind = '"..self.kind.."',") print(ident.." mod = '"..self.mod.."',") print(ident.." type = '"..self.type.."',") print(ident.." ptr = '"..self.ptr.."',") print(ident.." name = '"..self.name.."',") 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 function classOperator:supcode_tmp() if not _TM[self.kind] then return classFunction.supcode(self) end -- no overload, no parameters, always inclass output("/* method:",self.name," of class ",self:inclass()," */") output("#ifndef TOLUA_DISABLE_"..self.cname) output("\nstatic int",self.cname,"(lua_State* tolua_S)") if overload < 0 then output('#ifndef TOLUA_RELEASE\n') end output(' tolua_Error tolua_err;') output(' if (\n') -- check self output(' !'..'tolua_isusertype(tolua_S,1,"'..self.parent.type..'",0,&tolua_err) ||\n') output(' !tolua_isnoobj(tolua_S,2,&tolua_err)\n )') output(' goto tolua_lerror;') output(' else\n') output('#endif\n') -- tolua_release output(' {') -- declare self output(' ',self.const,self.parent.type,'*','self = ') output('(',self.const,self.parent.type,'*) ') output('tolua_tousertype(tolua_S,1,0);') -- check self output('#ifndef TOLUA_RELEASE\n') output(' if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);'); output('#endif\n') -- cast self output(' ',self.mod,self.type,self.ptr,'tolua_ret = ') output('(',self.mod,self.type,self.ptr,')(*self);') -- return value local t,ct = isbasic(self.type) if t then output(' tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);') 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 output(' }') output(' return 1;') 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') output('}') output('#endif //#ifndef TOLUA_DISABLE\n') output('\n') end -- Internal constructor function _Operator (t) setmetatable(t,classOperator) if t.const ~= 'const' and t.const ~= '' then error("#invalid 'const' specification") end append(t) if not t:inclass() then error("#operator can only be defined as class member") end --t.name = t.name .. "_" .. (_TM[t.kind] or t.kind) t.cname = t:cfuncname("tolua")..t:overload(t) t.name = "operator" .. t.kind -- set appropriate calling name return t end -- Constructor function Operator (d,k,a,c) local op_k = string.gsub(k, "^%s*", "") op_k = string.gsub(k, "%s*$", "") --if string.find(k, "^[%w_:%d<>%*%&]+$") then if d == "operator" and k ~= '' then d = k.." operator" elseif not _TM[op_k] then if flags['W'] then error("tolua: no support for operator" .. f.kind) else warning("No support for operator "..op_k..", ignoring") return nil end end local ref = '' local t = split_c_tokens(strsub(a,2,strlen(a)-1),',') -- 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 if k == '[]' then local _ _, _, ref = strfind(d,'(&)') d = gsub(d,'&','') elseif k=='&[]' then l.n = l.n+1 l[l.n] = Declaration(d,'var') l[l.n].name = 'tolua_value' end local f = Declaration(d,'func') if k == '[]' and (l[1]==nil or isbasic(l[1].type)~='number') then error('operator[] can only be defined for numeric index.') end f.args = l f.const = c f.kind = op_k f.lname = "."..(_TM[f.kind] or f.kind) if not _TM[f.kind] then f.cast_operator = true end if f.kind == '[]' and ref=='&' and f.const~='const' then Operator(d,'&'..k,a,c) -- create correspoding set operator end return _Operator(f) end