Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/tolua/lua/operator.lua @ 2030

Last change on this file since 2030 was 1650, checked in by rgrieder, 16 years ago

added preliminary automatic creation of tolua generator that creates the actual executable
(please don't ask about the egg-hen question…)

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.