Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/tolua/lua/variable.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: 7.6 KB
Line 
1-- tolua: variable 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-- Variable class
14-- Represents a extern variable or a public member of a class.
15-- Stores all fields present in a declaration.
16classVariable = {
17 _get = {},   -- mapped get functions
18 _set = {},   -- mapped set functions
19}
20classVariable.__index = classVariable
21setmetatable(classVariable,classDeclaration)
22
23-- Print method
24function classVariable:print (ident,close)
25 print(ident.."Variable{")
26 print(ident.." mod  = '"..self.mod.."',")
27 print(ident.." type = '"..self.type.."',")
28 print(ident.." ptr  = '"..self.ptr.."',")
29 print(ident.." name = '"..self.name.."',")
30 if self.dim then print(ident.." dim = '"..self.dim.."',") end
31 print(ident.." def  = '"..self.def.."',")
32 print(ident.." ret  = '"..self.ret.."',")
33 print(ident.."}"..close)
34end
35
36-- Generates C function name
37function classVariable:cfuncname (prefix)
38 local parent = ""
39 local unsigned = ""
40 local ptr = ""
41
42 local p = self:inmodule() or self:innamespace() or self:inclass()
43
44 if p then
45        if self.parent.classtype == 'class' then
46                parent = "_" .. self.parent.type
47        else
48          parent = "_" .. p
49        end
50 end
51
52 if strfind(self.mod,"(unsigned)") then
53  unsigned = "_unsigned"
54 end
55
56 if self.ptr == "*" then ptr = "_ptr"
57 elseif self.ptr == "&" then ptr = "_ref"
58 end
59
60 local name =  prefix .. parent .. unsigned .. "_" .. gsub(self.lname or self.name,".*::","") .. ptr
61
62        name = clean_template(name)
63 return name
64
65end
66
67-- check if it is a variable
68function classVariable:isvariable ()
69 return true
70end
71
72-- get variable value
73function classVariable:getvalue (class,static, prop_get)
74
75        local name
76        if prop_get then
77
78                name = prop_get.."()"
79        else
80                name = self.name
81        end
82
83        if class and static then
84         return self.parent.type..'::'..name
85        elseif class then
86         return 'self->'..name
87        else
88         return name
89        end
90end
91
92-- get variable pointer value
93function classVariable:getpointervalue (class,static)
94 if class and static then
95  return class..'::p'
96 elseif class then
97  return 'self->p'
98 else
99  return 'p'
100 end
101end
102
103-- Write binding functions
104function classVariable:supcode ()
105
106 local class = self:inclass()
107
108        local prop_get,prop_set
109        if string.find(self.mod, 'tolua_property') then
110
111                _,_,type = string.find(self.mod, "tolua_property__([^%s]*)")
112                type = type or "default"
113                prop_get,prop_set = get_property_methods(type, self.name)
114                self.mod = string.gsub(self.mod, "tolua_property[^%s]*", "")
115        end
116
117 -- get function ------------------------------------------------
118 if class then
119  output("/* get function:",self.name," of class ",class," */")
120 else
121  output("/* get function:",self.name," */")
122 end
123 self.cgetname = self:cfuncname("tolua_get")
124 output("#ifndef TOLUA_DISABLE_"..self.cgetname)
125 output("\nstatic int",self.cgetname,"(lua_State* tolua_S)")
126 output("{")
127
128 -- declare self, if the case
129 local _,_,static = strfind(self.mod,'^%s*(static)')
130 if class and static==nil then
131  output(' ',self.parent.type,'*','self = ')
132  output('(',self.parent.type,'*) ')
133  output('tolua_tousertype(tolua_S,1,0);')
134 elseif static then
135  _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
136 end
137
138
139 -- check self value
140 if class and static==nil then
141         output('#ifndef TOLUA_RELEASE\n')
142  output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
143                output('#endif\n')
144 end
145
146 -- return value
147 if string.find(self.mod, 'tolua_inherits') then
148        output('#ifdef __cplusplus\n')
149        output('  tolua_pushusertype(tolua_S,(void*)static_cast<'..self.type..'*>(self), "',self.type,'");')
150        output('#else\n')
151        output('  tolua_pushusertype(tolua_S,(void*)(('..self.type..'*)self), "',self.type,'");')
152        output('#endif\n')
153 else
154        local t,ct = isbasic(self.type)
155        if t then
156                output('  tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static,prop_get)..');')
157        else
158                t = self.type
159                if self.ptr == '&' or self.ptr == '' then
160                        output('  tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static,prop_get)..',"',t,'");')
161                else
162                        output('  tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static,prop_get)..',"',t,'");')
163                end
164        end
165 end
166 output(' return 1;')
167 output('}')
168 output('#endif //#ifndef TOLUA_DISABLE\n')
169 output('\n')
170
171 -- set function ------------------------------------------------
172 if not (strfind(self.type,'const%s+') or string.find(self.mod, 'tolua_readonly') or string.find(self.mod, 'tolua_inherits'))  then
173  if class then
174   output("/* set function:",self.name," of class ",class," */")
175  else
176   output("/* set function:",self.name," */")
177  end
178  self.csetname = self:cfuncname("tolua_set")
179  output("#ifndef TOLUA_DISABLE_"..self.csetname)
180  output("\nstatic int",self.csetname,"(lua_State* tolua_S)")
181  output("{")
182
183  -- declare self, if the case
184  if class and static==nil then
185   output(' ',self.parent.type,'*','self = ')
186   output('(',self.parent.type,'*) ')
187   output('tolua_tousertype(tolua_S,1,0);')
188   -- check self value
189                end
190  -- check types
191                output('#ifndef TOLUA_RELEASE\n')
192                output('  tolua_Error tolua_err;')
193  if class and static==nil then
194   output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
195  elseif static then
196   _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
197  end
198
199  -- check variable type
200  output('  if (!'..self:outchecktype(2)..')')
201  output('   tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);')
202                output('#endif\n')
203
204  -- assign value
205                local def = 0
206                if self.def ~= '' then def = self.def end
207                if self.type == 'char*' and self.dim ~= '' then -- is string
208                 output(' strncpy(')
209                        if class and static then
210                                output(self.parent.type..'::'..self.name)
211                        elseif class then
212                                output('self->'..self.name)
213                        else
214                                output(self.name)
215                        end
216                        output(',tolua_tostring(tolua_S,2,',def,'),',self.dim,'-1);')
217                else
218                        local ptr = ''
219                        if self.ptr~='' then ptr = '*' end
220                        output(' ')
221                        local name = prop_set or self.name
222                        if class and static then
223                                output(self.parent.type..'::'..name)
224                        elseif class then
225                                output('self->'..name)
226                        else
227                                output(name)
228                        end
229                        local t = isbasic(self.type)
230                        if prop_set then
231                                output('(')
232                        else
233                                output(' = ')
234                        end
235                        if not t and ptr=='' then output('*') end
236                        output('((',self.mod,self.type)
237                        if not t then
238                                output('*')
239                        end
240                        output(') ')
241                        if t then
242                                if isenum(self.type) then
243                                        output('(int) ')
244                                end
245                                output('tolua_to'..t,'(tolua_S,2,',def,'))')
246                        else
247                                output('tolua_tousertype(tolua_S,2,',def,'))')
248                        end
249                        if prop_set then
250                                output(")")
251                        end
252                        output(";")
253                end
254  output(' return 0;')
255  output('}')
256  output('#endif //#ifndef TOLUA_DISABLE\n')
257  output('\n')
258 end
259
260end
261
262function classVariable:register (pre)
263
264        if not self:check_public_access() then
265                return
266        end
267 pre = pre or ''
268 local parent = self:inmodule() or self:innamespace() or self:inclass()
269 if not parent then
270  if classVariable._warning==nil then
271   warning("Mapping variable to global may degrade performance")
272   classVariable._warning = 1
273  end
274 end
275 if self.csetname then
276  output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
277 else
278  output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
279 end
280end
281
282-- Internal constructor
283function _Variable (t)
284 setmetatable(t,classVariable)
285 append(t)
286 return t
287end
288
289-- Constructor
290-- Expects a string representing the variable declaration.
291function Variable (s)
292 return _Variable (Declaration(s,'var'))
293end
294
295
Note: See TracBrowser for help on using the repository browser.