Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2087 was 2087, checked in by landauf, 16 years ago

merged objecthierarchy branch back to trunk

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