Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/tolua/lua/operator.lua @ 3231

Last change on this file since 3231 was 2710, checked in by rgrieder, 16 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

  • Property svn:eol-style set to native
File size: 6.2 KB
RevLine 
[1650]1-- tolua: operator class
2-- Written by Waldemar Celes
3-- TeCGraf/PUC-Rio
4-- Jul 1998
5-- $Id: $
6
7-- This code is free software; you can redistribute it and/or modify it.
8-- The software provided hereunder is on an "as is" basis, and
9-- the author has no obligation to provide maintenance, support, updates,
10-- enhancements, or modifications.
11
12
13-- Operator class
14-- Represents an operator function or a class operator method.
15-- It stores the same fields as functions do plus:
16--  kind = set of character representing the operator (as it appers in C++ code)
17classOperator = {
[2710]18    kind = '',
[1650]19}
20classOperator.__index = classOperator
21setmetatable(classOperator,classFunction)
22
23-- table to transform operator kind into the appropriate tag method name
[2710]24_TM = {
25    ['+'] = 'add',
26    ['-'] = 'sub',
27    ['*'] = 'mul',
28    ['/'] = 'div',
29    ['<'] = 'lt',
30    ['<='] = 'le',
31    ['=='] = 'eq',
32    ['[]'] = 'geti',
33    ['&[]'] = 'seti',
34    --['->'] = 'flechita',
35}
[1650]36
37
38-- Print method
39function classOperator:print (ident,close)
[2710]40    print(ident.."Operator{")
41    print(ident.." kind  = '"..self.kind.."',")
42    print(ident.." mod  = '"..self.mod.."',")
43    print(ident.." type = '"..self.type.."',")
44    print(ident.." ptr  = '"..self.ptr.."',")
45    print(ident.." name = '"..self.name.."',")
46    print(ident.." const = '"..self.const.."',")
47    print(ident.." cname = '"..self.cname.."',")
48    print(ident.." lname = '"..self.lname.."',")
49    print(ident.." args = {")
50    local i=1
51    while self.args[i] do
52        self.args[i]:print(ident.."  ",",")
53        i = i+1
54    end
55    print(ident.." }")
56    print(ident.."}"..close)
[1650]57end
58
59function classOperator:supcode_tmp()
60
[2710]61    if not _TM[self.kind] then
62        return classFunction.supcode(self)
63    end
[1650]64
[2710]65    -- no overload, no parameters, always inclass
66    output("/* method:",self.name," of class ",self:inclass()," */")
[1650]67
[2710]68    output("#ifndef TOLUA_DISABLE_"..self.cname)
69    output("\nstatic int",self.cname,"(lua_State* tolua_S)")
[1650]70
[2710]71    if overload < 0 then
72        output('#ifndef TOLUA_RELEASE\n')
73    end
74    output(' tolua_Error tolua_err;')
75    output(' if (\n')
76    -- check self
77    output('     !'..'tolua_isusertype(tolua_S,1,"'..self.parent.type..'",0,&tolua_err) ||\n')
78    output('     !tolua_isnoobj(tolua_S,2,&tolua_err)\n )')
79    output('  goto tolua_lerror;')
[1650]80
[2710]81    output(' else\n')
82    output('#endif\n') -- tolua_release
83    output(' {')
[1650]84
[2710]85    -- declare self
86    output(' ',self.const,self.parent.type,'*','self = ')
87    output('(',self.const,self.parent.type,'*) ')
88    output('tolua_tousertype(tolua_S,1,0);')
[1650]89
[2710]90    -- check self
91    output('#ifndef TOLUA_RELEASE\n')
92    output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
93    output('#endif\n')
[1650]94
[2710]95    -- cast self
96    output('  ',self.mod,self.type,self.ptr,'tolua_ret = ')
97    output('(',self.mod,self.type,self.ptr,')(*self);')
[1650]98
[2710]99    -- return value
100    local t,ct = isbasic(self.type)
101    if t then
102        output('   tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);')
103    else
104        t = self.type
105        new_t = string.gsub(t, "const%s+", "")
106        if self.ptr == '' then
107            output('   {')
108            output('#ifdef __cplusplus\n')
109            output('    void* tolua_obj = new',new_t,'(tolua_ret);')
110            output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
111            output('#else\n')
112            output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
113            output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
114            output('#endif\n')
115            output('   }')
116        elseif self.ptr == '&' then
117            output('   tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
118        else
119            if local_constructor then
120                output('   tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
121            else
122                output('   tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
123            end
124        end
125    end
[1650]126
[2710]127    output('  }')
128    output(' return 1;')
[1650]129
[2710]130    output('#ifndef TOLUA_RELEASE\n')
131    output('tolua_lerror:\n')
132    output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
133    output(' return 0;')
134    output('#endif\n')
[1650]135
136
[2710]137    output('}')
138    output('#endif //#ifndef TOLUA_DISABLE\n')
139    output('\n')
[1650]140end
141
142-- Internal constructor
143function _Operator (t)
[2710]144    setmetatable(t,classOperator)
[1650]145
[2710]146    if t.const ~= 'const' and t.const ~= '' then
147        error("#invalid 'const' specification")
148    end
[1650]149
[2710]150    append(t)
151    if not t:inclass() then
152        error("#operator can only be defined as class member")
153    end
[1650]154
[2710]155    --t.name = t.name .. "_" .. (_TM[t.kind] or t.kind)
156    t.cname = t:cfuncname("tolua")..t:overload(t)
157    t.name = "operator" .. t.kind  -- set appropriate calling name
158    return t
[1650]159end
160
161-- Constructor
162function Operator (d,k,a,c)
163
[2710]164    local op_k = string.gsub(k, "^%s*", "")
165    op_k = string.gsub(k, "%s*$", "")
166    --if string.find(k, "^[%w_:%d<>%*%&]+$") then
167    if d == "operator" and k ~= '' then
[1650]168
[2710]169        d = k.." operator"
170    elseif not _TM[op_k] then
[1650]171
[2710]172        if flags['W'] then
173            error("tolua: no support for operator" .. f.kind)
174        else
175            warning("No support for operator "..op_k..", ignoring")
176            return nil
177        end
178    end
[1650]179
[2710]180    local ref = ''
181    local t = split_c_tokens(strsub(a,2,strlen(a)-1),',') -- eliminate braces
182    local i=1
183    local l = {n=0}
184    while t[i] do
185        l.n = l.n+1
186        l[l.n] = Declaration(t[i],'var')
187        i = i+1
188    end
189    if k == '[]' then
190        local _
191        _, _, ref = strfind(d,'(&)')
192        d = gsub(d,'&','')
193    elseif k=='&[]' then
194        l.n = l.n+1
195        l[l.n] = Declaration(d,'var')
196        l[l.n].name = 'tolua_value'
197    end
198    local f = Declaration(d,'func')
199    if k == '[]' and (l[1]==nil or isbasic(l[1].type)~='number') then
200        error('operator[] can only be defined for numeric index.')
201    end
202    f.args = l
203    f.const = c
204    f.kind = op_k
205    f.lname = "."..(_TM[f.kind] or f.kind)
206    if not _TM[f.kind] then
207        f.cast_operator = true
208    end
209    if f.kind == '[]' and ref=='&' and f.const~='const' then
210        Operator(d,'&'..k,a,c)     -- create correspoding set operator
211    end
212    return _Operator(f)
[1650]213end
214
215
Note: See TracBrowser for help on using the repository browser.