Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2760 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
Line 
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 = {
18    kind = '',
19}
20classOperator.__index = classOperator
21setmetatable(classOperator,classFunction)
22
23-- table to transform operator kind into the appropriate tag method name
24_TM = {
25    ['+'] = 'add',
26    ['-'] = 'sub',
27    ['*'] = 'mul',
28    ['/'] = 'div',
29    ['<'] = 'lt',
30    ['<='] = 'le',
31    ['=='] = 'eq',
32    ['[]'] = 'geti',
33    ['&[]'] = 'seti',
34    --['->'] = 'flechita',
35}
36
37
38-- Print method
39function classOperator:print (ident,close)
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)
57end
58
59function classOperator:supcode_tmp()
60
61    if not _TM[self.kind] then
62        return classFunction.supcode(self)
63    end
64
65    -- no overload, no parameters, always inclass
66    output("/* method:",self.name," of class ",self:inclass()," */")
67
68    output("#ifndef TOLUA_DISABLE_"..self.cname)
69    output("\nstatic int",self.cname,"(lua_State* tolua_S)")
70
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;')
80
81    output(' else\n')
82    output('#endif\n') -- tolua_release
83    output(' {')
84
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);')
89
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')
94
95    -- cast self
96    output('  ',self.mod,self.type,self.ptr,'tolua_ret = ')
97    output('(',self.mod,self.type,self.ptr,')(*self);')
98
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
126
127    output('  }')
128    output(' return 1;')
129
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')
135
136
137    output('}')
138    output('#endif //#ifndef TOLUA_DISABLE\n')
139    output('\n')
140end
141
142-- Internal constructor
143function _Operator (t)
144    setmetatable(t,classOperator)
145
146    if t.const ~= 'const' and t.const ~= '' then
147        error("#invalid 'const' specification")
148    end
149
150    append(t)
151    if not t:inclass() then
152        error("#operator can only be defined as class member")
153    end
154
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
159end
160
161-- Constructor
162function Operator (d,k,a,c)
163
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
168
169        d = k.." operator"
170    elseif not _TM[op_k] then
171
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
179
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)
213end
214
215
Note: See TracBrowser for help on using the repository browser.