1-- tolua: array class
2-- Written by Waldemar Celes
3-- TeCGraf/PUC-Rio
4-- Jul 1999
5-- $Id: array.lua,v 1.1 2000/11/06 22:03:57 celes Exp $
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-- Array class
14-- Represents a extern array variable or a public member of a class.
15-- Stores all fields present in a declaration.
16classArray = {
17}
18classArray.__index = classArray
19setmetatable(classArray,classDeclaration)
20
21-- Print method
22function classArray:print (ident,close)
23 print(ident.."Array{")
24 print(ident.." mod  = '"..self.mod.."',")
25 print(ident.." type = '"..self.type.."',")
26 print(ident.." ptr  = '"..self.ptr.."',")
27 print(ident.." name = '"..self.name.."',")
28 print(ident.." def  = '"..self.def.."',")
29 print(ident.." dim  = '"..self.dim.."',")
30 print(ident.." ret  = '"..self.ret.."',")
31 print(ident.."}"..close)
32end
33
34-- check if it is a variable
35function classArray:isvariable ()
36 return true
37end
38
39
40-- get variable value
41function classArray:getvalue (class,static)
42 if class and static then
43  return class..'::'..self.name..'[tolua_index]'
44 elseif class then
45  return 'self->'..self.name..'[tolua_index]'
46 else
47  return self.name..'[tolua_index]'
48 end
49end
50
51-- Write binding functions
52function classArray:supcode ()
53 local class = self:inclass()
54
55 -- get function ------------------------------------------------
56 if class then
57  output("/* get function:",self.name," of class ",class," */")
58 else
59  output("/* get function:",self.name," */")
60 end
61 self.cgetname = self:cfuncname("tolua_get")
62 output("#ifndef TOLUA_DISABLE_"..self.cgetname)
63 output("\nstatic int",self.cgetname,"(lua_State* tolua_S)")
64 output("{")
65 output(" int tolua_index;")
66
67 -- declare self, if the case
68 local _,_,static = strfind(self.mod,'^%s*(static)')
69 if class and static==nil then
70  output(' ',self.parent.type,'*','self;')
71  output(' lua_pushstring(tolua_S,".self");')
72  output(' lua_rawget(tolua_S,1);')
73  output(' self = ')
74  output('(',self.parent.type,'*) ')
75  output('lua_touserdata(tolua_S,-1);')
76 elseif static then
77  _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
78 end
79
80 -- check index
81	output('#ifndef TOLUA_RELEASE\n')
82	output(' {')
83	output('  tolua_Error tolua_err;')
84 output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
85 output('   tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);')
86	output(' }')
87	output('#endif\n')
88	if flags['1'] then -- for compatibility with tolua5 ?
89		output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
90	else
91		output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
92	end
93	output('#ifndef TOLUA_RELEASE\n')
94	if self.dim and self.dim ~= '' then
95	  output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
96	else
97	  output(' if (tolua_index<0)')
98	end
99 output('  tolua_error(tolua_S,"array indexing out of range.",NULL);')
100	output('#endif\n')
101
102 -- return value
103 local t,ct = isbasic(self.type)
104 local push_func = get_push_function(t)
105 if t then
106  output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');')
107 else
108		t = self.type
109  if self.ptr == '&' or self.ptr == '' then
110   output(' ',push_func,'(tolua_S,(void*)&'..self:getvalue(class,static)..',"',t,'");')
111  else
112   output(' ',push_func,'(tolua_S,(void*)'..self:getvalue(class,static)..',"',t,'");')
113  end
114 end
115 output(' return 1;')
116 output('}')
117 output('#endif //#ifndef TOLUA_DISABLE\n')
118 output('\n')
119
120 -- set function ------------------------------------------------
121 if not strfind(self.type,'const') then
122  if class then
123   output("/* set function:",self.name," of class ",class," */")
124  else
125   output("/* set function:",self.name," */")
126  end
127  self.csetname = self:cfuncname("tolua_set")
128  output("#ifndef TOLUA_DISABLE_"..self.csetname)
129  output("\nstatic int",self.csetname,"(lua_State* tolua_S)")
130  output("{")
131
132  -- declare index
133  output(' int tolua_index;')
134
135  -- declare self, if the case
136  local _,_,static = strfind(self.mod,'^%s*(static)')
137  if class and static==nil then
138   output(' ',self.parent.type,'*','self;')
139   output(' lua_pushstring(tolua_S,".self");')
140   output(' lua_rawget(tolua_S,1);')
141   output(' self = ')
142   output('(',self.parent.type,'*) ')
143   output('lua_touserdata(tolua_S,-1);')
144  elseif static then
145   _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
146  end
147
148  -- check index
149	 output('#ifndef TOLUA_RELEASE\n')
150	 output(' {')
151	 output('  tolua_Error tolua_err;')
152  output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
153  output('   tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);')
154		output(' }')
155		output('#endif\n')
156
157	if flags['1'] then -- for compatibility with tolua5 ?
158		output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
159	else
160		output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
161	end
162
163	 output('#ifndef TOLUA_RELEASE\n')
164	if self.dim and self.dim ~= '' then
165	  output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
166	else
167	  output(' if (tolua_index<0)')
168	end
169  output('  tolua_error(tolua_S,"array indexing out of range.",NULL);')
170		output('#endif\n')
171
172  -- assign value
173  local ptr = ''
174  if self.ptr~='' then ptr = '*' end
175  output(' ')
176  if class and static then
177   output(class..'::'..self.name..'[tolua_index]')
178  elseif class then
179   output('self->'..self.name..'[tolua_index]')
180  else
181   output(self.name..'[tolua_index]')
182  end
183  local t = isbasic(self.type)
184  output(' = ')
185  if not t and ptr=='' then output('*') end
186  output('((',self.mod,self.type)
187  if not t then
188   output('*')
189  end
190  output(') ')
191  local def = 0
192  if self.def ~= '' then def = self.def end
193  if t then
194   output('tolua_to'..t,'(tolua_S,3,',def,'));')
195  else
196   local to_func = get_to_function(self.type)
197   output(to_func,'(tolua_S,3,',def,'));')
198  end
199  output(' return 0;')
200  output('}')
201  output('#endif //#ifndef TOLUA_DISABLE\n')
202  output('\n')
203 end
204
205end
206
207function classArray:register (pre)
208	if not self:check_public_access() then
209		return
210	end
211
212 pre = pre or ''
213 if self.csetname then
214  output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
215 else
216  output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
217 end
218end
219
220-- Internal constructor
221function _Array (t)
222 setmetatable(t,classArray)
223 append(t)
224 return t
225end
226
227-- Constructor
228-- Expects a string representing the variable declaration.
229function Array (s)
230 return _Array (Declaration(s,'var'))
231end
232
233
234