| [1650] | 1 | -- tolua: declaration 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 | -- Declaration class | 
|---|
|  | 14 | -- Represents variable, function, or argument declaration. | 
|---|
|  | 15 | -- Stores the following fields: | 
|---|
|  | 16 | --  mod  = type modifiers | 
|---|
|  | 17 | --  type = type | 
|---|
|  | 18 | --  ptr  = "*" or "&", if representing a pointer or a reference | 
|---|
|  | 19 | --  name = name | 
|---|
|  | 20 | --  dim  = dimension, if a vector | 
|---|
|  | 21 | --  def  = default value, if any (only for arguments) | 
|---|
|  | 22 | --  ret  = "*" or "&", if value is to be returned (only for arguments) | 
|---|
|  | 23 | classDeclaration = { | 
|---|
| [2710] | 24 | mod = '', | 
|---|
|  | 25 | type = '', | 
|---|
|  | 26 | ptr = '', | 
|---|
|  | 27 | name = '', | 
|---|
|  | 28 | dim = '', | 
|---|
|  | 29 | ret = '', | 
|---|
|  | 30 | def = '' | 
|---|
| [1650] | 31 | } | 
|---|
|  | 32 | classDeclaration.__index = classDeclaration | 
|---|
|  | 33 | setmetatable(classDeclaration,classFeature) | 
|---|
|  | 34 |  | 
|---|
|  | 35 | -- Create an unique variable name | 
|---|
|  | 36 | function create_varname () | 
|---|
| [2710] | 37 | if not _varnumber then _varnumber = 0 end | 
|---|
|  | 38 | _varnumber = _varnumber + 1 | 
|---|
|  | 39 | return "tolua_var_".._varnumber | 
|---|
| [1650] | 40 | end | 
|---|
|  | 41 |  | 
|---|
|  | 42 | -- Check declaration name | 
|---|
|  | 43 | -- It also identifies default values | 
|---|
|  | 44 | function classDeclaration:checkname () | 
|---|
|  | 45 |  | 
|---|
| [2710] | 46 | if strsub(self.name,1,1) == '[' and not findtype(self.type) then | 
|---|
|  | 47 | self.name = self.type..self.name | 
|---|
|  | 48 | local m = split(self.mod,'%s%s*') | 
|---|
|  | 49 | self.type = m[m.n] | 
|---|
|  | 50 | self.mod = concat(m,1,m.n-1) | 
|---|
|  | 51 | end | 
|---|
| [1650] | 52 |  | 
|---|
| [2710] | 53 | local t = split(self.name,'=') | 
|---|
|  | 54 | if t.n==2 then | 
|---|
|  | 55 | self.name = t[1] | 
|---|
|  | 56 | self.def = find_enum_var(t[t.n]) | 
|---|
|  | 57 | end | 
|---|
| [1650] | 58 |  | 
|---|
| [2710] | 59 | local b,e,d = strfind(self.name,"%[(.-)%]") | 
|---|
|  | 60 | if b then | 
|---|
|  | 61 | self.name = strsub(self.name,1,b-1) | 
|---|
|  | 62 | self.dim = find_enum_var(d) | 
|---|
|  | 63 | end | 
|---|
| [1650] | 64 |  | 
|---|
|  | 65 |  | 
|---|
| [2710] | 66 | if self.type ~= '' and self.type ~= 'void' and self.name == '' then | 
|---|
|  | 67 | self.name = create_varname() | 
|---|
|  | 68 | elseif self.kind=='var' then | 
|---|
|  | 69 | if self.type=='' and self.name~='' then | 
|---|
|  | 70 | self.type = self.type..self.name | 
|---|
|  | 71 | self.name = create_varname() | 
|---|
|  | 72 | elseif findtype(self.name) then | 
|---|
|  | 73 | if self.type=='' then self.type = self.name | 
|---|
|  | 74 | else self.type = self.type..' '..self.name end | 
|---|
|  | 75 | self.name = create_varname() | 
|---|
|  | 76 | end | 
|---|
|  | 77 | end | 
|---|
| [1650] | 78 |  | 
|---|
| [2710] | 79 | -- adjust type of string | 
|---|
|  | 80 | if self.type == 'char' and self.dim ~= '' then | 
|---|
|  | 81 | self.type = 'char*' | 
|---|
|  | 82 | end | 
|---|
| [1650] | 83 |  | 
|---|
| [2710] | 84 | if self.kind and self.kind == 'var' then | 
|---|
|  | 85 | self.name = string.gsub(self.name, ":.*$", "") -- ??? | 
|---|
|  | 86 | end | 
|---|
| [1650] | 87 | end | 
|---|
|  | 88 |  | 
|---|
|  | 89 | -- Check declaration type | 
|---|
|  | 90 | -- Substitutes typedef's. | 
|---|
|  | 91 | function classDeclaration:checktype () | 
|---|
|  | 92 |  | 
|---|
| [2710] | 93 | -- check if there is a pointer to basic type | 
|---|
|  | 94 | local basic = isbasic(self.type) | 
|---|
|  | 95 | if self.kind == 'func' and basic=='number' and string.find(self.ptr, "%*") then | 
|---|
|  | 96 | self.type = '_userdata' | 
|---|
|  | 97 | self.ptr = "" | 
|---|
|  | 98 | end | 
|---|
|  | 99 | if basic and self.ptr~='' then | 
|---|
|  | 100 | self.ret = self.ptr | 
|---|
|  | 101 | self.ptr = nil | 
|---|
|  | 102 | if isbasic(self.type) == 'number' then | 
|---|
|  | 103 | self.return_userdata = true | 
|---|
|  | 104 | end | 
|---|
|  | 105 | end | 
|---|
| [1650] | 106 |  | 
|---|
| [2710] | 107 | -- check if there is array to be returned | 
|---|
|  | 108 | if self.dim~='' and self.ret~='' then | 
|---|
|  | 109 | error('#invalid parameter: cannot return an array of values') | 
|---|
|  | 110 | end | 
|---|
|  | 111 | -- restore 'void*' and 'string*' | 
|---|
|  | 112 | if self.type == '_userdata' then self.type = 'void*' | 
|---|
|  | 113 | elseif self.type == '_cstring' then self.type = 'char*' | 
|---|
|  | 114 | elseif self.type == '_lstate' then self.type = 'lua_State*' | 
|---|
|  | 115 | end | 
|---|
| [1650] | 116 |  | 
|---|
| [2710] | 117 | -- resolve types inside the templates | 
|---|
|  | 118 | if self.type then | 
|---|
|  | 119 | self.type = resolve_template_types(self.type) | 
|---|
|  | 120 | end | 
|---|
| [1650] | 121 |  | 
|---|
| [2710] | 122 | -- | 
|---|
|  | 123 | -- -- if returning value, automatically set default value | 
|---|
|  | 124 | -- if self.ret ~= '' and self.def == '' then | 
|---|
|  | 125 | --  self.def = '0' | 
|---|
|  | 126 | -- end | 
|---|
|  | 127 | -- | 
|---|
| [1650] | 128 |  | 
|---|
|  | 129 | end | 
|---|
|  | 130 |  | 
|---|
|  | 131 | function resolve_template_types(type) | 
|---|
|  | 132 |  | 
|---|
| [2710] | 133 | if isbasic(type) then | 
|---|
|  | 134 | return type | 
|---|
|  | 135 | end | 
|---|
|  | 136 | local b,_,m = string.find(type, "(%b<>)") | 
|---|
|  | 137 | if b then | 
|---|
| [1650] | 138 |  | 
|---|
| [2710] | 139 | m = split_c_tokens(string.sub(m, 2, -2), ",") | 
|---|
|  | 140 | for i=1, table.getn(m) do | 
|---|
|  | 141 | m[i] = string.gsub(m[i],"%s*([%*&])", "%1") | 
|---|
|  | 142 | m[i] = findtype(m[i]) or m[i] | 
|---|
|  | 143 | m[i] = resolve_template_types(m[i]) | 
|---|
|  | 144 | end | 
|---|
| [1650] | 145 |  | 
|---|
| [2710] | 146 | local b,i | 
|---|
|  | 147 | type,b,i = break_template(type) | 
|---|
|  | 148 | local template_part = "<"..string.gsub(concat(m, 1, m.n), " ", ",")..">" | 
|---|
|  | 149 | type = rebuild_template(type, b, template_part) | 
|---|
|  | 150 | type = string.gsub(type, ">>", "> >") | 
|---|
|  | 151 | end | 
|---|
|  | 152 | return type | 
|---|
| [1650] | 153 | end | 
|---|
|  | 154 |  | 
|---|
|  | 155 | function break_template(s) | 
|---|
| [2710] | 156 | local b,e,timpl = string.find(s, "(%b<>)") | 
|---|
|  | 157 | if timpl then | 
|---|
|  | 158 | s = string.gsub(s, "%b<>", "") | 
|---|
|  | 159 | return s, b, timpl | 
|---|
|  | 160 | else | 
|---|
|  | 161 | return s, 0, nil | 
|---|
|  | 162 | end | 
|---|
| [1650] | 163 | end | 
|---|
|  | 164 |  | 
|---|
|  | 165 | function rebuild_template(s, b, timpl) | 
|---|
|  | 166 |  | 
|---|
| [2710] | 167 | if b == 0 then | 
|---|
|  | 168 | return s | 
|---|
|  | 169 | end | 
|---|
| [1650] | 170 |  | 
|---|
| [2710] | 171 | return string.sub(s, 1, b-1)..timpl..string.sub(s, b, -1) | 
|---|
| [1650] | 172 | end | 
|---|
|  | 173 |  | 
|---|
|  | 174 | -- Print method | 
|---|
|  | 175 | function classDeclaration:print (ident,close) | 
|---|
| [2710] | 176 | print(ident.."Declaration{") | 
|---|
|  | 177 | print(ident.." mod  = '"..self.mod.."',") | 
|---|
|  | 178 | print(ident.." type = '"..self.type.."',") | 
|---|
|  | 179 | print(ident.." ptr  = '"..self.ptr.."',") | 
|---|
|  | 180 | print(ident.." name = '"..self.name.."',") | 
|---|
|  | 181 | print(ident.." dim  = '"..self.dim.."',") | 
|---|
|  | 182 | print(ident.." def  = '"..self.def.."',") | 
|---|
|  | 183 | print(ident.." ret  = '"..self.ret.."',") | 
|---|
|  | 184 | print(ident.."}"..close) | 
|---|
| [1650] | 185 | end | 
|---|
|  | 186 |  | 
|---|
|  | 187 | -- check if array of values are returned to Lua | 
|---|
|  | 188 | function classDeclaration:requirecollection (t) | 
|---|
|  | 189 | if self.mod ~= 'const' and | 
|---|
| [2710] | 190 | self.dim and self.dim ~= '' and | 
|---|
|  | 191 | not isbasic(self.type) and | 
|---|
|  | 192 | self.ptr == '' then | 
|---|
|  | 193 | local type = gsub(self.type,"%s*const%s+","") | 
|---|
|  | 194 | t[type] = "tolua_collect_" .. clean_template(type) | 
|---|
|  | 195 | return true | 
|---|
|  | 196 | end | 
|---|
|  | 197 | return false | 
|---|
| [1650] | 198 | end | 
|---|
|  | 199 |  | 
|---|
|  | 200 | -- declare tag | 
|---|
|  | 201 | function classDeclaration:decltype () | 
|---|
|  | 202 |  | 
|---|
| [2710] | 203 | self.type = typevar(self.type) | 
|---|
|  | 204 | if strfind(self.mod,'const') then | 
|---|
|  | 205 | self.type = 'const '..self.type | 
|---|
|  | 206 | self.mod = gsub(self.mod,'const%s*','') | 
|---|
|  | 207 | end | 
|---|
| [1650] | 208 | end | 
|---|
|  | 209 |  | 
|---|
|  | 210 |  | 
|---|
|  | 211 | -- output type checking | 
|---|
|  | 212 | function classDeclaration:outchecktype (narg) | 
|---|
| [2710] | 213 | local def | 
|---|
|  | 214 | local t = isbasic(self.type) | 
|---|
|  | 215 | if self.def~='' then | 
|---|
|  | 216 | def = 1 | 
|---|
|  | 217 | else | 
|---|
|  | 218 | def = 0 | 
|---|
|  | 219 | end | 
|---|
|  | 220 | if self.dim ~= '' then | 
|---|
|  | 221 | --if t=='string' then | 
|---|
|  | 222 | --    return 'tolua_isstringarray(tolua_S,'..narg..','..def..',&tolua_err)' | 
|---|
|  | 223 | --else | 
|---|
|  | 224 | return 'tolua_istable(tolua_S,'..narg..',0,&tolua_err)' | 
|---|
|  | 225 | --end | 
|---|
|  | 226 | elseif t then | 
|---|
|  | 227 | return 'tolua_is'..t..'(tolua_S,'..narg..','..def..',&tolua_err)' | 
|---|
|  | 228 | else | 
|---|
|  | 229 | return 'tolua_isusertype(tolua_S,'..narg..',"'..self.type..'",'..def..',&tolua_err)' | 
|---|
|  | 230 | end | 
|---|
| [1650] | 231 | end | 
|---|
|  | 232 |  | 
|---|
|  | 233 | function classDeclaration:builddeclaration (narg, cplusplus) | 
|---|
| [2710] | 234 | local array = self.dim ~= '' and tonumber(self.dim)==nil | 
|---|
|  | 235 | local line = "" | 
|---|
|  | 236 | local ptr = '' | 
|---|
|  | 237 | local mod | 
|---|
|  | 238 | local type = self.type | 
|---|
|  | 239 | if self.dim ~= '' then | 
|---|
|  | 240 | type = gsub(self.type,'const%s+','')  -- eliminates const modifier for arrays | 
|---|
|  | 241 | end | 
|---|
|  | 242 | if self.ptr~='' and not isbasic(type) then ptr = '*' end | 
|---|
|  | 243 | line = concatparam(line," ",self.mod,type,ptr) | 
|---|
|  | 244 | if array then | 
|---|
|  | 245 | line = concatparam(line,'*') | 
|---|
|  | 246 | end | 
|---|
|  | 247 | line = concatparam(line,self.name) | 
|---|
|  | 248 | if self.dim ~= '' then | 
|---|
|  | 249 | if tonumber(self.dim)~=nil then | 
|---|
|  | 250 | line = concatparam(line,'[',self.dim,'];') | 
|---|
|  | 251 | else | 
|---|
|  | 252 | if cplusplus then | 
|---|
|  | 253 | line = concatparam(line,' = new',type,ptr,'['..self.dim..'];') | 
|---|
|  | 254 | else | 
|---|
|  | 255 | line = concatparam(line,' = (',type,ptr,'*)', | 
|---|
|  | 256 | 'malloc((',self.dim,')*sizeof(',type,ptr,'));') | 
|---|
|  | 257 | end | 
|---|
|  | 258 | end | 
|---|
|  | 259 | else | 
|---|
|  | 260 | local t = isbasic(type) | 
|---|
|  | 261 | line = concatparam(line,' = ') | 
|---|
|  | 262 | if t == 'state' then | 
|---|
|  | 263 | line = concatparam(line, 'tolua_S;') | 
|---|
|  | 264 | else | 
|---|
|  | 265 | --print("t is "..tostring(t)..", ptr is "..tostring(self.ptr)) | 
|---|
|  | 266 | if t == 'number' and string.find(self.ptr, "%*") then | 
|---|
|  | 267 | t = 'userdata' | 
|---|
|  | 268 | end | 
|---|
|  | 269 | if not t and ptr=='' then line = concatparam(line,'*') end | 
|---|
|  | 270 | line = concatparam(line,'((',self.mod,type) | 
|---|
|  | 271 | if not t then | 
|---|
|  | 272 | line = concatparam(line,'*') | 
|---|
|  | 273 | end | 
|---|
|  | 274 | line = concatparam(line,') ') | 
|---|
|  | 275 | if isenum(type) then | 
|---|
|  | 276 | line = concatparam(line,'(int) ') | 
|---|
|  | 277 | end | 
|---|
|  | 278 | local def = 0 | 
|---|
|  | 279 | if self.def ~= '' then | 
|---|
|  | 280 | def = self.def | 
|---|
|  | 281 | if (ptr == '' or self.ptr == '&') and not t then | 
|---|
|  | 282 | def = "(void*)&(const "..type..")"..def | 
|---|
|  | 283 | end | 
|---|
|  | 284 | end | 
|---|
|  | 285 | if t then | 
|---|
|  | 286 | line = concatparam(line,'tolua_to'..t,'(tolua_S,',narg,',',def,'));') | 
|---|
|  | 287 | else | 
|---|
|  | 288 | line = concatparam(line,'tolua_tousertype(tolua_S,',narg,',',def,'));') | 
|---|
|  | 289 | end | 
|---|
|  | 290 | end | 
|---|
|  | 291 | end | 
|---|
|  | 292 | return line | 
|---|
| [1650] | 293 | end | 
|---|
|  | 294 |  | 
|---|
|  | 295 | -- Declare variable | 
|---|
|  | 296 | function classDeclaration:declare (narg) | 
|---|
| [2710] | 297 | if self.dim ~= '' and tonumber(self.dim)==nil then | 
|---|
|  | 298 | output('#ifdef __cplusplus\n') | 
|---|
|  | 299 | output(self:builddeclaration(narg,true)) | 
|---|
|  | 300 | output('#else\n') | 
|---|
|  | 301 | output(self:builddeclaration(narg,false)) | 
|---|
|  | 302 | output('#endif\n') | 
|---|
|  | 303 | else | 
|---|
|  | 304 | output(self:builddeclaration(narg,false)) | 
|---|
|  | 305 | end | 
|---|
| [1650] | 306 | end | 
|---|
|  | 307 |  | 
|---|
|  | 308 | -- Get parameter value | 
|---|
|  | 309 | function classDeclaration:getarray (narg) | 
|---|
| [2710] | 310 | if self.dim ~= '' then | 
|---|
|  | 311 | local type = gsub(self.type,'const ','') | 
|---|
|  | 312 | output('  {') | 
|---|
|  | 313 | output('#ifndef TOLUA_RELEASE\n') | 
|---|
|  | 314 | local def; if self.def~='' then def=1 else def=0 end | 
|---|
|  | 315 | local t = isbasic(type) | 
|---|
|  | 316 | if (t) then | 
|---|
|  | 317 | output('   if (!tolua_is'..t..'array(tolua_S,',narg,',',self.dim,',',def,',&tolua_err))') | 
|---|
|  | 318 | else | 
|---|
|  | 319 | output('   if (!tolua_isusertypearray(tolua_S,',narg,',"',type,'",',self.dim,',',def,',&tolua_err))') | 
|---|
|  | 320 | end | 
|---|
|  | 321 | output('    goto tolua_lerror;') | 
|---|
|  | 322 | output('   else\n') | 
|---|
|  | 323 | output('#endif\n') | 
|---|
|  | 324 | output('   {') | 
|---|
|  | 325 | output('    int i;') | 
|---|
|  | 326 | output('    for(i=0; i<'..self.dim..';i++)') | 
|---|
|  | 327 | local t = isbasic(type) | 
|---|
|  | 328 | local ptr = '' | 
|---|
|  | 329 | if self.ptr~='' then ptr = '*' end | 
|---|
|  | 330 | output('   ',self.name..'[i] = ') | 
|---|
|  | 331 | if not t and ptr=='' then output('*') end | 
|---|
|  | 332 | output('((',type) | 
|---|
|  | 333 | if not t then | 
|---|
|  | 334 | output('*') | 
|---|
|  | 335 | end | 
|---|
|  | 336 | output(') ') | 
|---|
|  | 337 | local def = 0 | 
|---|
|  | 338 | if self.def ~= '' then def = self.def end | 
|---|
|  | 339 | if t then | 
|---|
|  | 340 | output('tolua_tofield'..t..'(tolua_S,',narg,',i+1,',def,'));') | 
|---|
|  | 341 | else | 
|---|
|  | 342 | output('tolua_tofieldusertype(tolua_S,',narg,',i+1,',def,'));') | 
|---|
|  | 343 | end | 
|---|
|  | 344 | output('   }') | 
|---|
|  | 345 | output('  }') | 
|---|
|  | 346 | end | 
|---|
| [1650] | 347 | end | 
|---|
|  | 348 |  | 
|---|
|  | 349 | -- Get parameter value | 
|---|
|  | 350 | function classDeclaration:setarray (narg) | 
|---|
| [2710] | 351 | if not strfind(self.type,'const%s+') and self.dim ~= '' then | 
|---|
|  | 352 | local type = gsub(self.type,'const ','') | 
|---|
|  | 353 | output('  {') | 
|---|
|  | 354 | output('   int i;') | 
|---|
|  | 355 | output('   for(i=0; i<'..self.dim..';i++)') | 
|---|
|  | 356 | local t,ct = isbasic(type) | 
|---|
|  | 357 | if t then | 
|---|
|  | 358 | output('    tolua_pushfield'..t..'(tolua_S,',narg,',i+1,(',ct,')',self.name,'[i]);') | 
|---|
|  | 359 | else | 
|---|
|  | 360 | if self.ptr == '' then | 
|---|
|  | 361 | output('   {') | 
|---|
|  | 362 | output('#ifdef __cplusplus\n') | 
|---|
|  | 363 | output('    void* tolua_obj = new',type,'(',self.name,'[i]);') | 
|---|
|  | 364 | output('    tolua_pushfieldusertype_and_takeownership(tolua_S,',narg,',i+1,tolua_obj,"',type,'");') | 
|---|
|  | 365 | output('#else\n') | 
|---|
|  | 366 | output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&',self.name,'[i],sizeof(',type,'));') | 
|---|
|  | 367 | output('    tolua_pushfieldusertype(tolua_S,',narg,',i+1,tolua_obj,"',type,'");') | 
|---|
|  | 368 | output('#endif\n') | 
|---|
|  | 369 | output('   }') | 
|---|
|  | 370 | else | 
|---|
|  | 371 | output('   tolua_pushfieldusertype(tolua_S,',narg,',i+1,(void*)',self.name,'[i],"',type,'");') | 
|---|
|  | 372 | end | 
|---|
|  | 373 | end | 
|---|
|  | 374 | output('  }') | 
|---|
|  | 375 | end | 
|---|
| [1650] | 376 | end | 
|---|
|  | 377 |  | 
|---|
|  | 378 | -- Free dynamically allocated array | 
|---|
|  | 379 | function classDeclaration:freearray () | 
|---|
| [2710] | 380 | if self.dim ~= '' and tonumber(self.dim)==nil then | 
|---|
|  | 381 | output('#ifdef __cplusplus\n') | 
|---|
|  | 382 | output('  delete []',self.name,';') | 
|---|
|  | 383 | output('#else\n') | 
|---|
|  | 384 | output('  free(',self.name,');') | 
|---|
|  | 385 | output('#endif\n') | 
|---|
|  | 386 | end | 
|---|
| [1650] | 387 | end | 
|---|
|  | 388 |  | 
|---|
|  | 389 | -- Pass parameter | 
|---|
|  | 390 | function classDeclaration:passpar () | 
|---|
| [2710] | 391 | if self.ptr=='&' and not isbasic(self.type) then | 
|---|
|  | 392 | output('*'..self.name) | 
|---|
|  | 393 | elseif self.ret=='*' then | 
|---|
|  | 394 | output('&'..self.name) | 
|---|
|  | 395 | else | 
|---|
|  | 396 | output(self.name) | 
|---|
|  | 397 | end | 
|---|
| [1650] | 398 | end | 
|---|
|  | 399 |  | 
|---|
|  | 400 | -- Return parameter value | 
|---|
|  | 401 | function classDeclaration:retvalue () | 
|---|
| [2710] | 402 | if self.ret ~= '' then | 
|---|
|  | 403 | local t,ct = isbasic(self.type) | 
|---|
|  | 404 | if t and t~='' then | 
|---|
|  | 405 | output('   tolua_push'..t..'(tolua_S,(',ct,')'..self.name..');') | 
|---|
|  | 406 | else | 
|---|
|  | 407 | output('   tolua_pushusertype(tolua_S,(void*)'..self.name..',"',self.type,'");') | 
|---|
|  | 408 | end | 
|---|
|  | 409 | return 1 | 
|---|
|  | 410 | end | 
|---|
|  | 411 | return 0 | 
|---|
| [1650] | 412 | end | 
|---|
|  | 413 |  | 
|---|
|  | 414 | -- Internal constructor | 
|---|
|  | 415 | function _Declaration (t) | 
|---|
|  | 416 |  | 
|---|
| [2710] | 417 | setmetatable(t,classDeclaration) | 
|---|
|  | 418 | t:buildnames() | 
|---|
|  | 419 | t:checkname() | 
|---|
|  | 420 | t:checktype() | 
|---|
|  | 421 | local ft = findtype(t.type) or t.type | 
|---|
|  | 422 | if not isenum(ft) then | 
|---|
|  | 423 | t.mod, t.type = applytypedef(t.mod, ft) | 
|---|
|  | 424 | end | 
|---|
| [1650] | 425 |  | 
|---|
| [2710] | 426 | if t.kind=="var" and (string.find(t.mod, "tolua_property%s") or string.find(t.mod, "tolua_property$")) then | 
|---|
|  | 427 | t.mod = string.gsub(t.mod, "tolua_property", "tolua_property__"..get_property_type()) | 
|---|
|  | 428 | end | 
|---|
| [1650] | 429 |  | 
|---|
| [2710] | 430 | return t | 
|---|
| [1650] | 431 | end | 
|---|
|  | 432 |  | 
|---|
|  | 433 | -- Constructor | 
|---|
|  | 434 | -- Expects the string declaration. | 
|---|
|  | 435 | -- The kind of declaration can be "var" or "func". | 
|---|
|  | 436 | function Declaration (s,kind,is_parameter) | 
|---|
|  | 437 |  | 
|---|
| [2710] | 438 | -- eliminate spaces if default value is provided | 
|---|
|  | 439 | s = gsub(s,"%s*=%s*","=") | 
|---|
|  | 440 | s = gsub(s, "%s*<", "<") | 
|---|
| [1650] | 441 |  | 
|---|
| [2710] | 442 | local defb,tmpdef | 
|---|
|  | 443 | defb,_,tmpdef = string.find(s, "(=.*)$") | 
|---|
|  | 444 | if defb then | 
|---|
|  | 445 | s = string.gsub(s, "=.*$", "") | 
|---|
|  | 446 | else | 
|---|
|  | 447 | tmpdef = '' | 
|---|
|  | 448 | end | 
|---|
|  | 449 | if kind == "var" then | 
|---|
|  | 450 | -- check the form: void | 
|---|
|  | 451 | if s == '' or s == 'void' then | 
|---|
|  | 452 | return _Declaration{type = 'void', kind = kind, is_parameter = is_parameter} | 
|---|
|  | 453 | end | 
|---|
|  | 454 | end | 
|---|
| [1650] | 455 |  | 
|---|
| [2710] | 456 | -- check the form: mod type*& name | 
|---|
|  | 457 | local t = split_c_tokens(s,'%*%s*&') | 
|---|
|  | 458 | if t.n == 2 then | 
|---|
|  | 459 | if kind == 'func' then | 
|---|
|  | 460 | error("#invalid function return type: "..s) | 
|---|
|  | 461 | end | 
|---|
|  | 462 | --local m = split(t[1],'%s%s*') | 
|---|
|  | 463 | local m = split_c_tokens(t[1],'%s+') | 
|---|
|  | 464 | return _Declaration { | 
|---|
|  | 465 | name = t[2]..tmpdef, | 
|---|
|  | 466 | ptr = '*', | 
|---|
|  | 467 | ret = '&', | 
|---|
|  | 468 | --type = rebuild_template(m[m.n], tb, timpl), | 
|---|
|  | 469 | type = m[m.n], | 
|---|
|  | 470 | mod = concat(m,1,m.n-1), | 
|---|
|  | 471 | is_parameter = is_parameter, | 
|---|
|  | 472 | kind = kind | 
|---|
|  | 473 | } | 
|---|
|  | 474 | end | 
|---|
| [1650] | 475 |  | 
|---|
| [2710] | 476 | -- check the form: mod type** name | 
|---|
|  | 477 | t = split_c_tokens(s,'%*%s*%*') | 
|---|
|  | 478 | if t.n == 2 then | 
|---|
|  | 479 | if kind == 'func' then | 
|---|
|  | 480 | error("#invalid function return type: "..s) | 
|---|
|  | 481 | end | 
|---|
|  | 482 | --local m = split(t[1],'%s%s*') | 
|---|
|  | 483 | local m = split_c_tokens(t[1],'%s+') | 
|---|
|  | 484 | return _Declaration { | 
|---|
|  | 485 | name = t[2]..tmpdef, | 
|---|
|  | 486 | ptr = '*', | 
|---|
|  | 487 | ret = '*', | 
|---|
|  | 488 | --type = rebuild_template(m[m.n], tb, timpl), | 
|---|
|  | 489 | type = m[m.n], | 
|---|
|  | 490 | mod = concat(m,1,m.n-1), | 
|---|
|  | 491 | is_parameter = is_parameter, | 
|---|
|  | 492 | kind = kind | 
|---|
|  | 493 | } | 
|---|
|  | 494 | end | 
|---|
| [1650] | 495 |  | 
|---|
| [2710] | 496 | -- check the form: mod type& name | 
|---|
|  | 497 | t = split_c_tokens(s,'&') | 
|---|
|  | 498 | if t.n == 2 then | 
|---|
|  | 499 | --local m = split(t[1],'%s%s*') | 
|---|
|  | 500 | local m = split_c_tokens(t[1],'%s+') | 
|---|
|  | 501 | return _Declaration { | 
|---|
|  | 502 | name = t[2]..tmpdef, | 
|---|
|  | 503 | ptr = '&', | 
|---|
|  | 504 | --type = rebuild_template(m[m.n], tb, timpl), | 
|---|
|  | 505 | type = m[m.n], | 
|---|
|  | 506 | mod = concat(m,1,m.n-1), | 
|---|
|  | 507 | is_parameter = is_parameter, | 
|---|
|  | 508 | kind = kind | 
|---|
|  | 509 | } | 
|---|
|  | 510 | end | 
|---|
| [1650] | 511 |  | 
|---|
| [2710] | 512 | -- check the form: mod type* name | 
|---|
|  | 513 | local s1 = gsub(s,"(%b\[\])",function (n) return gsub(n,'%*','\1') end) | 
|---|
|  | 514 | t = split_c_tokens(s1,'%*') | 
|---|
|  | 515 | if t.n == 2 then | 
|---|
|  | 516 | t[2] = gsub(t[2],'\1','%*') -- restore * in dimension expression | 
|---|
|  | 517 | --local m = split(t[1],'%s%s*') | 
|---|
|  | 518 | local m = split_c_tokens(t[1],'%s+') | 
|---|
|  | 519 | return _Declaration { | 
|---|
|  | 520 | name = t[2]..tmpdef, | 
|---|
|  | 521 | ptr = '*', | 
|---|
|  | 522 | type = m[m.n], | 
|---|
|  | 523 | --type = rebuild_template(m[m.n], tb, timpl), | 
|---|
|  | 524 | mod = concat(m,1,m.n-1)   , | 
|---|
|  | 525 | is_parameter = is_parameter, | 
|---|
|  | 526 | kind = kind | 
|---|
|  | 527 | } | 
|---|
|  | 528 | end | 
|---|
| [1650] | 529 |  | 
|---|
| [2710] | 530 | if kind == 'var' then | 
|---|
|  | 531 | -- check the form: mod type name | 
|---|
|  | 532 | --t = split(s,'%s%s*') | 
|---|
|  | 533 | t = split_c_tokens(s,'%s+') | 
|---|
|  | 534 | local v | 
|---|
|  | 535 | if findtype(t[t.n]) then v = create_varname() else v = t[t.n]; t.n = t.n-1 end | 
|---|
|  | 536 | return _Declaration { | 
|---|
|  | 537 | name = v..tmpdef, | 
|---|
|  | 538 | --type = rebuild_template(t[t.n], tb, timpl), | 
|---|
|  | 539 | type = t[t.n], | 
|---|
|  | 540 | mod = concat(t,1,t.n-1), | 
|---|
|  | 541 | is_parameter = is_parameter, | 
|---|
|  | 542 | kind = kind | 
|---|
|  | 543 | } | 
|---|
| [1650] | 544 |  | 
|---|
| [2710] | 545 | else -- kind == "func" | 
|---|
| [1650] | 546 |  | 
|---|
| [2710] | 547 | -- check the form: mod type name | 
|---|
|  | 548 | --t = split(s,'%s%s*') | 
|---|
|  | 549 | t = split_c_tokens(s,'%s+') | 
|---|
|  | 550 | local v = t[t.n]  -- last word is the function name | 
|---|
|  | 551 | local tp,md | 
|---|
|  | 552 | if t.n>1 then | 
|---|
|  | 553 | tp = t[t.n-1] | 
|---|
|  | 554 | md = concat(t,1,t.n-2) | 
|---|
|  | 555 | end | 
|---|
|  | 556 | --if tp then tp = rebuild_template(tp, tb, timpl) end | 
|---|
|  | 557 | return _Declaration { | 
|---|
|  | 558 | name = v, | 
|---|
|  | 559 | type = tp, | 
|---|
|  | 560 | mod = md, | 
|---|
|  | 561 | is_parameter = is_parameter, | 
|---|
|  | 562 | kind = kind | 
|---|
|  | 563 | } | 
|---|
|  | 564 | end | 
|---|
| [1650] | 565 |  | 
|---|
|  | 566 | end | 
|---|
|  | 567 |  | 
|---|