Changeset 2664 for code/branches/buildsystem3/src/tolua/lua
- Timestamp:
- Feb 14, 2009, 10:53:45 PM (16 years ago)
- Location:
- code/branches/buildsystem3
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/buildsystem3
- Property svn:ignore deleted
- Property svn:mergeinfo changed
-
code/branches/buildsystem3/src/tolua/lua/array.lua
r2087 r2664 21 21 -- Print method 22 22 function 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)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) 32 32 end 33 33 34 34 -- check if it is a variable 35 35 function classArray:isvariable () 36 return true36 return true 37 37 end 38 38 … … 40 40 -- get variable value 41 41 function classArray:getvalue (class,static) 42 if class and static then43 return class..'::'..self.name..'[tolua_index]'44 elseif class then45 return 'self->'..self.name..'[tolua_index]'46 else47 return self.name..'[tolua_index]'48 end42 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 49 49 end 50 50 51 51 -- Write binding functions 52 52 function 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 if t then 105 output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');') 106 else 107 t = self.type 108 if self.ptr == '&' or self.ptr == '' then 109 output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static)..',"',t,'");') 110 else 111 output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static)..',"',t,'");') 112 end 113 end 114 output(' return 1;') 115 output('}') 116 output('#endif //#ifndef TOLUA_DISABLE\n') 117 output('\n') 118 119 -- set function ------------------------------------------------ 120 if not strfind(self.type,'const') then 121 if class then 122 output("/* set function:",self.name," of class ",class," */") 123 else 124 output("/* set function:",self.name," */") 125 end 126 self.csetname = self:cfuncname("tolua_set") 127 output("#ifndef TOLUA_DISABLE_"..self.csetname) 128 output("\nstatic int",self.csetname,"(lua_State* tolua_S)") 129 output("{") 130 131 -- declare index 132 output(' int tolua_index;') 133 134 -- declare self, if the case 135 local _,_,static = strfind(self.mod,'^%s*(static)') 136 if class and static==nil then 137 output(' ',self.parent.type,'*','self;') 138 output(' lua_pushstring(tolua_S,".self");') 139 output(' lua_rawget(tolua_S,1);') 140 output(' self = ') 141 output('(',self.parent.type,'*) ') 142 output('lua_touserdata(tolua_S,-1);') 143 elseif static then 144 _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)') 145 end 146 147 -- check index 148 output('#ifndef TOLUA_RELEASE\n') 149 output(' {') 150 output(' tolua_Error tolua_err;') 151 output(' if (!tolua_isnumber(tolua_S,2,0,&tolua_err))') 152 output(' tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);') 153 output(' }') 154 output('#endif\n') 155 156 if flags['1'] then -- for compatibility with tolua5 ? 157 output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;') 158 else 159 output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);') 160 end 161 162 output('#ifndef TOLUA_RELEASE\n') 163 if self.dim and self.dim ~= '' then 164 output(' if (tolua_index<0 || tolua_index>='..self.dim..')') 165 else 166 output(' if (tolua_index<0)') 167 end 168 output(' tolua_error(tolua_S,"array indexing out of range.",NULL);') 169 output('#endif\n') 170 171 -- assign value 172 local ptr = '' 173 if self.ptr~='' then ptr = '*' end 174 output(' ') 175 if class and static then 176 output(class..'::'..self.name..'[tolua_index]') 177 elseif class then 178 output('self->'..self.name..'[tolua_index]') 179 else 180 output(self.name..'[tolua_index]') 181 end 182 local t = isbasic(self.type) 183 output(' = ') 184 if not t and ptr=='' then output('*') end 185 output('((',self.mod,self.type) 186 if not t then 187 output('*') 188 end 189 output(') ') 190 local def = 0 191 if self.def ~= '' then def = self.def end 192 if t then 193 output('tolua_to'..t,'(tolua_S,3,',def,'));') 194 else 195 output('tolua_tousertype(tolua_S,3,',def,'));') 196 end 197 output(' return 0;') 198 output('}') 199 output('#endif //#ifndef TOLUA_DISABLE\n') 200 output('\n') 201 end 202 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 if t then 105 output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');') 106 else 107 t = self.type 108 if self.ptr == '&' or self.ptr == '' then 109 output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static)..',"',t,'");') 110 else 111 output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static)..',"',t,'");') 112 end 113 end 114 output(' return 1;') 115 output('}') 116 output('#endif //#ifndef TOLUA_DISABLE\n') 117 output('\n') 118 119 -- set function ------------------------------------------------ 120 if not strfind(self.type,'const') then 121 if class then 122 output("/* set function:",self.name," of class ",class," */") 123 else 124 output("/* set function:",self.name," */") 125 end 126 self.csetname = self:cfuncname("tolua_set") 127 output("#ifndef TOLUA_DISABLE_"..self.csetname) 128 output("\nstatic int",self.csetname,"(lua_State* tolua_S)") 129 output("{") 130 131 -- declare index 132 output(' int tolua_index;') 133 134 -- declare self, if the case 135 local _,_,static = strfind(self.mod,'^%s*(static)') 136 if class and static==nil then 137 output(' ',self.parent.type,'*','self;') 138 output(' lua_pushstring(tolua_S,".self");') 139 output(' lua_rawget(tolua_S,1);') 140 output(' self = ') 141 output('(',self.parent.type,'*) ') 142 output('lua_touserdata(tolua_S,-1);') 143 elseif static then 144 _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)') 145 end 146 147 -- check index 148 output('#ifndef TOLUA_RELEASE\n') 149 output(' {') 150 output(' tolua_Error tolua_err;') 151 output(' if (!tolua_isnumber(tolua_S,2,0,&tolua_err))') 152 output(' tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);') 153 output(' }') 154 output('#endif\n') 155 156 if flags['1'] then -- for compatibility with tolua5 ? 157 output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;') 158 else 159 output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);') 160 end 161 162 output('#ifndef TOLUA_RELEASE\n') 163 if self.dim and self.dim ~= '' then 164 output(' if (tolua_index<0 || tolua_index>='..self.dim..')') 165 else 166 output(' if (tolua_index<0)') 167 end 168 output(' tolua_error(tolua_S,"array indexing out of range.",NULL);') 169 output('#endif\n') 170 171 -- assign value 172 local ptr = '' 173 if self.ptr~='' then ptr = '*' end 174 output(' ') 175 if class and static then 176 output(class..'::'..self.name..'[tolua_index]') 177 elseif class then 178 output('self->'..self.name..'[tolua_index]') 179 else 180 output(self.name..'[tolua_index]') 181 end 182 local t = isbasic(self.type) 183 output(' = ') 184 if not t and ptr=='' then output('*') end 185 output('((',self.mod,self.type) 186 if not t then 187 output('*') 188 end 189 output(') ') 190 local def = 0 191 if self.def ~= '' then def = self.def end 192 if t then 193 output('tolua_to'..t,'(tolua_S,3,',def,'));') 194 else 195 output('tolua_tousertype(tolua_S,3,',def,'));') 196 end 197 output(' return 0;') 198 output('}') 199 output('#endif //#ifndef TOLUA_DISABLE\n') 200 output('\n') 201 end 203 202 end 204 203 205 204 function classArray:register (pre) 206 pre = pre or ''207 if self.csetname then208 output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')209 else210 output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')211 end205 pre = pre or '' 206 if self.csetname then 207 output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');') 208 else 209 output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);') 210 end 212 211 end 213 212 214 213 -- Internal constructor 215 214 function _Array (t) 216 setmetatable(t,classArray)217 append(t)218 return t215 setmetatable(t,classArray) 216 append(t) 217 return t 219 218 end 220 219 … … 222 221 -- Expects a string representing the variable declaration. 223 222 function Array (s) 224 return _Array (Declaration(s,'var'))225 end 226 227 223 return _Array (Declaration(s,'var')) 224 end 225 226 -
code/branches/buildsystem3/src/tolua/lua/basic.lua
r2087 r2664 16 16 -- and all occurrences of "void*" will be replaced by "_userdata" 17 17 _basic = { 18 ['void'] = '',19 ['char'] = 'number',20 ['int'] = 'number',21 ['short'] = 'number',22 ['long'] = 'number',23 ['unsigned'] = 'number',24 ['float'] = 'number',25 ['double'] = 'number',26 ['_cstring'] = 'string',27 ['_userdata'] = 'userdata',28 ['char*'] = 'string',29 ['void*'] = 'userdata',30 ['bool'] = 'boolean',31 ['lua_Object'] = 'value',32 ['LUA_VALUE'] = 'value', -- for compatibility with tolua 4.033 ['lua_State*'] = 'state',34 ['_lstate'] = 'state',35 ['lua_Function'] = 'value',18 ['void'] = '', 19 ['char'] = 'number', 20 ['int'] = 'number', 21 ['short'] = 'number', 22 ['long'] = 'number', 23 ['unsigned'] = 'number', 24 ['float'] = 'number', 25 ['double'] = 'number', 26 ['_cstring'] = 'string', 27 ['_userdata'] = 'userdata', 28 ['char*'] = 'string', 29 ['void*'] = 'userdata', 30 ['bool'] = 'boolean', 31 ['lua_Object'] = 'value', 32 ['LUA_VALUE'] = 'value', -- for compatibility with tolua 4.0 33 ['lua_State*'] = 'state', 34 ['_lstate'] = 'state', 35 ['lua_Function'] = 'value', 36 36 } 37 37 38 38 _basic_ctype = { 39 number = "lua_Number",40 string = "const char*",41 userdata = "void*",42 boolean = "bool",43 value = "int",44 state = "lua_State*",39 number = "lua_Number", 40 string = "const char*", 41 userdata = "void*", 42 boolean = "bool", 43 value = "int", 44 state = "lua_State*", 45 45 } 46 46 … … 68 68 _renaming = {} 69 69 function appendrenaming (s) 70 local b,e,old,new = strfind(s,"%s*(.-)%s*@%s*(.-)%s*$")71 72 73 74 70 local b,e,old,new = strfind(s,"%s*(.-)%s*@%s*(.-)%s*$") 71 if not b then 72 error("#Invalid renaming syntax; it should be of the form: pattern@pattern") 73 end 74 tinsert(_renaming,{old=old, new=new}) 75 75 end 76 76 77 77 function applyrenaming (s) 78 79 80 81 82 83 84 78 for i=1,getn(_renaming) do 79 local m,n = gsub(s,_renaming[i].old,_renaming[i].new) 80 if n ~= 0 then 81 return m 82 end 83 end 84 return nil 85 85 end 86 86 87 87 -- Error handler 88 88 function tolua_error (s,f) 89 if _curr_code then90 91 92 end93 local out = _OUTPUT94 _OUTPUT = _STDERR95 if strsub(s,1,1) == '#' then96 write("\n** tolua: "..strsub(s,2)..".\n\n")97 if _curr_code then98 local _,_,s = strfind(_curr_code,"^%s*(.-\n)") -- extract first line99 if s==nil then s = _curr_code end100 s = gsub(s,"_userdata","void*") -- return with 'void*'101 s = gsub(s,"_cstring","char*") -- return with 'char*'102 s = gsub(s,"_lstate","lua_State*") -- return with 'lua_State*'103 write("Code being processed:\n"..s.."\n")104 end105 else106 if not f then f = "(f is nil)" end107 print("\n** tolua internal error: "..f..s..".\n\n")108 return109 end110 _OUTPUT = out89 if _curr_code then 90 print("***curr code for error is "..tostring(_curr_code)) 91 print(debug.traceback()) 92 end 93 local out = _OUTPUT 94 _OUTPUT = _STDERR 95 if strsub(s,1,1) == '#' then 96 write("\n** tolua: "..strsub(s,2)..".\n\n") 97 if _curr_code then 98 local _,_,s = strfind(_curr_code,"^%s*(.-\n)") -- extract first line 99 if s==nil then s = _curr_code end 100 s = gsub(s,"_userdata","void*") -- return with 'void*' 101 s = gsub(s,"_cstring","char*") -- return with 'char*' 102 s = gsub(s,"_lstate","lua_State*") -- return with 'lua_State*' 103 write("Code being processed:\n"..s.."\n") 104 end 105 else 106 if not f then f = "(f is nil)" end 107 print("\n** tolua internal error: "..f..s..".\n\n") 108 return 109 end 110 _OUTPUT = out 111 111 end 112 112 113 113 function warning (msg) 114 local out = _OUTPUT115 _OUTPUT = _STDERR116 write("\n** tolua warning: "..msg..".\n\n")117 _OUTPUT = out114 local out = _OUTPUT 115 _OUTPUT = _STDERR 116 write("\n** tolua warning: "..msg..".\n\n") 117 _OUTPUT = out 118 118 end 119 119 120 120 -- register an user defined type: returns full type 121 121 function regtype (t) 122 123 --return t124 125 126 127 128 129 130 122 --if isbasic(t) then 123 -- return t 124 --end 125 local ft = findtype(t) 126 127 if not _usertype[ft] then 128 return appendusertype(t) 129 end 130 return ft 131 131 end 132 132 133 133 -- return type name: returns full type 134 134 function typevar(type) 135 136 137 138 139 140 141 142 143 144 135 if type == '' or type == 'void' then 136 return type 137 else 138 local ft = findtype(type) 139 if ft then 140 return ft 141 end 142 _usertype[type] = type 143 return type 144 end 145 145 end 146 146 147 147 -- check if basic type 148 148 function isbasic (type) 149 local t = gsub(type,'const ','')150 local m,t = applytypedef('', t)151 local b = _basic[t]152 if b then153 return b,_basic_ctype[b]154 end155 return nil149 local t = gsub(type,'const ','') 150 local m,t = applytypedef('', t) 151 local b = _basic[t] 152 if b then 153 return b,_basic_ctype[b] 154 end 155 return nil 156 156 end 157 157 158 158 -- split string using a token 159 159 function split (s,t) 160 local l = {n=0}161 local f = function (s)162 l.n = l.n + 1163 l[l.n] = s164 return ""165 end166 local p = "%s*(.-)%s*"..t.."%s*"167 s = gsub(s,"^%s+","")168 s = gsub(s,"%s+$","")169 s = gsub(s,p,f)170 l.n = l.n + 1171 l[l.n] = gsub(s,"(%s%s*)$","")172 return l160 local l = {n=0} 161 local f = function (s) 162 l.n = l.n + 1 163 l[l.n] = s 164 return "" 165 end 166 local p = "%s*(.-)%s*"..t.."%s*" 167 s = gsub(s,"^%s+","") 168 s = gsub(s,"%s+$","") 169 s = gsub(s,p,f) 170 l.n = l.n + 1 171 l[l.n] = gsub(s,"(%s%s*)$","") 172 return l 173 173 end 174 174 … … 178 178 function split_c_tokens(s, pat) 179 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 --ret.n=1231 --ret[1] = ""232 233 234 180 s = string.gsub(s, "^%s*", "") 181 s = string.gsub(s, "%s*$", "") 182 183 local token_begin = 1 184 local token_end = 1 185 local ofs = 1 186 local ret = {n=0} 187 188 function add_token(ofs) 189 190 local t = string.sub(s, token_begin, ofs) 191 t = string.gsub(t, "^%s*", "") 192 t = string.gsub(t, "%s*$", "") 193 ret.n = ret.n + 1 194 ret[ret.n] = t 195 end 196 197 while ofs <= string.len(s) do 198 199 local sub = string.sub(s, ofs, -1) 200 local b,e = string.find(sub, "^"..pat) 201 if b then 202 add_token(ofs-1) 203 ofs = ofs+e 204 token_begin = ofs 205 else 206 local char = string.sub(s, ofs, ofs) 207 if char == "(" or char == "<" then 208 209 local block 210 if char == "(" then block = "^%b()" end 211 if char == "<" then block = "^%b<>" end 212 213 b,e = string.find(sub, block) 214 if not b then 215 -- unterminated block? 216 ofs = ofs+1 217 else 218 ofs = ofs + e 219 end 220 221 else 222 ofs = ofs+1 223 end 224 end 225 226 end 227 add_token(ofs) 228 --if ret.n == 0 then 229 230 -- ret.n=1 231 -- ret[1] = "" 232 --end 233 234 return ret 235 235 236 236 end … … 238 238 -- concatenate strings of a table 239 239 function concat (t,f,l,jstr) 240 241 local s = ''242 local i=f243 while i<=l do244 s = s..t[i]245 i = i+1246 if i <= l then s = s..jstr end247 end248 return s240 jstr = jstr or " " 241 local s = '' 242 local i=f 243 while i<=l do 244 s = s..t[i] 245 i = i+1 246 if i <= l then s = s..jstr end 247 end 248 return s 249 249 end 250 250 251 251 -- concatenate all parameters, following output rules 252 252 function concatparam (line, ...) 253 local i=1254 while i<=arg.n do255 if _cont and not strfind(_cont,'[%(,"]') and256 strfind(arg[i],"^[%a_~]") then257 258 end259 line = line .. arg[i]260 if arg[i] ~= '' then261 _cont = strsub(arg[i],-1,-1)262 end263 i = i+1264 end265 if strfind(arg[arg.n],"[%/%)%;%{%}]$") then266 _cont=nil line = line .. '\n'267 end268 253 local i=1 254 while i<=arg.n do 255 if _cont and not strfind(_cont,'[%(,"]') and 256 strfind(arg[i],"^[%a_~]") then 257 line = line .. ' ' 258 end 259 line = line .. arg[i] 260 if arg[i] ~= '' then 261 _cont = strsub(arg[i],-1,-1) 262 end 263 i = i+1 264 end 265 if strfind(arg[arg.n],"[%/%)%;%{%}]$") then 266 _cont=nil line = line .. '\n' 267 end 268 return line 269 269 end 270 270 271 271 -- output line 272 272 function output (...) 273 local i=1274 while i<=arg.n do275 if _cont and not strfind(_cont,'[%(,"]') and276 strfind(arg[i],"^[%a_~]") then277 278 end279 write(arg[i])280 if arg[i] ~= '' then281 _cont = strsub(arg[i],-1,-1)282 end283 i = i+1284 end285 if strfind(arg[arg.n],"[%/%)%;%{%}]$") then286 _cont=nil write('\n')287 end273 local i=1 274 while i<=arg.n do 275 if _cont and not strfind(_cont,'[%(,"]') and 276 strfind(arg[i],"^[%a_~]") then 277 write(' ') 278 end 279 write(arg[i]) 280 if arg[i] ~= '' then 281 _cont = strsub(arg[i],-1,-1) 282 end 283 i = i+1 284 end 285 if strfind(arg[arg.n],"[%/%)%;%{%}]$") then 286 _cont=nil write('\n') 287 end 288 288 end 289 289 290 290 function get_property_methods(ptype, name) 291 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 292 if get_property_methods_hook and get_property_methods_hook(ptype,name) then 293 return get_property_methods_hook(ptype, name) 294 end 295 296 if ptype == "default" then -- get_name, set_name 297 return "get_"..name, "set_"..name 298 end 299 300 if ptype == "qt" then -- name, setName 301 return name, "set"..string.upper(string.sub(name, 1, 1))..string.sub(name, 2, -1) 302 end 303 304 if ptype == "overload" then -- name, name 305 return name,name 306 end 307 308 return nil 309 309 end 310 310 … … 315 315 -- takes the package object as the parameter 316 316 function preprocess_hook(p) 317 317 -- p.code has all the input code from the pkg 318 318 end 319 319 … … 351 351 function parser_hook(s) 352 352 353 354 end 355 356 353 return nil 354 end 355 356 -
code/branches/buildsystem3/src/tolua/lua/class.lua
r2087 r2664 18 18 -- {i} = list of members 19 19 classClass = { 20 classtype = 'class',21 name = '',22 base = '',23 type = '',24 btype = '',25 ctype = '',20 classtype = 'class', 21 name = '', 22 base = '', 23 type = '', 24 btype = '', 25 ctype = '', 26 26 } 27 27 classClass.__index = classClass … … 31 31 -- register class 32 32 function classClass:register (pre) 33 34 35 36 37 pre = pre or ''38 push(self)39 40 41 output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",'.._collect[self.type]..');')42 43 output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')44 45 46 output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')47 48 49 50 51 --output(pre..' tolua_addbase(tolua_S, "'..self.type..'", "'..base..'");')52 53 54 output(pre..'tolua_beginmodule(tolua_S,"'..self.lname..'");')55 local i=156 while self[i] do57 self[i]:register(pre..' ')58 i = i+159 end60 output(pre..'tolua_endmodule(tolua_S);')61 33 if not self:check_public_access() then 34 return 35 end 36 37 pre = pre or '' 38 push(self) 39 if _collect[self.type] then 40 output(pre,'#ifdef __cplusplus\n') 41 output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",'.._collect[self.type]..');') 42 output(pre,'#else\n') 43 output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);') 44 output(pre,'#endif\n') 45 else 46 output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);') 47 end 48 if self.extra_bases then 49 for k,base in ipairs(self.extra_bases) do 50 -- not now 51 --output(pre..' tolua_addbase(tolua_S, "'..self.type..'", "'..base..'");') 52 end 53 end 54 output(pre..'tolua_beginmodule(tolua_S,"'..self.lname..'");') 55 local i=1 56 while self[i] do 57 self[i]:register(pre..' ') 58 i = i+1 59 end 60 output(pre..'tolua_endmodule(tolua_S);') 61 pop() 62 62 end 63 63 64 64 -- return collection requirement 65 65 function classClass:requirecollection (t) 66 67 68 69 push(self)70 71 local i=172 while self[i] do73 r = self[i]:requirecollection(t) or r74 i = i+175 end76 77 78 79 80 81 82 83 84 return r66 if self.flags.protected_destructor then 67 return false 68 end 69 push(self) 70 local r = false 71 local i=1 72 while self[i] do 73 r = self[i]:requirecollection(t) or r 74 i = i+1 75 end 76 pop() 77 -- only class that exports destructor can be appropriately collected 78 -- classes that export constructors need to have a collector (overrided by -D flag on command line) 79 if self._delete or ((not flags['D']) and self._new) then 80 --t[self.type] = "tolua_collect_" .. gsub(self.type,"::","_") 81 t[self.type] = "tolua_collect_" .. clean_template(self.type) 82 r = true 83 end 84 return r 85 85 end 86 86 87 87 -- output tags 88 88 function classClass:decltype () 89 push(self)90 91 92 93 94 95 96 97 98 local i=199 while self[i] do100 self[i]:decltype()101 i = i+1102 end103 89 push(self) 90 self.type = regtype(self.original_name or self.name) 91 self.btype = typevar(self.base) 92 self.ctype = 'const '..self.type 93 if self.extra_bases then 94 for i=1,table.getn(self.extra_bases) do 95 self.extra_bases[i] = typevar(self.extra_bases[i]) 96 end 97 end 98 local i=1 99 while self[i] do 100 self[i]:decltype() 101 i = i+1 102 end 103 pop() 104 104 end 105 105 … … 107 107 -- Print method 108 108 function classClass:print (ident,close) 109 print(ident.."Class{")110 print(ident.." name = '"..self.name.."',")111 print(ident.." base = '"..self.base.."';")112 print(ident.." lname = '"..self.lname.."',")113 print(ident.." type = '"..self.type.."',")114 print(ident.." btype = '"..self.btype.."',")115 print(ident.." ctype = '"..self.ctype.."',")116 local i=1117 while self[i] do118 self[i]:print(ident.." ",",")119 i = i+1120 end121 print(ident.."}"..close)109 print(ident.."Class{") 110 print(ident.." name = '"..self.name.."',") 111 print(ident.." base = '"..self.base.."';") 112 print(ident.." lname = '"..self.lname.."',") 113 print(ident.." type = '"..self.type.."',") 114 print(ident.." btype = '"..self.btype.."',") 115 print(ident.." ctype = '"..self.ctype.."',") 116 local i=1 117 while self[i] do 118 self[i]:print(ident.." ",",") 119 i = i+1 120 end 121 print(ident.."}"..close) 122 122 end 123 123 124 124 function classClass:set_protected_destructor(p) 125 125 self.flags.protected_destructor = self.flags.protected_destructor or p 126 126 end 127 127 128 128 -- Internal constructor 129 129 function _Class (t) 130 setmetatable(t,classClass)131 t:buildnames()132 append(t)133 return t130 setmetatable(t,classClass) 131 t:buildnames() 132 append(t) 133 return t 134 134 end 135 135 … … 138 138 function Class (n,p,b) 139 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 end 220 140 if table.getn(p) > 1 then 141 b = string.sub(b, 1, -2) 142 for i=2,table.getn(p),1 do 143 b = b.."\n tolua_inherits "..p[i].." __"..p[i].."__;\n" 144 end 145 b = b.."\n}" 146 end 147 148 -- check for template 149 b = string.gsub(b, "^{%s*TEMPLATE_BIND", "{\nTOLUA_TEMPLATE_BIND") 150 local t,_,T,I = string.find(b, "^{%s*TOLUA_TEMPLATE_BIND%s*%(+%s*\"?([^\",]*)\"?%s*,%s*([^%)]*)%s*%)+") 151 if t then 152 153 -- remove quotes 154 I = string.gsub(I, "\"", "") 155 T = string.gsub(T, "\"", "") 156 -- get type list 157 local types = split_c_tokens(I, ",") 158 -- remove TEMPLATE_BIND line 159 local bs = string.gsub(b, "^{%s*TOLUA_TEMPLATE_BIND[^\n]*\n", "{\n") 160 161 -- replace 162 for i =1 , types.n do 163 164 local Tl = split(T, " ") 165 local Il = split_c_tokens(types[i], " ") 166 local bI = bs 167 local pI = {} 168 for j = 1,Tl.n do 169 Tl[j] = findtype(Tl[j]) or Tl[j] 170 bI = string.gsub(bI, "([^_%w])"..Tl[j].."([^_%w])", "%1"..Il[j].."%2") 171 if p then 172 for i=1,table.getn(p) do 173 pI[i] = string.gsub(p[i], "([^_%w]?)"..Tl[j].."([^_%w]?)", "%1"..Il[j].."%2") 174 end 175 end 176 end 177 --local append = "<"..string.gsub(types[i], "%s+", ",")..">" 178 local append = "<"..concat(Il, 1, table.getn(Il), ",")..">" 179 append = string.gsub(append, "%s*,%s*", ",") 180 append = string.gsub(append, ">>", "> >") 181 for i=1,table.getn(pI) do 182 --pI[i] = string.gsub(pI[i], ">>", "> >") 183 pI[i] = resolve_template_types(pI[i]) 184 end 185 bI = string.gsub(bI, ">>", "> >") 186 Class(n..append, pI, bI) 187 end 188 return 189 end 190 191 local mbase 192 193 if p then 194 mbase = table.remove(p, 1) 195 if not p[1] then p = nil end 196 end 197 198 mbase = mbase and resolve_template_types(mbase) 199 200 local c 201 local oname = string.gsub(n, "@.*$", "") 202 oname = getnamespace(classContainer.curr)..oname 203 204 if _global_classes[oname] then 205 c = _global_classes[oname] 206 if mbase and ((not c.base) or c.base == "") then 207 c.base = mbase 208 end 209 else 210 c = _Class(_Container{name=n, base=mbase, extra_bases=p}) 211 212 local ft = getnamespace(c.parent)..c.original_name 213 append_global_type(ft, c) 214 end 215 216 push(c) 217 c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces 218 pop() 219 end 220 -
code/branches/buildsystem3/src/tolua/lua/clean.lua
r2087 r2664 10 10 11 11 MASK = { -- the substitution order is important 12 {ESC1, "\\'"},13 {ESC2, '\\"'},14 {STR1, "'"},15 {STR2, '"'},16 {STR3, "%[%["},17 {STR4, "%]%]"},18 {REM , "%-%-"},12 {ESC1, "\\'"}, 13 {ESC2, '\\"'}, 14 {STR1, "'"}, 15 {STR2, '"'}, 16 {STR3, "%[%["}, 17 {STR4, "%]%]"}, 18 {REM , "%-%-"}, 19 19 } 20 20 21 21 function mask (s) 22 for i = 1,getn(MASK) do23 s = gsub(s,MASK[i][2],MASK[i][1])24 end25 return s22 for i = 1,getn(MASK) do 23 s = gsub(s,MASK[i][2],MASK[i][1]) 24 end 25 return s 26 26 end 27 27 28 28 function unmask (s) 29 for i = 1,getn(MASK) do30 s = gsub(s,MASK[i][1],MASK[i][2])31 end32 return s29 for i = 1,getn(MASK) do 30 s = gsub(s,MASK[i][1],MASK[i][2]) 31 end 32 return s 33 33 end 34 34 35 35 function clean (s) 36 -- check for compilation error37 local code = "return function ()\n" .. s .. "\n end"38 if not dostring(code) then39 return nil40 end36 -- check for compilation error 37 local code = "return function ()\n" .. s .. "\n end" 38 if not dostring(code) then 39 return nil 40 end 41 41 42 if flags['C'] then43 44 end42 if flags['C'] then 43 return s 44 end 45 45 46 local S = "" -- saved string46 local S = "" -- saved string 47 47 48 s = mask(s)48 s = mask(s) 49 49 50 -- remove blanks and comments51 while 1 do52 local b,e,d = strfind(s,ANY)53 if b then54 S = S..strsub(s,1,b-1)55 s = strsub(s,b+1)56 if d==STR1 or d==STR2 then57 e = strfind(s,d)58 S = S ..d..strsub(s,1,e)59 s = strsub(s,e+1)60 elseif d==STR3 then61 e = strfind(s,STR4)62 S = S..d..strsub(s,1,e)63 s = strsub(s,e+1)64 elseif d==REM then65 s = gsub(s,"[^\n]*(\n?)","%1",1)66 end67 else68 S = S..s69 break70 end71 end72 -- eliminate unecessary spaces73 S = gsub(S,"[ \t]+"," ")74 S = gsub(S,"[ \t]*\n[ \t]*","\n")75 76 S = unmask(S)77 return S50 -- remove blanks and comments 51 while 1 do 52 local b,e,d = strfind(s,ANY) 53 if b then 54 S = S..strsub(s,1,b-1) 55 s = strsub(s,b+1) 56 if d==STR1 or d==STR2 then 57 e = strfind(s,d) 58 S = S ..d..strsub(s,1,e) 59 s = strsub(s,e+1) 60 elseif d==STR3 then 61 e = strfind(s,STR4) 62 S = S..d..strsub(s,1,e) 63 s = strsub(s,e+1) 64 elseif d==REM then 65 s = gsub(s,"[^\n]*(\n?)","%1",1) 66 end 67 else 68 S = S..s 69 break 70 end 71 end 72 -- eliminate unecessary spaces 73 S = gsub(S,"[ \t]+"," ") 74 S = gsub(S,"[ \t]*\n[ \t]*","\n") 75 S = gsub(S,"\n+","\n") 76 S = unmask(S) 77 return S 78 78 end 79 79 -
code/branches/buildsystem3/src/tolua/lua/code.lua
r2087 r2664 19 19 -- text = text code 20 20 classCode = { 21 text = '',21 text = '', 22 22 } 23 23 classCode.__index = classCode … … 26 26 -- register code 27 27 function classCode:register (pre) 28 pre = pre or ''29 -- clean Lua code30 local s = clean(self.text)31 if not s then32 --print(self.text)33 error("parser error in embedded code")34 end28 pre = pre or '' 29 -- clean Lua code 30 local s = clean(self.text) 31 if not s then 32 --print(self.text) 33 error("parser error in embedded code") 34 end 35 35 36 -- get first line37 local _, _, first_line=string.find(self.text, "^([^\n\r]*)")38 if string.find(first_line, "^%s*%-%-") then39 40 41 42 43 44 45 else46 47 end36 -- get first line 37 local _, _, first_line=string.find(self.text, "^([^\n\r]*)") 38 if string.find(first_line, "^%s*%-%-") then 39 if string.find(first_line, "^%-%-##") then 40 first_line = string.gsub(first_line, "^%-%-##", "") 41 if flags['C'] then 42 s = string.gsub(s, "^%-%-##[^\n\r]*\n", "") 43 end 44 end 45 else 46 first_line = "" 47 end 48 48 49 -- convert to C 50 output('\n'..pre..'{ /* begin embedded lua code */\n') 51 output(pre..' int top = lua_gettop(tolua_S);') 52 output(pre..' static unsigned char B[] = {\n ') 53 local t={n=0} 54 local b = gsub(s,'(.)',function (c) 55 local e = '' 56 t.n=t.n+1 if t.n==15 then t.n=0 e='\n'..pre..' ' end 57 return format('%3u,%s',strbyte(c),e) 58 end 59 ) 60 output(b..strbyte(" ")) 61 output('\n'..pre..' };\n') 62 if first_line and first_line ~= "" then 63 output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: '..first_line..'");') 64 else 65 output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua: embedded Lua code '..code_n..'");') 66 end 67 output(pre..' lua_settop(tolua_S, top);') 68 output(pre..'} /* end of embedded lua code */\n\n') 69 code_n = code_n +1 49 -- convert to C 50 output('\n'..pre..'{ /* begin embedded lua code */\n') 51 output(pre..' int top = lua_gettop(tolua_S);') 52 output(pre..' static unsigned char B[] = {\n ') 53 local t={n=0} 54 local b = gsub(s, '(.)', 55 function (c) 56 local e = '' 57 t.n=t.n+1 58 if t.n==15 then 59 t.n=0 e='\n'..pre..' ' 60 end 61 return format('%3u,%s',strbyte(c),e) 62 end 63 ) 64 output(b..strbyte(" ")) 65 output('\n'..pre..' };\n') 66 if first_line and first_line ~= "" then 67 output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: '..first_line..'");') 68 else 69 output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua: embedded Lua code '..code_n..'");') 70 end 71 output(pre..' lua_settop(tolua_S, top);') 72 output(pre..'} /* end of embedded lua code */\n\n') 73 code_n = code_n +1 70 74 end 71 75 … … 73 77 -- Print method 74 78 function classCode:print (ident,close) 75 print(ident.."Code{")76 print(ident.." text = [["..self.text.."]],")77 print(ident.."}"..close)79 print(ident.."Code{") 80 print(ident.." text = [["..self.text.."]],") 81 print(ident.."}"..close) 78 82 end 79 83 … … 81 85 -- Internal constructor 82 86 function _Code (t) 83 setmetatable(t,classCode)84 append(t)85 return t87 setmetatable(t,classCode) 88 append(t) 89 return t 86 90 end 87 91 … … 89 93 -- Expects a string representing the code text 90 94 function Code (l) 91 return _Code {92 text = l93 }95 return _Code { 96 text = l 97 } 94 98 end 95 99 -
code/branches/buildsystem3/src/tolua/lua/compat-5.1.lua
r2087 r2664 1 1 if string.find(_VERSION, "5%.0") then 2 2 return 3 3 end 4 4 5 5 -- "loadfile" 6 6 local function pp_dofile(path) 7 local loaded = false 8 local getfile = function() 7 9 8 local loaded = false 9 local getfile = function() 10 if loaded then 11 return 12 else 13 local file,err = io.open(path) 14 if not file then 15 error("error loading file "..path..": "..err) 16 end 17 local ret = file:read("*a") 18 file:close() 10 19 11 if loaded then 12 return 13 else 14 local file,err = io.open(path) 15 if not file then 16 error("error loading file "..path..": "..err) 17 end 18 local ret = file:read("*a") 19 file:close() 20 ret = string.gsub(ret, "%.%.%.%s*%)", "...) local arg = {n=select('#', ...), ...};") 20 21 21 ret = string.gsub(ret, "%.%.%.%s*%)", "...) local arg = {n=select('#', ...), ...};") 22 loaded = true 23 return ret 24 end 25 end 22 26 23 loaded = true 24 return ret 25 end 26 end 27 28 local f = load(getfile, path) 29 return f() 27 local f = load(getfile, path) 28 return f() 30 29 end 31 30 … … 38 37 local ogsub = string.gsub 39 38 local function compgsub(a,b,c,d) 40 if type(c) == "function" then41 local oc = c42 c = function (...) return oc(...) or '' end43 end44 return ogsub(a,b,c,d)39 if type(c) == "function" then 40 local oc = c 41 c = function (...) return oc(...) or '' end 42 end 43 return ogsub(a,b,c,d) 45 44 end 46 45 string.repl = ogsub -
code/branches/buildsystem3/src/tolua/lua/compat.lua
r2087 r2664 34 34 35 35 function do_ (f, err) 36 if not f then print(err); return end37 local a,b = pcall(f)38 if not a then print(b); return nil39 else return b or true40 end36 if not f then print(err); return end 37 local a,b = pcall(f) 38 if not a then print(b); return nil 39 else return b or true 40 end 41 41 end 42 42 … … 141 141 142 142 function flush (f) 143 if f then f:flush()144 else _OUTPUT:flush()145 end143 if f then f:flush() 144 else _OUTPUT:flush() 145 end 146 146 end 147 147 148 148 function readfrom (name) 149 if name == nil then150 local f, err, cod = io.close(_INPUT)151 _INPUT = io.stdin152 return f, err, cod153 else154 local f, err, cod = io.open(name, "r")155 _INPUT = f or _INPUT156 return f, err, cod157 end149 if name == nil then 150 local f, err, cod = io.close(_INPUT) 151 _INPUT = io.stdin 152 return f, err, cod 153 else 154 local f, err, cod = io.open(name, "r") 155 _INPUT = f or _INPUT 156 return f, err, cod 157 end 158 158 end 159 159 160 160 function writeto (name) 161 if name == nil then162 local f, err, cod = io.close(_OUTPUT)163 _OUTPUT = io.stdout164 return f, err, cod165 else166 local f, err, cod = io.open(name, "w")167 _OUTPUT = f or _OUTPUT168 return f, err, cod169 end161 if name == nil then 162 local f, err, cod = io.close(_OUTPUT) 163 _OUTPUT = io.stdout 164 return f, err, cod 165 else 166 local f, err, cod = io.open(name, "w") 167 _OUTPUT = f or _OUTPUT 168 return f, err, cod 169 end 170 170 end 171 171 172 172 function appendto (name) 173 local f, err, cod = io.open(name, "a")174 _OUTPUT = f or _OUTPUT175 return f, err, cod173 local f, err, cod = io.open(name, "a") 174 _OUTPUT = f or _OUTPUT 175 return f, err, cod 176 176 end 177 177 178 178 function read (...) 179 local f = _INPUT180 if rawtype(arg[1]) == 'userdata' then181 f = tab.remove(arg, 1)182 end183 return f:read(unpack(arg))179 local f = _INPUT 180 if rawtype(arg[1]) == 'userdata' then 181 f = tab.remove(arg, 1) 182 end 183 return f:read(unpack(arg)) 184 184 end 185 185 186 186 function write (...) 187 local f = _OUTPUT188 if rawtype(arg[1]) == 'userdata' then189 f = tab.remove(arg, 1)190 end191 return f:write(unpack(arg))187 local f = _OUTPUT 188 if rawtype(arg[1]) == 'userdata' then 189 f = tab.remove(arg, 1) 190 end 191 return f:write(unpack(arg)) 192 192 end 193 193 -
code/branches/buildsystem3/src/tolua/lua/container.lua
r2087 r2664 19 19 classContainer = 20 20 { 21 curr = nil,21 curr = nil, 22 22 } 23 23 classContainer.__index = classContainer … … 26 26 -- output tags 27 27 function classContainer:decltype () 28 push(self)29 local i=130 while self[i] do31 self[i]:decltype()32 i = i+133 end34 pop()28 push(self) 29 local i=1 30 while self[i] do 31 self[i]:decltype() 32 i = i+1 33 end 34 pop() 35 35 end 36 36 … … 39 39 function classContainer:supcode () 40 40 41 42 43 44 45 push(self)46 local i=147 while self[i] do48 if self[i]:check_public_access() then49 50 end51 i = i+152 end53 pop()41 if not self:check_public_access() then 42 return 43 end 44 45 push(self) 46 local i=1 47 while self[i] do 48 if self[i]:check_public_access() then 49 self[i]:supcode() 50 end 51 i = i+1 52 end 53 pop() 54 54 end 55 55 56 56 function classContainer:hasvar () 57 local i=158 while self[i] do59 if self[i]:isvariable() then60 61 62 i = i+163 end64 57 local i=1 58 while self[i] do 59 if self[i]:isvariable() then 60 return 1 61 end 62 i = i+1 63 end 64 return 0 65 65 end 66 66 67 67 -- Internal container constructor 68 68 function _Container (self) 69 setmetatable(self,classContainer)70 self.n = 071 self.typedefs = {tolua_n=0}72 self.usertypes = {}73 self.enums = {tolua_n=0}74 self.lnames = {}75 return self69 setmetatable(self,classContainer) 70 self.n = 0 71 self.typedefs = {tolua_n=0} 72 self.usertypes = {} 73 self.enums = {tolua_n=0} 74 self.lnames = {} 75 return self 76 76 end 77 77 78 78 -- push container 79 79 function push (t) 80 81 classContainer.curr = t80 t.prox = classContainer.curr 81 classContainer.curr = t 82 82 end 83 83 84 84 -- pop container 85 85 function pop () 86 --print("name",classContainer.curr.name)87 --foreach(classContainer.curr.usertypes,print)88 --print("______________")89 classContainer.curr = classContainer.curr.prox86 --print("name",classContainer.curr.name) 87 --foreach(classContainer.curr.usertypes,print) 88 --print("______________") 89 classContainer.curr = classContainer.curr.prox 90 90 end 91 91 92 92 -- get current namespace 93 93 function getcurrnamespace () 94 94 return getnamespace(classContainer.curr) 95 95 end 96 96 97 97 -- append to current container 98 98 function append (t) 99 return classContainer.curr:append(t)99 return classContainer.curr:append(t) 100 100 end 101 101 102 102 -- append typedef to current container 103 103 function appendtypedef (t) 104 return classContainer.curr:appendtypedef(t)104 return classContainer.curr:appendtypedef(t) 105 105 end 106 106 107 107 -- append usertype to current container 108 108 function appendusertype (t) 109 return classContainer.curr:appendusertype(t)109 return classContainer.curr:appendusertype(t) 110 110 end 111 111 112 112 -- append enum to current container 113 113 function appendenum (t) 114 return classContainer.curr:appendenum(t)114 return classContainer.curr:appendenum(t) 115 115 end 116 116 117 117 -- substitute typedef 118 118 function applytypedef (mod,type) 119 return classContainer.curr:applytypedef(mod,type)119 return classContainer.curr:applytypedef(mod,type) 120 120 end 121 121 122 122 -- check if is type 123 123 function findtype (type) 124 local t = classContainer.curr:findtype(type)125 124 local t = classContainer.curr:findtype(type) 125 return t 126 126 end 127 127 128 128 -- check if is typedef 129 129 function istypedef (type) 130 return classContainer.curr:istypedef(type)130 return classContainer.curr:istypedef(type) 131 131 end 132 132 133 133 -- get fulltype (with namespace) 134 134 function fulltype (t) 135 local curr = classContainer.curr136 137 138 139 140 141 142 143 144 145 146 135 local curr = classContainer.curr 136 while curr do 137 if curr then 138 if curr.typedefs and curr.typedefs[t] then 139 return curr.typedefs[t] 140 elseif curr.usertypes and curr.usertypes[t] then 141 return curr.usertypes[t] 142 end 143 end 144 curr = curr.prox 145 end 146 return t 147 147 end 148 148 149 149 -- checks if it requires collection 150 150 function classContainer:requirecollection (t) 151 push(self)152 local i=1153 154 while self[i] do155 r = self[i]:requirecollection(t) or r156 i = i+1157 end158 159 151 push(self) 152 local i=1 153 local r = false 154 while self[i] do 155 r = self[i]:requirecollection(t) or r 156 i = i+1 157 end 158 pop() 159 return r 160 160 end 161 161 … … 163 163 -- get namesapce 164 164 function getnamespace (curr) 165 166 167 168 169 170 171 172 173 174 175 165 local namespace = '' 166 while curr do 167 if curr and 168 ( curr.classtype == 'class' or curr.classtype == 'namespace') 169 then 170 namespace = (curr.original_name or curr.name) .. '::' .. namespace 171 --namespace = curr.name .. '::' .. namespace 172 end 173 curr = curr.prox 174 end 175 return namespace 176 176 end 177 177 178 178 -- get namespace (only namespace) 179 179 function getonlynamespace () 180 local curr = classContainer.curr181 182 183 184 185 186 187 188 189 190 180 local curr = classContainer.curr 181 local namespace = '' 182 while curr do 183 if curr.classtype == 'class' then 184 return namespace 185 elseif curr.classtype == 'namespace' then 186 namespace = curr.name .. '::' .. namespace 187 end 188 curr = curr.prox 189 end 190 return namespace 191 191 end 192 192 193 193 -- check if is enum 194 194 function isenum (type) 195 return classContainer.curr:isenum(type)195 return classContainer.curr:isenum(type) 196 196 end 197 197 198 198 -- append feature to container 199 199 function classContainer:append (t) 200 self.n = self.n + 1201 self[self.n] = t202 t.parent = self200 self.n = self.n + 1 201 self[self.n] = t 202 t.parent = self 203 203 end 204 204 205 205 -- append typedef 206 206 function classContainer:appendtypedef (t) 207 local namespace = getnamespace(classContainer.curr) 208 self.typedefs.tolua_n = self.typedefs.tolua_n + 1 209 self.typedefs[self.typedefs.tolua_n] = t 210 self.typedefs[t.utype] = namespace .. t.utype 211 global_typedefs[namespace..t.utype] = t 212 t.ftype = findtype(t.type) or t.type 213 --print("appending typedef "..t.utype.." as "..namespace..t.utype.." with ftype "..t.ftype) 214 append_global_type(namespace..t.utype) 215 if t.ftype and isenum(t.ftype) then 216 217 global_enums[namespace..t.utype] = true 218 end 207 local namespace = getnamespace(classContainer.curr) 208 self.typedefs.tolua_n = self.typedefs.tolua_n + 1 209 self.typedefs[self.typedefs.tolua_n] = t 210 self.typedefs[t.utype] = namespace .. t.utype 211 global_typedefs[namespace..t.utype] = t 212 t.ftype = findtype(t.type) or t.type 213 --print("appending typedef "..t.utype.." as "..namespace..t.utype.." with ftype "..t.ftype) 214 append_global_type(namespace..t.utype) 215 if t.ftype and isenum(t.ftype) then 216 global_enums[namespace..t.utype] = true 217 end 219 218 end 220 219 221 220 -- append usertype: return full type 222 221 function classContainer:appendusertype (t) 223 224 225 226 227 228 229 230 231 232 222 local container 223 if t == (self.original_name or self.name) then 224 container = self.prox 225 else 226 container = self 227 end 228 local ft = getnamespace(container) .. t 229 container.usertypes[t] = ft 230 _usertype[ft] = ft 231 return ft 233 232 end 234 233 235 234 -- append enum 236 235 function classContainer:appendenum (t) 237 local namespace = getnamespace(classContainer.curr)238 self.enums.tolua_n = self.enums.tolua_n + 1239 self.enums[self.enums.tolua_n] = t240 236 local namespace = getnamespace(classContainer.curr) 237 self.enums.tolua_n = self.enums.tolua_n + 1 238 self.enums[self.enums.tolua_n] = t 239 global_enums[namespace..t.name] = t 241 240 end 242 241 243 242 -- determine lua function name overload 244 243 function classContainer:overload (lname) 245 if not self.lnames[lname] then246 self.lnames[lname] = 0247 else248 self.lnames[lname] = self.lnames[lname] + 1249 end250 return format("%02d",self.lnames[lname])244 if not self.lnames[lname] then 245 self.lnames[lname] = 0 246 else 247 self.lnames[lname] = self.lnames[lname] + 1 248 end 249 return format("%02d",self.lnames[lname]) 251 250 end 252 251 253 252 -- applies typedef: returns the 'the facto' modifier and type 254 253 function classContainer:applytypedef (mod,type) 255 256 257 258 259 260 261 262 254 if global_typedefs[type] then 255 --print("found typedef "..global_typedefs[type].type) 256 local mod1, type1 = global_typedefs[type].mod, global_typedefs[type].ftype 257 local mod2, type2 = applytypedef(mod.." "..mod1, type1) 258 --return mod2 .. ' ' .. mod1, type2 259 return mod2, type2 260 end 261 do return mod,type end 263 262 end 264 263 265 264 -- check if it is a typedef 266 265 function classContainer:istypedef (type) 267 local env = self268 while env do269 if env.typedefs then270 local i=1271 while env.typedefs[i] do272 if env.typedefs[i].utype == type then273 return type274 end275 i = i+1276 end277 end278 env = env.parent279 end280 return nil266 local env = self 267 while env do 268 if env.typedefs then 269 local i=1 270 while env.typedefs[i] do 271 if env.typedefs[i].utype == type then 272 return type 273 end 274 i = i+1 275 end 276 end 277 env = env.parent 278 end 279 return nil 281 280 end 282 281 283 282 function find_enum_var(var) 284 283 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 284 if tonumber(var) then return var end 285 286 local c = classContainer.curr 287 while c do 288 local ns = getnamespace(c) 289 for k,v in pairs(_global_enums) do 290 if match_type(var, v, ns) then 291 return v 292 end 293 end 294 if c.base and c.base ~= '' then 295 c = _global_classes[c:findtype(c.base)] 296 else 297 c = nil 298 end 299 end 300 301 return var 303 302 end 304 303 … … 306 305 function classContainer:findtype (t) 307 306 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 307 t = string.gsub(t, "=.*", "") 308 if _basic[t] then 309 return t 310 end 311 312 local _,_,em = string.find(t, "([&%*])%s*$") 313 t = string.gsub(t, "%s*([&%*])%s*$", "") 314 p = self 315 while p and type(p)=='table' do 316 local st = getnamespace(p) 317 318 for i=_global_types.n,1,-1 do -- in reverse order 319 320 if match_type(t, _global_types[i], st) then 321 return _global_types[i]..(em or "") 322 end 323 end 324 if p.base and p.base ~= '' and p.base ~= t then 325 --print("type is "..t..", p is "..p.base.." self.type is "..self.type.." self.name is "..self.name) 326 p = _global_classes[p:findtype(p.base)] 327 else 328 p = nil 329 end 330 end 331 332 return nil 334 333 end 335 334 336 335 function append_global_type(t, class) 337 338 339 340 336 _global_types.n = _global_types.n +1 337 _global_types[_global_types.n] = t 338 _global_types_hash[t] = 1 339 if class then append_class_type(t, class) end 341 340 end 342 341 343 342 function append_class_type(t,class) 344 345 346 347 348 349 350 351 352 343 if _global_classes[t] then 344 class.flags = _global_classes[t].flags 345 class.lnames = _global_classes[t].lnames 346 if _global_classes[t].base and (_global_classes[t].base ~= '') then 347 class.base = _global_classes[t].base or class.base 348 end 349 end 350 _global_classes[t] = class 351 class.flags = class.flags or {} 353 352 end 354 353 355 354 function match_type(childtype, regtype, st) 356 355 --print("findtype "..childtype..", "..regtype..", "..st) 357 358 359 360 361 362 363 364 365 366 367 356 local b,e = string.find(regtype, childtype, -string.len(childtype), true) 357 if b then 358 359 if e == string.len(regtype) and 360 (b == 1 or (string.sub(regtype, b-1, b-1) == ':' and 361 string.sub(regtype, 1, b-1) == string.sub(st, 1, b-1))) then 362 return true 363 end 364 end 365 366 return false 368 367 end 369 368 370 369 function findtype_on_childs(self, t) 371 370 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 371 local tchild 372 if self.classtype == 'class' or self.classtype == 'namespace' then 373 for k,v in ipairs(self) do 374 if v.classtype == 'class' or v.classtype == 'namespace' then 375 if v.typedefs and v.typedefs[t] then 376 return v.typedefs[t] 377 elseif v.usertypes and v.usertypes[t] then 378 return v.usertypes[t] 379 end 380 tchild = findtype_on_childs(v, t) 381 if tchild then return tchild end 382 end 383 end 384 end 385 return nil 387 386 388 387 end 389 388 390 389 function classContainer:isenum (type) 391 if global_enums[type] then392 393 else394 395 end396 397 local basetype = gsub(type,"^.*::","")398 local env = self399 while env do400 if env.enums then401 local i=1402 while env.enums[i] do403 if env.enums[i].name == basetype then404 return true405 end406 i = i+1407 end408 end409 env = env.parent410 end411 return false390 if global_enums[type] then 391 return type 392 else 393 return false 394 end 395 396 local basetype = gsub(type,"^.*::","") 397 local env = self 398 while env do 399 if env.enums then 400 local i=1 401 while env.enums[i] do 402 if env.enums[i].name == basetype then 403 return true 404 end 405 i = i+1 406 end 407 end 408 env = env.parent 409 end 410 return false 412 411 end 413 412 … … 416 415 -- parse chunk 417 416 function classContainer:doparse (s) 418 --print ("parse "..s)419 420 -- try the parser hook421 do422 423 424 425 426 end427 428 -- try the null statement429 do430 431 432 433 434 end435 436 -- try empty verbatim line437 do438 439 440 441 442 end443 444 -- try Lua code445 do446 local b,e,code = strfind(s,"^%s*(%b\1\2)")447 if b then448 Code(strsub(code,2,-2))449 return strsub(s,e+1)450 end451 end452 453 -- try C code454 do455 local b,e,code = strfind(s,"^%s*(%b\3\4)")456 if b then457 458 459 460 end461 end462 463 -- try C code for preamble section464 do465 466 467 468 469 470 471 end472 473 -- try default_property directive474 do475 476 477 478 479 480 481 482 483 end484 485 -- try protected_destructor directive486 do487 488 489 490 491 492 493 494 end495 496 -- try 'extern' keyword497 do498 499 500 501 502 503 end504 505 -- try 'virtual' keyworkd506 do507 508 509 510 511 512 end513 514 -- try labels (public, private, etc)515 do516 517 518 519 520 end521 522 -- try module523 do524 local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*")525 if b then526 _curr_code = strsub(s,b,e)527 Module(name,body)528 return strsub(s,e+1)529 end530 end531 532 -- try namesapce533 do534 local b,e,name,body = strfind(s,"^%s*namespace%s%s*([_%w][_%w]*)%s*(%b{})%s*;?")535 if b then536 _curr_code = strsub(s,b,e)537 Namespace(name,body)538 return strsub(s,e+1)539 end540 end541 542 -- try define543 do544 local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*")545 if b then546 _curr_code = strsub(s,b,e)547 Define(name)548 return strsub(s,e+1)549 end550 end551 552 -- try enumerates553 554 do555 local b,e,name,body,varname = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*([^%s;]*)%s*;?%s*")556 if b then557 --error("#Sorry, declaration of enums and variables on the same statement is not supported.\nDeclare your variable separately (example: '"..name.." "..varname..";')")558 _curr_code = strsub(s,b,e)559 Enumerate(name,body,varname)560 return strsub(s,e+1)561 end562 end563 564 -- do565 --local b,e,name,body = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*;?%s*")566 --if b then567 --_curr_code = strsub(s,b,e)568 --Enumerate(name,body)569 --return strsub(s,e+1)570 --end571 -- end572 573 do574 local b,e,body,name = strfind(s,"^%s*typedef%s+enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*")575 if b then576 _curr_code = strsub(s,b,e)577 Enumerate(name,body)578 return strsub(s,e+1)579 end580 end581 582 -- try operator583 do584 local b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")585 if not b then586 587 b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)[%s\n]*%b{}%s*;?%s*")588 end589 if not b then590 591 592 593 594 595 596 597 598 end599 if b then600 _curr_code = strsub(s,b,e)601 Operator(decl,kind,arg,const)602 return strsub(s,e+1)603 end604 end605 606 -- try function607 do608 --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w])%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*")609 local b,e,decl,arg,const,virt = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)%s*(=?%s*0?)%s*;%s*")610 if not b then611 612 613 end614 if not b then615 -- try a single letter function name616 b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")617 end618 if b then619 620 621 622 623 624 _curr_code = strsub(s,b,e)625 Function(decl,arg,const)626 return strsub(s,e+1)627 end628 end629 630 -- try inline function631 do632 local b,e,decl,arg,const = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)[^;{]*%b{}%s*;?%s*")633 --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w>])%s*(%b())%s*(c?o?n?s?t?)[^;]*%b{}%s*;?%s*")634 if not b then635 -- try a single letter function name636 b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?).-%b{}%s*;?%s*")637 end638 if b then639 _curr_code = strsub(s,b,e)640 Function(decl,arg,const)641 return strsub(s,e+1)642 end643 end644 645 -- try class646 do647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 -- try typedef683 do684 local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*")685 if b then686 _curr_code = strsub(s,b,e)687 Typedef(types)688 return strsub(s,e+1)689 end690 end691 692 -- try variable693 do694 local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&:<>,]*[_%w%d])%s*;%s*")695 if b then696 _curr_code = strsub(s,b,e)697 698 699 700 701 702 703 704 705 706 707 708 709 --Variable(decl)710 return strsub(s,e+1)711 end712 end713 714 715 do716 local b,e,decl = strfind(s,"^%s*([_%w]?[_%s%w%d]-char%s+[_@%w%d]*%s*%[%s*%S+%s*%])%s*;%s*")717 if b then718 _curr_code = strsub(s,b,e)719 Variable(decl)720 return strsub(s,e+1)721 end722 end723 724 -- try array725 do726 local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:]*[]_%w%d])%s*;%s*")727 if b then728 _curr_code = strsub(s,b,e)729 Array(decl)730 return strsub(s,e+1)731 end732 end733 734 -- no matching735 if gsub(s,"%s%s*","") ~= "" then736 _curr_code = s737 error("#parse error")738 else739 return ""740 end417 --print ("parse "..s) 418 419 -- try the parser hook 420 do 421 local sub = parser_hook(s) 422 if sub then 423 return sub 424 end 425 end 426 427 -- try the null statement 428 do 429 local b,e,code = string.find(s, "^%s*;") 430 if b then 431 return strsub(s,e+1) 432 end 433 end 434 435 -- try empty verbatim line 436 do 437 local b,e,code = string.find(s, "^%s*$\n") 438 if b then 439 return strsub(s,e+1) 440 end 441 end 442 443 -- try Lua code 444 do 445 local b,e,code = strfind(s,"^%s*(%b\1\2)") 446 if b then 447 Code(strsub(code,2,-2)) 448 return strsub(s,e+1) 449 end 450 end 451 452 -- try C code 453 do 454 local b,e,code = strfind(s,"^%s*(%b\3\4)") 455 if b then 456 code = '{'..strsub(code,2,-2)..'\n}\n' 457 Verbatim(code,'r') -- verbatim code for 'r'egister fragment 458 return strsub(s,e+1) 459 end 460 end 461 462 -- try C code for preamble section 463 do 464 local b,e,code = string.find(s, "^%s*(%b\5\6)") 465 if b then 466 code = string.sub(code, 2, -2).."\n" 467 Verbatim(code, '') 468 return string.sub(s, e+1) 469 end 470 end 471 472 -- try default_property directive 473 do 474 local b,e,ptype = strfind(s, "^%s*TOLUA_PROPERTY_TYPE%s*%(+%s*([^%)%s]*)%s*%)+%s*;?") 475 if b then 476 if not ptype or ptype == "" then 477 ptype = "default" 478 end 479 self:set_property_type(ptype) 480 return strsub(s, e+1) 481 end 482 end 483 484 -- try protected_destructor directive 485 do 486 local b,e = string.find(s, "^%s*TOLUA_PROTECTED_DESTRUCTOR%s*;?") 487 if b then 488 if self.set_protected_destructor then 489 self:set_protected_destructor(true) 490 end 491 return strsub(s, e+1) 492 end 493 end 494 495 -- try 'extern' keyword 496 do 497 local b,e = string.find(s, "^%s*extern%s+") 498 if b then 499 -- do nothing 500 return strsub(s, e+1) 501 end 502 end 503 504 -- try 'virtual' keyworkd 505 do 506 local b,e = string.find(s, "^%s*virtual%s+") 507 if b then 508 methodisvirtual = true 509 return strsub(s, e+1) 510 end 511 end 512 513 -- try labels (public, private, etc) 514 do 515 local b,e = string.find(s, "^%s*%w*%s*:[^:]") 516 if b then 517 return strsub(s, e) -- preserve the [^:] 518 end 519 end 520 521 -- try module 522 do 523 local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*") 524 if b then 525 _curr_code = strsub(s,b,e) 526 Module(name,body) 527 return strsub(s,e+1) 528 end 529 end 530 531 -- try namesapce 532 do 533 local b,e,name,body = strfind(s,"^%s*namespace%s%s*([_%w][_%w]*)%s*(%b{})%s*;?") 534 if b then 535 _curr_code = strsub(s,b,e) 536 Namespace(name,body) 537 return strsub(s,e+1) 538 end 539 end 540 541 -- try define 542 do 543 local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*") 544 if b then 545 _curr_code = strsub(s,b,e) 546 Define(name) 547 return strsub(s,e+1) 548 end 549 end 550 551 -- try enumerates 552 553 do 554 local b,e,name,body,varname = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*([^%s;]*)%s*;?%s*") 555 if b then 556 --error("#Sorry, declaration of enums and variables on the same statement is not supported.\nDeclare your variable separately (example: '"..name.." "..varname..";')") 557 _curr_code = strsub(s,b,e) 558 Enumerate(name,body,varname) 559 return strsub(s,e+1) 560 end 561 end 562 563 -- do 564 -- local b,e,name,body = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*;?%s*") 565 -- if b then 566 -- _curr_code = strsub(s,b,e) 567 -- Enumerate(name,body) 568 -- return strsub(s,e+1) 569 -- end 570 -- end 571 572 do 573 local b,e,body,name = strfind(s,"^%s*typedef%s+enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*") 574 if b then 575 _curr_code = strsub(s,b,e) 576 Enumerate(name,body) 577 return strsub(s,e+1) 578 end 579 end 580 581 -- try operator 582 do 583 local b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)%s*;%s*") 584 if not b then 585 -- try inline 586 b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)[%s\n]*%b{}%s*;?%s*") 587 end 588 if not b then 589 -- try cast operator 590 b,e,decl,kind,arg,const = strfind(s, "^%s*(operator)%s+([%w_:%d<>%*%&%s]+)%s*(%b())%s*(c?o?n?s?t?)"); 591 if b then 592 local _,ie = string.find(s, "^%s*%b{}", e+1) 593 if ie then 594 e = ie 595 end 596 end 597 end 598 if b then 599 _curr_code = strsub(s,b,e) 600 Operator(decl,kind,arg,const) 601 return strsub(s,e+1) 602 end 603 end 604 605 -- try function 606 do 607 --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w])%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*") 608 local b,e,decl,arg,const,virt = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)%s*(=?%s*0?)%s*;%s*") 609 if not b then 610 -- try function with template 611 b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w]%b<>)%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*") 612 end 613 if not b then 614 -- try a single letter function name 615 b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*") 616 end 617 if b then 618 if virt and string.find(virt, "[=0]") then 619 if self.flags then 620 self.flags.pure_virtual = true 621 end 622 end 623 _curr_code = strsub(s,b,e) 624 Function(decl,arg,const) 625 return strsub(s,e+1) 626 end 627 end 628 629 -- try inline function 630 do 631 local b,e,decl,arg,const = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)[^;{]*%b{}%s*;?%s*") 632 --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w>])%s*(%b())%s*(c?o?n?s?t?)[^;]*%b{}%s*;?%s*") 633 if not b then 634 -- try a single letter function name 635 b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?).-%b{}%s*;?%s*") 636 end 637 if b then 638 _curr_code = strsub(s,b,e) 639 Function(decl,arg,const) 640 return strsub(s,e+1) 641 end 642 end 643 644 -- try class 645 do 646 local b,e,name,base,body 647 base = '' body = '' 648 b,e,name = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*;") -- dummy class 649 if not b then 650 b,e,name = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*;") -- dummy struct 651 if not b then 652 b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*") 653 if not b then 654 b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*") 655 if not b then 656 b,e,name,base,body = strfind(s,"^%s*union%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*") 657 if not b then 658 base = '' 659 b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w@]*)%s*;%s*") 660 end 661 end 662 end 663 end 664 end 665 if b then 666 if base ~= '' then 667 base = string.gsub(base, "^%s*:%s*", "") 668 base = string.gsub(base, "%s*public%s*", "") 669 base = split(base, ",") 670 --local b,e 671 --b,e,base = strfind(base,".-([_%w][_%w<>,:]*)$") 672 else 673 base = {} 674 end 675 _curr_code = strsub(s,b,e) 676 Class(name,base,body) 677 return strsub(s,e+1) 678 end 679 end 680 681 -- try typedef 682 do 683 local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*") 684 if b then 685 _curr_code = strsub(s,b,e) 686 Typedef(types) 687 return strsub(s,e+1) 688 end 689 end 690 691 -- try variable 692 do 693 local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&:<>,]*[_%w%d])%s*;%s*") 694 if b then 695 _curr_code = strsub(s,b,e) 696 697 local list = split_c_tokens(decl, ",") 698 Variable(list[1]) 699 if list.n > 1 then 700 local _,_,type = strfind(list[1], "(.-)%s+([^%s]*)$"); 701 702 local i =2; 703 while list[i] do 704 Variable(type.." "..list[i]) 705 i=i+1 706 end 707 end 708 --Variable(decl) 709 return strsub(s,e+1) 710 end 711 end 712 713 -- try string 714 do 715 local b,e,decl = strfind(s,"^%s*([_%w]?[_%s%w%d]-char%s+[_@%w%d]*%s*%[%s*%S+%s*%])%s*;%s*") 716 if b then 717 _curr_code = strsub(s,b,e) 718 Variable(decl) 719 return strsub(s,e+1) 720 end 721 end 722 723 -- try array 724 do 725 local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:]*[]_%w%d])%s*;%s*") 726 if b then 727 _curr_code = strsub(s,b,e) 728 Array(decl) 729 return strsub(s,e+1) 730 end 731 end 732 733 -- no matching 734 if gsub(s,"%s%s*","") ~= "" then 735 _curr_code = s 736 error("#parse error") 737 else 738 return "" 739 end 741 740 742 741 end … … 744 743 function classContainer:parse (s) 745 744 746 747 748 while s ~= '' do749 s = self:doparse(s)750 methodisvirtual = false751 end745 self.curr_member_access = nil 746 747 while s ~= '' do 748 s = self:doparse(s) 749 methodisvirtual = false 750 end 752 751 end 753 752 … … 757 756 function get_property_type() 758 757 759 758 return classContainer.curr:get_property_type() 760 759 end 761 760 762 761 function classContainer:set_property_type(ptype) 763 764 765 766 762 ptype = string.gsub(ptype, "^%s*", "") 763 ptype = string.gsub(ptype, "%s*$", "") 764 765 self.property_type = ptype 767 766 end 768 767 769 768 function classContainer:get_property_type() 770 771 end 769 return self.property_type or (self.parent and self.parent:get_property_type()) or "default" 770 end -
code/branches/buildsystem3/src/tolua/lua/custom.lua
r2087 r2664 1 1 2 2 function extract_code(fn,s) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 3 local code = "" 4 if fn then 5 code = '\n$#include "'..fn..'"\n' 6 end 7 s= "\n" .. s .. "\n" -- add blank lines as sentinels 8 local _,e,c,t = strfind(s, "\n([^\n]-)SCRIPT_([%w_]*)[^\n]*\n") 9 while e do 10 t = strlower(t) 11 if t == "bind_begin" then 12 _,e,c = strfind(s,"(.-)\n[^\n]*SCRIPT_BIND_END[^\n]*\n",e) 13 if not e then 14 tolua_error("Unbalanced 'SCRIPT_BIND_BEGIN' directive in header file") 15 end 16 end 17 if t == "bind_class" or t == "bind_block" then 18 local b 19 _,e,c,b = string.find(s, "([^{]-)(%b{})", e) 20 c = c..'{\n'..extract_code(nil, b)..'\n};\n' 21 end 22 code = code .. c .. "\n" 23 _,e,c,t = strfind(s, "\n([^\n]-)SCRIPT_([%w_]*)[^\n]*\n",e) 24 end 25 return code 26 26 end 27 27 … … 33 33 34 34 function include_file_hook(p, filename) 35 35 do return end 36 36 --print("FILENAME is "..filename) 37 38 39 40 41 42 43 37 p.code = string.gsub(p.code, "\n%s*SigC::Signal", "\n\ttolua_readonly SigC::Signal") 38 p.code = string.gsub(p.code, "#ifdef __cplusplus\nextern \"C\" {\n#endif", "") 39 p.code = string.gsub(p.code, "#ifdef __cplusplus\n};?\n#endif", "") 40 p.code = string.gsub(p.code, "DECLSPEC", "") 41 p.code = string.gsub(p.code, "SDLCALL", "") 42 p.code = string.gsub(p.code, "DLLINTERFACE", "") 43 p.code = string.gsub(p.code, "#define[^\n]*_[hH]_?%s*\n", "\n") 44 44 --print("code is "..p.code) 45 45 end -
code/branches/buildsystem3/src/tolua/lua/custom_hide.lua
r2087 r2664 1 1 -- extract code with tolua_hide, and also 2 2 function extract_code(fn,s) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 3 local code = '\n$#include "'..fn..'"\n' 4 s= "\n" .. s .. "\n" -- add blank lines as sentinels 5 local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n") 6 while e do 7 t = strlower(t) 8 if t == "begin" then 9 _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e) 10 if not e then 11 tolua_error("Unbalanced 'tolua_begin' directive in header file") 12 end 13 end 14 c = c.."\n" 15 c = string.gsub(c, "\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[hH][iI][Dd][eE][^\n]*\n", "\n"); 16 c = string.gsub(c, "#define[^%(\n]*%(.-\n", "\n") 17 code = code .. c 18 _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e) 19 end 20 return code 21 21 end -
code/branches/buildsystem3/src/tolua/lua/declaration.lua
r2087 r2664 22 22 -- ret = "*" or "&", if value is to be returned (only for arguments) 23 23 classDeclaration = { 24 mod = '',25 type = '',26 ptr = '',27 name = '',28 dim = '',29 ret = '',30 def = ''24 mod = '', 25 type = '', 26 ptr = '', 27 name = '', 28 dim = '', 29 ret = '', 30 def = '' 31 31 } 32 32 classDeclaration.__index = classDeclaration … … 35 35 -- Create an unique variable name 36 36 function create_varname () 37 if not _varnumber then _varnumber = 0 end38 _varnumber = _varnumber + 139 return "tolua_var_".._varnumber37 if not _varnumber then _varnumber = 0 end 38 _varnumber = _varnumber + 1 39 return "tolua_var_".._varnumber 40 40 end 41 41 … … 44 44 function classDeclaration:checkname () 45 45 46 if strsub(self.name,1,1) == '[' and not findtype(self.type) then47 self.name = self.type..self.name48 local m = split(self.mod,'%s%s*')49 self.type = m[m.n]50 self.mod = concat(m,1,m.n-1)51 end52 53 local t = split(self.name,'=')54 if t.n==2 then55 self.name = t[1]56 self.def = find_enum_var(t[t.n])57 end58 59 local b,e,d = strfind(self.name,"%[(.-)%]")60 if b then61 self.name = strsub(self.name,1,b-1)62 self.dim = find_enum_var(d)63 end64 65 66 if self.type ~= '' and self.type ~= 'void' and self.name == '' then67 self.name = create_varname()68 elseif self.kind=='var' then69 if self.type=='' and self.name~='' then70 self.type = self.type..self.name71 self.name = create_varname()72 elseif findtype(self.name) then73 if self.type=='' then self.type = self.name74 else self.type = self.type..' '..self.name end75 self.name = create_varname()76 end77 end78 79 -- adjust type of string80 if self.type == 'char' and self.dim ~= '' then81 82 end83 84 85 86 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 52 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 58 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 64 65 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 78 79 -- adjust type of string 80 if self.type == 'char' and self.dim ~= '' then 81 self.type = 'char*' 82 end 83 84 if self.kind and self.kind == 'var' then 85 self.name = string.gsub(self.name, ":.*$", "") -- ??? 86 end 87 87 end 88 88 … … 91 91 function classDeclaration:checktype () 92 92 93 -- check if there is a pointer to basic type94 local basic = isbasic(self.type)95 if self.kind == 'func' and basic=='number' and string.find(self.ptr, "%*") then96 97 98 end99 if basic and self.ptr~='' then100 self.ret = self.ptr101 self.ptr = nil102 if isbasic(self.type) == 'number' then103 104 end105 end106 107 -- check if there is array to be returned108 if self.dim~='' and self.ret~='' then109 error('#invalid parameter: cannot return an array of values')110 end111 -- 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 end116 117 -- resolve types inside the templates118 if self.type then119 120 end121 122 --123 -- -- if returning value, automatically set default value124 -- if self.ret ~= '' and self.def == '' then125 -- self.def = '0'126 -- end127 --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 106 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 116 117 -- resolve types inside the templates 118 if self.type then 119 self.type = resolve_template_types(self.type) 120 end 121 122 -- 123 -- -- if returning value, automatically set default value 124 -- if self.ret ~= '' and self.def == '' then 125 -- self.def = '0' 126 -- end 127 -- 128 128 129 129 end … … 131 131 function resolve_template_types(type) 132 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 133 if isbasic(type) then 134 return type 135 end 136 local b,_,m = string.find(type, "(%b<>)") 137 if b then 138 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 145 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 153 153 end 154 154 155 155 function break_template(s) 156 157 158 159 160 161 162 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 163 163 end 164 164 165 165 function rebuild_template(s, b, timpl) 166 166 167 168 169 170 171 167 if b == 0 then 168 return s 169 end 170 171 return string.sub(s, 1, b-1)..timpl..string.sub(s, b, -1) 172 172 end 173 173 174 174 -- Print method 175 175 function classDeclaration:print (ident,close) 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)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) 185 185 end 186 186 … … 188 188 function classDeclaration:requirecollection (t) 189 189 if self.mod ~= 'const' and 190 191 192 193 194 195 196 197 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 198 198 end 199 199 … … 201 201 function classDeclaration:decltype () 202 202 203 204 205 206 207 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 208 208 end 209 209 … … 211 211 -- output type checking 212 212 function classDeclaration:outchecktype (narg) 213 local def214 local t = isbasic(self.type)215 if self.def~='' then216 def = 1217 else218 def = 0219 end220 if self.dim ~= '' then221 222 --return 'tolua_isstringarray(tolua_S,'..narg..','..def..',&tolua_err)'223 224 225 226 elseif t then227 228 else229 return 'tolua_isusertype(tolua_S,'..narg..',"'..self.type..'",'..def..',&tolua_err)'230 end213 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 231 231 end 232 232 233 233 function classDeclaration:builddeclaration (narg, cplusplus) 234 local array = self.dim ~= '' and tonumber(self.dim)==nil235 236 local ptr = ''237 238 239 if self.dim ~= '' then240 241 end242 if self.ptr~='' and not isbasic(type) then ptr = '*' end243 line = concatparam(line," ",self.mod,type,ptr)244 if array then245 line = concatparam(line,'*')246 end247 line = concatparam(line,self.name)248 if self.dim ~= '' then249 if tonumber(self.dim)~=nil then250 line = concatparam(line,'[',self.dim,'];')251 else252 253 254 255 256 257 258 end259 else260 local t = isbasic(type)261 line = concatparam(line,' = ')262 if t == 'state' then263 264 else265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 end291 end292 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 293 293 end 294 294 295 295 -- Declare variable 296 296 function classDeclaration:declare (narg) 297 if self.dim ~= '' and tonumber(self.dim)==nil then298 299 300 301 302 303 304 305 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 306 306 end 307 307 308 308 -- Get parameter value 309 309 function classDeclaration:getarray (narg) 310 if self.dim ~= '' then311 312 output(' {')313 314 local def; if self.def~='' then def=1 else def=0 end315 316 317 output(' if (!tolua_is'..t..'array(tolua_S,',narg,',',self.dim,',',def,',&tolua_err))')318 319 output(' if (!tolua_isusertypearray(tolua_S,',narg,',"',type,'",',self.dim,',',def,',&tolua_err))')320 321 output(' goto tolua_lerror;')322 output(' else\n')323 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 = '*' end330 output(' ',self.name..'[i] = ')331 if not t and ptr=='' then output('*') end332 output('((',type)333 if not t then334 output('*')335 end336 output(') ')337 local def = 0338 if self.def ~= '' then def = self.def end339 if t then340 output('tolua_tofield'..t..'(tolua_S,',narg,',i+1,',def,'));')341 else342 output('tolua_tofieldusertype(tolua_S,',narg,',i+1,',def,'));')343 end344 output(' }')345 output(' }')346 end310 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 347 347 end 348 348 349 349 -- Get parameter value 350 350 function classDeclaration:setarray (narg) 351 if not strfind(self.type,'const%s+') and self.dim ~= '' then352 353 output(' {')354 output(' int i;')355 output(' for(i=0; i<'..self.dim..';i++)')356 local t,ct = isbasic(type)357 if t then358 output(' tolua_pushfield'..t..'(tolua_S,',narg,',i+1,(',ct,')',self.name,'[i]);')359 else360 if self.ptr == '' then361 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 else371 output(' tolua_pushfieldusertype(tolua_S,',narg,',i+1,(void*)',self.name,'[i],"',type,'");')372 end373 end374 output(' }')375 end351 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 376 376 end 377 377 378 378 -- Free dynamically allocated array 379 379 function classDeclaration:freearray () 380 if self.dim ~= '' and tonumber(self.dim)==nil then381 382 383 384 output(' free(',self.name,');')385 386 end380 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 387 387 end 388 388 389 389 -- Pass parameter 390 390 function classDeclaration:passpar () 391 if self.ptr=='&' and not isbasic(self.type) then392 output('*'..self.name)393 elseif self.ret=='*' then394 output('&'..self.name)395 else396 output(self.name)397 end391 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 398 398 end 399 399 400 400 -- Return parameter value 401 401 function classDeclaration:retvalue () 402 if self.ret ~= '' then403 local t,ct = isbasic(self.type)404 if t and t~='' then405 output(' tolua_push'..t..'(tolua_S,(',ct,')'..self.name..');')406 else407 output(' tolua_pushusertype(tolua_S,(void*)'..self.name..',"',self.type,'");')408 end409 return 1410 end411 return 0402 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 412 412 end 413 413 … … 415 415 function _Declaration (t) 416 416 417 setmetatable(t,classDeclaration)418 t:buildnames()419 t:checkname()420 t:checktype()421 local ft = findtype(t.type) or t.type422 if not isenum(ft) then423 424 end425 426 if t.kind=="var" and (string.find(t.mod, "tolua_property%s") or string.find(t.mod, "tolua_property$")) then427 428 end429 430 return t417 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 425 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 429 430 return t 431 431 end 432 432 … … 436 436 function Declaration (s,kind,is_parameter) 437 437 438 -- eliminate spaces if default value is provided439 s = gsub(s,"%s*=%s*","=")440 s = gsub(s, "%s*<", "<")441 442 local defb,tmpdef443 defb,_,tmpdef = string.find(s, "(=.*)$")444 if defb then445 446 else447 448 end449 if kind == "var" then450 -- check the form: void451 if s == '' or s == 'void' then452 return _Declaration{type = 'void', kind = kind, is_parameter = is_parameter}453 end454 end455 456 -- check the form: mod type*& name457 local t = split_c_tokens(s,'%*%s*&')458 if t.n == 2 then459 if kind == 'func' then460 error("#invalid function return type: "..s)461 end462 --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 = kind473 }474 end475 476 -- check the form: mod type** name477 t = split_c_tokens(s,'%*%s*%*')478 if t.n == 2 then479 if kind == 'func' then480 error("#invalid function return type: "..s)481 end482 --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 = kind493 }494 end495 496 -- check the form: mod type& name497 t = split_c_tokens(s,'&')498 if t.n == 2 then499 --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 = kind509 }510 end511 512 -- check the form: mod type* name513 local s1 = gsub(s,"(%b\[\])",function (n) return gsub(n,'%*','\1') end)514 t = split_c_tokens(s1,'%*')515 if t.n == 2 then516 t[2] = gsub(t[2],'\1','%*') -- restore * in dimension expression517 --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 = kind527 }528 end529 530 if kind == 'var' then531 -- check the form: mod type name532 --t = split(s,'%s%s*')533 t = split_c_tokens(s,'%s+')534 local v535 if findtype(t[t.n]) then v = create_varname() else v = t[t.n]; t.n = t.n-1 end536 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 = kind543 }544 545 else -- kind == "func"546 547 -- check the form: mod type name548 --t = split(s,'%s%s*')549 t = split_c_tokens(s,'%s+')550 local v = t[t.n] -- last word is the function name551 local tp,md552 if t.n>1 then553 tp = t[t.n-1]554 md = concat(t,1,t.n-2)555 end556 --if tp then tp = rebuild_template(tp, tb, timpl) end557 return _Declaration{558 name = v,559 type = tp,560 mod = md,561 is_parameter = is_parameter,562 kind = kind563 }564 end565 566 end 567 438 -- eliminate spaces if default value is provided 439 s = gsub(s,"%s*=%s*","=") 440 s = gsub(s, "%s*<", "<") 441 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 455 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 475 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 495 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 511 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 529 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 } 544 545 else -- kind == "func" 546 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 565 566 end 567 -
code/branches/buildsystem3/src/tolua/lua/define.lua
r2087 r2664 16 16 -- name = constant name 17 17 classDefine = { 18 name = '',18 name = '', 19 19 } 20 20 classDefine.__index = classDefine … … 23 23 -- register define 24 24 function classDefine:register (pre) 25 26 27 25 if not self:check_public_access() then 26 return 27 end 28 28 29 pre = pre or ''30 output(pre..'tolua_constant(tolua_S,"'..self.lname..'",'..self.name..');')29 pre = pre or '' 30 output(pre..'tolua_constant(tolua_S,"'..self.lname..'",'..self.name..');') 31 31 end 32 32 33 33 -- Print method 34 34 function classDefine:print (ident,close) 35 print(ident.."Define{")36 print(ident.." name = '"..self.name.."',")37 print(ident.." lname = '"..self.lname.."',")38 print(ident.."}"..close)35 print(ident.."Define{") 36 print(ident.." name = '"..self.name.."',") 37 print(ident.." lname = '"..self.lname.."',") 38 print(ident.."}"..close) 39 39 end 40 40 … … 42 42 -- Internal constructor 43 43 function _Define (t) 44 setmetatable(t,classDefine)45 t:buildnames()44 setmetatable(t,classDefine) 45 t:buildnames() 46 46 47 if t.name == '' then48 error("#invalid define")49 end47 if t.name == '' then 48 error("#invalid define") 49 end 50 50 51 append(t)52 return t51 append(t) 52 return t 53 53 end 54 54 … … 56 56 -- Expects a string representing the constant name 57 57 function Define (n) 58 return _Define{59 name = n60 }58 return _Define { 59 name = n 60 } 61 61 end 62 62 -
code/branches/buildsystem3/src/tolua/lua/doit.lua
r2087 r2664 14 14 function parse_extra() 15 15 16 17 18 19 20 21 22 23 24 16 for k,v in ipairs(_extra_parameters or {}) do 17 18 local b,e,name,value = string.find(v, "^([^=])=(.*)$") 19 if b then 20 _extra_parameters[name] = value 21 else 22 _extra_parameters[v] = true 23 end 24 end 25 25 end 26 26 27 27 function doit () 28 29 30 31 32 33 34 35 36 28 -- define package name, if not provided 29 if not flags.n then 30 if flags.f then 31 flags.n = gsub(flags.f,"%..*$","") 32 _,_,flags.n = string.find(flags.n, "([^/\\]*)$") 33 else 34 error("#no package name nor input file provided") 35 end 36 end 37 37 38 39 38 -- parse table with extra paramters 39 parse_extra() 40 40 41 -- do this after setting the package name 42 if flags['L']then43 dofile(flags['L']) 44 41 -- get potential working directory 42 if not flags.w then 43 flags.w = '' 44 end 45 45 46 -- add cppstring 47 if not flags['S'] then 48 _basic['string'] = 'cppstring' 49 _basic['std::string'] = 'cppstring' 50 _basic_ctype.cppstring = 'const char*' 51 end 46 -- do this after setting the package name 47 if flags.L then 48 if string.sub(flags.L, 1, 1) == '/' or string.sub(flags.L, 1, 1) == '\\' or (string.len(flags.L) > 1 and string.sub(flags.L, 2, 2) == ':') then 49 dofile(flags.L) 50 else 51 dofile(flags.w..'/'..flags.L) 52 end 53 end 52 54 53 -- proccess package 54 local p = Package(flags.n,flags.f) 55 -- add cppstring 56 if not flags.S then 57 _basic['string'] = 'cppstring' 58 _basic['std::string'] = 'cppstring' 59 _basic_ctype.cppstring = 'const char*' 60 end 55 61 56 if flags.p then 57 return -- only parse 58 end 62 -- proccess package 63 local file 64 if flags.f then 65 if string.sub(flags.f, 1, 1) == '/' or string.sub(flags.f, 1, 1) == '\\' or (string.len(flags.f) > 1 and string.sub(flags.f, 2, 2) == ':') then 66 file = flags.f 67 else 68 file = flags.w..'/'..flags.f 69 end 70 else 71 file = flags.f 72 end 73 local p = Package(flags.n, file) 59 74 60 if flags.o then 61 local st,msg = writeto(flags.o) 62 if not st then 63 error('#'..msg) 64 end 65 end 75 if flags.p then 76 return -- only parse 77 end 66 78 67 p:decltype() 68 if flags.P then 69 p:print() 70 else 71 p:preamble() 72 p:supcode() 73 p:register() 74 push(p) 75 post_output_hook(p) 76 pop() 77 end 79 if flags.o then 80 local file 81 if string.sub(flags.o, 1, 1) == '/' or string.sub(flags.o, 1, 1) == '\\' or (string.len(flags.o) > 1 and string.sub(flags.o, 2, 2) == ':') then 82 file = flags.o 83 else 84 file = flags.w..'/'..flags.o 85 end 86 local st,msg = writeto(file) 87 if not st then 88 error('#'..msg) 89 end 90 end 78 91 79 if flags.o then 80 writeto() 81 end 92 p:decltype() 93 if flags.P then 94 p:print() 95 else 96 p:preamble() 97 p:supcode() 98 p:register() 99 push(p) 100 post_output_hook(p) 101 pop() 102 end 82 103 83 -- write header file 84 if not flags.P then 85 if flags.H then 86 local st,msg = writeto(flags.H) 87 if not st then 88 error('#'..msg) 89 end 90 p:header() 91 writeto() 92 end 93 end 104 if flags.o then 105 writeto() 106 end 107 108 -- write header file 109 if not flags.P then 110 if flags.H then 111 local file 112 if string.sub(flags.H, 1, 1) == '/' or string.sub(flags.H, 1, 1) == '\\' or (string.len(flags.H) > 1 and string.sub(flags.H, 2, 2) == ':') then 113 file = flags.H 114 else 115 file = flags.w..'/'..flags.H 116 end 117 local st,msg = writeto(file) 118 if not st then 119 error('#'..msg) 120 end 121 p:header() 122 writeto() 123 end 124 end 94 125 end 95 126 -
code/branches/buildsystem3/src/tolua/lua/enumerate.lua
r2087 r2664 22 22 -- register enumeration 23 23 function classEnumerate:register (pre) 24 pre = pre or ''25 local nspace = getnamespace(classContainer.curr)26 local i=127 while self[i] do28 output(pre..'tolua_constant(tolua_S,"'..self.lnames[i]..'",'..nspace..self[i]..');')29 i = i+130 end24 pre = pre or '' 25 local nspace = getnamespace(classContainer.curr) 26 local i=1 27 while self[i] do 28 output(pre..'tolua_constant(tolua_S,"'..self.lnames[i]..'",'..nspace..self[i]..');') 29 i = i+1 30 end 31 31 end 32 32 33 33 -- Print method 34 34 function classEnumerate:print (ident,close) 35 print(ident.."Enumerate{")36 print(ident.." name = "..self.name)37 local i=138 while self[i] do39 print(ident.." '"..self[i].."'("..self.lnames[i].."),")40 i = i+141 end42 print(ident.."}"..close)35 print(ident.."Enumerate{") 36 print(ident.." name = "..self.name) 37 local i=1 38 while self[i] do 39 print(ident.." '"..self[i].."'("..self.lnames[i].."),") 40 i = i+1 41 end 42 print(ident.."}"..close) 43 43 end 44 44 45 45 -- Internal constructor 46 46 function _Enumerate (t,varname) 47 setmetatable(t,classEnumerate)48 append(t)49 appendenum(t)50 51 52 53 54 55 56 57 58 59 return t47 setmetatable(t,classEnumerate) 48 append(t) 49 appendenum(t) 50 if varname and varname ~= "" then 51 if t.name ~= "" then 52 Variable(t.name.." "..varname) 53 else 54 local ns = getcurrnamespace() 55 warning("Variable "..ns..varname.." of type <anonymous enum> is declared as read-only") 56 Variable("tolua_readonly int "..varname) 57 end 58 end 59 return t 60 60 end 61 61 … … 63 63 -- Expects a string representing the enumerate body 64 64 function Enumerate (n,b,varname) 65 66 local t = split(strsub(b,2,-2),',') -- eliminate braces67 local i = 168 local e = {n=0}69 while t[i] do70 local tt = split(t[i],'=') -- discard initial value71 e.n = e.n + 172 e[e.n] = tt[1]73 i = i+174 end75 -- set lua names76 i = 177 e.lnames = {}78 local ns = getcurrnamespace()79 while e[i] do80 local t = split(e[i],'@')81 e[i] = t[1]82 83 84 85 e.lnames[i] = t[2] or t[1]86 _global_enums[ ns..e[i] ] = (ns..e[i])87 i = i+188 end89 90 91 92 93 return _Enumerate(e, varname)65 b = string.gsub(b, ",[%s\n]*}", "\n}") -- eliminate last ',' 66 local t = split(strsub(b,2,-2),',') -- eliminate braces 67 local i = 1 68 local e = {n=0} 69 while t[i] do 70 local tt = split(t[i],'=') -- discard initial value 71 e.n = e.n + 1 72 e[e.n] = tt[1] 73 i = i+1 74 end 75 -- set lua names 76 i = 1 77 e.lnames = {} 78 local ns = getcurrnamespace() 79 while e[i] do 80 local t = split(e[i],'@') 81 e[i] = t[1] 82 if not t[2] then 83 t[2] = applyrenaming(t[1]) 84 end 85 e.lnames[i] = t[2] or t[1] 86 _global_enums[ ns..e[i] ] = (ns..e[i]) 87 i = i+1 88 end 89 e.name = n 90 if n ~= "" then 91 Typedef("int "..n) 92 end 93 return _Enumerate(e, varname) 94 94 end 95 95 -
code/branches/buildsystem3/src/tolua/lua/feature.lua
r2087 r2664 40 40 -- check if it requires collection 41 41 function classFeature:requirecollection (t) 42 return false42 return false 43 43 end 44 44 45 45 -- build names 46 46 function classFeature:buildnames () 47 if self.name and self.name~='' then48 local n = split(self.name,'@')49 self.name = n[1]50 if not n[2] then51 n[2] = applyrenaming(n[1])52 end53 self.lname = n[2] or gsub(n[1],"%[.-%]","")54 self.original_name = self.name55 self.lname = clean_template(self.lname)56 end57 if not self.is_parameter then58 59 end47 if self.name and self.name~='' then 48 local n = split(self.name,'@') 49 self.name = n[1] 50 if not n[2] then 51 n[2] = applyrenaming(n[1]) 52 end 53 self.lname = n[2] or gsub(n[1],"%[.-%]","") 54 self.original_name = self.name 55 self.lname = clean_template(self.lname) 56 end 57 if not self.is_parameter then 58 self.name = getonlynamespace() .. self.name 59 end 60 60 61 local parent = classContainer.curr62 if parent then63 64 else65 end61 local parent = classContainer.curr 62 if parent then 63 self.access = parent.curr_member_access 64 else 65 end 66 66 end 67 67 68 68 function classFeature:check_public_access() 69 69 70 71 72 70 if self.access and self.access ~= 0 then 71 return false 72 end 73 73 74 75 76 77 78 79 80 81 74 local parent = classContainer.curr 75 while parent do 76 if parent.access and parent.access ~= 0 then 77 return false 78 end 79 parent = parent.prox 80 end 81 return true 82 82 end 83 83 84 84 function clean_template(t) 85 85 86 86 return string.gsub(t, "[<>:, %*]", "_") 87 87 end 88 88 … … 90 90 -- it returns the container class name or nil. 91 91 function classFeature:incontainer (which) 92 if self.parent then93 local parent = self.parent94 while parent do95 if parent.classtype == which then96 return parent.name97 end98 parent = parent.parent99 end100 end101 return nil92 if self.parent then 93 local parent = self.parent 94 while parent do 95 if parent.classtype == which then 96 return parent.name 97 end 98 parent = parent.parent 99 end 100 end 101 return nil 102 102 end 103 103 104 104 function classFeature:inclass () 105 return self:incontainer('class')105 return self:incontainer('class') 106 106 end 107 107 108 108 function classFeature:inmodule () 109 return self:incontainer('module')109 return self:incontainer('module') 110 110 end 111 111 112 112 function classFeature:innamespace () 113 return self:incontainer('namespace')113 return self:incontainer('namespace') 114 114 end 115 115 … … 118 118 function classFeature:cfuncname (n) 119 119 120 if self.parent then121 n = self.parent:cfuncname(n)122 end120 if self.parent then 121 n = self.parent:cfuncname(n) 122 end 123 123 124 n = string.gsub(n..'_'.. (self.lname or self.name), "[<>:, \.%*&]", "_")124 n = string.gsub(n..'_'.. (self.lname or self.name), "[<>:, \.%*&]", "_") 125 125 126 return n126 return n 127 127 end 128 128 -
code/branches/buildsystem3/src/tolua/lua/function.lua
r2087 r2664 52 52 if e.ret == "nil" then 53 53 output("catch(",nameToEcho," CEGUIDeadException(",exceptionDefs[e.name].var,"))\n{\n") 54 55 56 54 else 55 output("catch(",nameToEcho,exceptionDefs[e.name].var,")\n{\n") 56 end 57 57 58 58 -- if just a nil … … 141 141 -- const = if it is a method receiving a const "this". 142 142 classFunction = { 143 mod = '',144 type = '',145 ptr = '',146 name = '',147 args = {n=0},148 const = '',143 mod = '', 144 type = '', 145 ptr = '', 146 name = '', 147 args = {n=0}, 148 const = '', 149 149 } 150 150 classFunction.__index = classFunction … … 153 153 -- declare tags 154 154 function classFunction:decltype () 155 self.type = typevar(self.type)156 if strfind(self.mod,'const') then157 158 159 160 local i=1161 while self.args[i] do162 self.args[i]:decltype()163 i = i+1164 end155 self.type = typevar(self.type) 156 if strfind(self.mod,'const') then 157 self.type = 'const '..self.type 158 self.mod = gsub(self.mod,'const','') 159 end 160 local i=1 161 while self.args[i] do 162 self.args[i]:decltype() 163 i = i+1 164 end 165 165 end 166 166 … … 170 170 function classFunction:supcode (local_constructor) 171 171 172 local overload = strsub(self.cname,-2,-1) - 1 -- indicate overloaded func173 local nret = 0 -- number of returned values174 local class = self:inclass()175 local _,_,static = strfind(self.mod,'^%s*(static)')176 if class then177 178 179 180 181 182 183 184 185 186 187 188 else189 output("/* function:",self.name," */")190 end191 192 if local_constructor then193 output("#ifndef TOLUA_DISABLE_"..self.cname.."_local")194 output("\nstatic int",self.cname.."_local","(lua_State* tolua_S)")195 else196 output("#ifndef TOLUA_DISABLE_"..self.cname)197 output("\nstatic int",self.cname,"(lua_State* tolua_S)")198 end199 output("{")200 201 -- check types202 203 204 205 206 output(' if (\n')207 -- check self208 local narg209 if class then narg=2 else narg=1 end210 if class then211 212 213 214 215 216 217 218 219 220 221 end222 -- check args223 if self.args[1].type ~= 'void' then224 local i=1225 while self.args[i] do226 local btype = isbasic(self.args[i].type)227 if btype ~= 'value' and btype ~= 'state' then228 output(' !'..self.args[i]:outchecktype(narg)..' ||\n')229 end230 if btype ~= 'state' then231 232 end233 i = i+1234 end235 end236 -- check end of list237 output(' !tolua_isnoobj(tolua_S,'..narg..',&tolua_err)\n )')238 239 240 output(' else\n')241 242 243 244 245 246 -- declare self, if the case247 local narg248 if class then narg=2 else narg=1 end249 if class and self.name~='new' and static==nil then250 output(' ',self.const,self.parent.type,'*','self = ')251 output('(',self.const,self.parent.type,'*) ')252 output('tolua_tousertype(tolua_S,1,0);')253 elseif static then254 _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')255 end256 -- declare parameters257 if self.args[1].type ~= 'void' then258 local i=1259 while self.args[i] do260 self.args[i]:declare(narg)261 if isbasic(self.args[i].type) ~= "state" then262 263 end264 i = i+1265 end266 end267 268 -- check self269 if class and self.name~='new' and static==nil then270 271 output(' if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');272 273 end274 275 -- get array element values276 if class then narg=2 else narg=1 end277 if self.args[1].type ~= 'void' then278 local i=1279 while self.args[i] do280 self.args[i]:getarray(narg)281 narg = narg+1282 i = i+1283 end284 end285 286 --------------------------------------------------287 -- CEGUILua mod288 -- init exception handling289 local throws = false290 do291 local pattern = "tolua_throws|.*|"292 local i,j = string.find(self.mod, pattern)293 if i then294 throws = {}295 -- ensure table is empty. Used to be: table.setn(throws,0)296 for x in pairs(throws) do297 throws[x] = nil298 end299 local excepts = string.sub(self.mod, i+12,j)300 local epattern = "|.-|"301 local i,j = string.find(excepts, epattern)302 while i do303 local e = string.sub(excepts,i+1,j-1)304 local _,_,name,rest = string.find(e, "([%w:_]+),?(.*)")305 table.insert(throws,{name=name, ret=rest})306 i,j = string.find(excepts, epattern, j)307 end308 self.mod = string.gsub(self.mod, pattern, "")309 end310 end311 local exRaiseError = false312 --------------------------------------------------313 314 local out = string.find(self.mod, "tolua_outside")315 316 ---------------317 -- CEGUILua mod318 -- remove "tolua_outside" from self.mod319 if out then320 self.mod = string.gsub(self.mod, "tolua_outside", "")321 end322 323 -- call function324 if class and self.name=='delete' then325 output(' delete self;')326 elseif class and self.name == 'operator&[]' then327 if flags['1'] then -- for compatibility with tolua5 ?328 329 else330 output(' self->operator[](',self.args[1].name,') = ',self.args[2].name,';')331 end332 else333 -- CEGUILua mod begin- throws334 if throws then335 for i=1,table.getn(throws) do336 if string.find(throws[i].ret, "error") then337 output("char errorBuffer["..exceptionMessageBufferSize.."];\n")338 output("bool errorDoIt = false;\n")339 exRaiseError = true340 break341 end342 end343 output("try\n")344 end345 -- CEGUILua mod end - throws346 output(' {')347 if self.type ~= '' and self.type ~= 'void' then348 output(' ',self.mod,self.type,self.ptr,'tolua_ret = ')349 output('(',self.mod,self.type,self.ptr,') ')350 else351 output(' ')352 end353 if class and self.name=='new' then354 output('new',self.type,'(')355 elseif class and static then356 357 358 359 360 361 elseif class then362 363 364 365 366 367 368 369 370 371 else372 output(self.name,'(')373 end374 375 if out and not static then376 377 378 379 380 end381 -- write parameters382 local i=1383 while self.args[i] do384 self.args[i]:passpar()385 i = i+1386 if self.args[i] then387 output(',')388 end389 end390 391 if class and self.name == 'operator[]' and flags['1'] then392 393 else394 395 end396 397 -- return values398 if self.type ~= '' and self.type ~= 'void' then399 nret = nret + 1400 local t,ct = isbasic(self.type)401 if t then402 403 404 405 406 407 else408 409 410 if self.ptr == '' then411 output(' {')412 output('#ifdef __cplusplus\n')413 output(' void* tolua_obj = new',new_t,'(tolua_ret);')414 output(' tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')415 output('#else\n')416 output(' void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')417 output(' tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')418 output('#endif\n')419 output(' }')420 elseif self.ptr == '&' then421 output(' tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')422 else423 424 425 426 427 428 end429 end430 end431 local i=1432 while self.args[i] do433 nret = nret + self.args[i]:retvalue()434 i = i+1435 end436 output(' }')437 438 ------------------------------------------439 -- CEGUILua mod440 -- finish exception handling441 -- catch442 if throws then443 outputExceptionCatchBlocks(self.name, throws, exRaiseError)444 end445 ------------------------------------------446 447 -- set array element values448 if class then narg=2 else narg=1 end449 if self.args[1].type ~= 'void' then450 local i=1451 while self.args[i] do452 self.args[i]:setarray(narg)453 narg = narg+1454 i = i+1455 end456 end457 458 -- free dynamically allocated array459 if self.args[1].type ~= 'void' then460 local i=1461 while self.args[i] do462 self.args[i]:freearray()463 i = i+1464 end465 end466 end467 468 output(' }')469 output(' return '..nret..';')470 471 -- call overloaded function or generate error472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 output('}')488 output('#endif //#ifndef TOLUA_DISABLE\n')489 output('\n')490 491 492 493 494 495 172 local overload = strsub(self.cname,-2,-1) - 1 -- indicate overloaded func 173 local nret = 0 -- number of returned values 174 local class = self:inclass() 175 local _,_,static = strfind(self.mod,'^%s*(static)') 176 if class then 177 178 if self.name == 'new' and self.parent.flags.pure_virtual then 179 -- no constructor for classes with pure virtual methods 180 return 181 end 182 183 if local_constructor then 184 output("/* method: new_local of class ",class," */") 185 else 186 output("/* method:",self.name," of class ",class," */") 187 end 188 else 189 output("/* function:",self.name," */") 190 end 191 192 if local_constructor then 193 output("#ifndef TOLUA_DISABLE_"..self.cname.."_local") 194 output("\nstatic int",self.cname.."_local","(lua_State* tolua_S)") 195 else 196 output("#ifndef TOLUA_DISABLE_"..self.cname) 197 output("\nstatic int",self.cname,"(lua_State* tolua_S)") 198 end 199 output("{") 200 201 -- check types 202 if overload < 0 then 203 output('#ifndef TOLUA_RELEASE\n') 204 end 205 output(' tolua_Error tolua_err;') 206 output(' if (\n') 207 -- check self 208 local narg 209 if class then narg=2 else narg=1 end 210 if class then 211 local func = 'tolua_isusertype' 212 local type = self.parent.type 213 if self.name=='new' or static~=nil then 214 func = 'tolua_isusertable' 215 type = self.parent.type 216 end 217 if self.const ~= '' then 218 type = "const "..type 219 end 220 output(' !'..func..'(tolua_S,1,"'..type..'",0,&tolua_err) ||\n') 221 end 222 -- check args 223 if self.args[1].type ~= 'void' then 224 local i=1 225 while self.args[i] do 226 local btype = isbasic(self.args[i].type) 227 if btype ~= 'value' and btype ~= 'state' then 228 output(' !'..self.args[i]:outchecktype(narg)..' ||\n') 229 end 230 if btype ~= 'state' then 231 narg = narg+1 232 end 233 i = i+1 234 end 235 end 236 -- check end of list 237 output(' !tolua_isnoobj(tolua_S,'..narg..',&tolua_err)\n )') 238 output(' goto tolua_lerror;') 239 240 output(' else\n') 241 if overload < 0 then 242 output('#endif\n') 243 end 244 output(' {') 245 246 -- declare self, if the case 247 local narg 248 if class then narg=2 else narg=1 end 249 if class and self.name~='new' and static==nil then 250 output(' ',self.const,self.parent.type,'*','self = ') 251 output('(',self.const,self.parent.type,'*) ') 252 output('tolua_tousertype(tolua_S,1,0);') 253 elseif static then 254 _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)') 255 end 256 -- declare parameters 257 if self.args[1].type ~= 'void' then 258 local i=1 259 while self.args[i] do 260 self.args[i]:declare(narg) 261 if isbasic(self.args[i].type) ~= "state" then 262 narg = narg+1 263 end 264 i = i+1 265 end 266 end 267 268 -- check self 269 if class and self.name~='new' and static==nil then 270 output('#ifndef TOLUA_RELEASE\n') 271 output(' if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);'); 272 output('#endif\n') 273 end 274 275 -- get array element values 276 if class then narg=2 else narg=1 end 277 if self.args[1].type ~= 'void' then 278 local i=1 279 while self.args[i] do 280 self.args[i]:getarray(narg) 281 narg = narg+1 282 i = i+1 283 end 284 end 285 286 -------------------------------------------------- 287 -- CEGUILua mod 288 -- init exception handling 289 local throws = false 290 do 291 local pattern = "tolua_throws|.*|" 292 local i,j = string.find(self.mod, pattern) 293 if i then 294 throws = {} 295 -- ensure table is empty. Used to be: table.setn(throws,0) 296 for x in pairs(throws) do 297 throws[x] = nil 298 end 299 local excepts = string.sub(self.mod, i+12,j) 300 local epattern = "|.-|" 301 local i,j = string.find(excepts, epattern) 302 while i do 303 local e = string.sub(excepts,i+1,j-1) 304 local _,_,name,rest = string.find(e, "([%w:_]+),?(.*)") 305 table.insert(throws,{name=name, ret=rest}) 306 i,j = string.find(excepts, epattern, j) 307 end 308 self.mod = string.gsub(self.mod, pattern, "") 309 end 310 end 311 local exRaiseError = false 312 -------------------------------------------------- 313 314 local out = string.find(self.mod, "tolua_outside") 315 316 --------------- 317 -- CEGUILua mod 318 -- remove "tolua_outside" from self.mod 319 if out then 320 self.mod = string.gsub(self.mod, "tolua_outside", "") 321 end 322 323 -- call function 324 if class and self.name=='delete' then 325 output(' delete self;') 326 elseif class and self.name == 'operator&[]' then 327 if flags['1'] then -- for compatibility with tolua5 ? 328 output(' self->operator[](',self.args[1].name,'-1) = ',self.args[2].name,';') 329 else 330 output(' self->operator[](',self.args[1].name,') = ',self.args[2].name,';') 331 end 332 else 333 -- CEGUILua mod begin- throws 334 if throws then 335 for i=1,table.getn(throws) do 336 if string.find(throws[i].ret, "error") then 337 output("char errorBuffer["..exceptionMessageBufferSize.."];\n") 338 output("bool errorDoIt = false;\n") 339 exRaiseError = true 340 break 341 end 342 end 343 output("try\n") 344 end 345 -- CEGUILua mod end - throws 346 output(' {') 347 if self.type ~= '' and self.type ~= 'void' then 348 output(' ',self.mod,self.type,self.ptr,'tolua_ret = ') 349 output('(',self.mod,self.type,self.ptr,') ') 350 else 351 output(' ') 352 end 353 if class and self.name=='new' then 354 output('new',self.type,'(') 355 elseif class and static then 356 if out then 357 output(self.name,'(') 358 else 359 output(class..'::'..self.name,'(') 360 end 361 elseif class then 362 if out then 363 output(self.name,'(') 364 else 365 if self.cast_operator then 366 output('static_cast<',self.mod,self.type,self.ptr,'>(*self') 367 else 368 output('self->'..self.name,'(') 369 end 370 end 371 else 372 output(self.name,'(') 373 end 374 375 if out and not static then 376 output('self') 377 if self.args[1] and self.args[1].name ~= '' then 378 output(',') 379 end 380 end 381 -- write parameters 382 local i=1 383 while self.args[i] do 384 self.args[i]:passpar() 385 i = i+1 386 if self.args[i] then 387 output(',') 388 end 389 end 390 391 if class and self.name == 'operator[]' and flags['1'] then 392 output('-1);') 393 else 394 output(');') 395 end 396 397 -- return values 398 if self.type ~= '' and self.type ~= 'void' then 399 nret = nret + 1 400 local t,ct = isbasic(self.type) 401 if t then 402 if self.cast_operator and _basic_raw_push[t] then 403 output(' ',_basic_raw_push[t],'(tolua_S,(',ct,')tolua_ret);') 404 else 405 output(' tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);') 406 end 407 else 408 t = self.type 409 new_t = string.gsub(t, "const%s+", "") 410 if self.ptr == '' then 411 output(' {') 412 output('#ifdef __cplusplus\n') 413 output(' void* tolua_obj = new',new_t,'(tolua_ret);') 414 output(' tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");') 415 output('#else\n') 416 output(' void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));') 417 output(' tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");') 418 output('#endif\n') 419 output(' }') 420 elseif self.ptr == '&' then 421 output(' tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");') 422 else 423 if local_constructor then 424 output(' tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");') 425 else 426 output(' tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");') 427 end 428 end 429 end 430 end 431 local i=1 432 while self.args[i] do 433 nret = nret + self.args[i]:retvalue() 434 i = i+1 435 end 436 output(' }') 437 438 ------------------------------------------ 439 -- CEGUILua mod 440 -- finish exception handling 441 -- catch 442 if throws then 443 outputExceptionCatchBlocks(self.name, throws, exRaiseError) 444 end 445 ------------------------------------------ 446 447 -- set array element values 448 if class then narg=2 else narg=1 end 449 if self.args[1].type ~= 'void' then 450 local i=1 451 while self.args[i] do 452 self.args[i]:setarray(narg) 453 narg = narg+1 454 i = i+1 455 end 456 end 457 458 -- free dynamically allocated array 459 if self.args[1].type ~= 'void' then 460 local i=1 461 while self.args[i] do 462 self.args[i]:freearray() 463 i = i+1 464 end 465 end 466 end 467 468 output(' }') 469 output(' return '..nret..';') 470 471 -- call overloaded function or generate error 472 if overload < 0 then 473 474 output('#ifndef TOLUA_RELEASE\n') 475 output('tolua_lerror:\n') 476 output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);') 477 output(' return 0;') 478 output('#endif\n') 479 else 480 local _local = "" 481 if local_constructor then 482 _local = "_local" 483 end 484 output('tolua_lerror:\n') 485 output(' return '..strsub(self.cname,1,-3)..format("%02d",overload).._local..'(tolua_S);') 486 end 487 output('}') 488 output('#endif //#ifndef TOLUA_DISABLE\n') 489 output('\n') 490 491 -- recursive call to write local constructor 492 if class and self.name=='new' and not local_constructor then 493 494 self:supcode(1) 495 end 496 496 497 497 end … … 501 501 function classFunction:register (pre) 502 502 503 504 505 506 507 508 509 510 511 512 output(pre..'tolua_function(tolua_S,"'..self.lname..'",'..self.cname..');')513 if self.name == 'new' then514 515 516 517 end503 if not self:check_public_access() then 504 return 505 end 506 507 if self.name == 'new' and self.parent.flags.pure_virtual then 508 -- no constructor for classes with pure virtual methods 509 return 510 end 511 512 output(pre..'tolua_function(tolua_S,"'..self.lname..'",'..self.cname..');') 513 if self.name == 'new' then 514 output(pre..'tolua_function(tolua_S,"new_local",'..self.cname..'_local);') 515 output(pre..'tolua_function(tolua_S,".call",'..self.cname..'_local);') 516 --output(' tolua_set_call_event(tolua_S,'..self.cname..'_local, "'..self.parent.type..'");') 517 end 518 518 end 519 519 520 520 -- Print method 521 521 function classFunction:print (ident,close) 522 print(ident.."Function{")523 print(ident.." mod = '"..self.mod.."',")524 print(ident.." type = '"..self.type.."',")525 print(ident.." ptr = '"..self.ptr.."',")526 print(ident.." name = '"..self.name.."',")527 print(ident.." lname = '"..self.lname.."',")528 print(ident.." const = '"..self.const.."',")529 print(ident.." cname = '"..self.cname.."',")530 print(ident.." lname = '"..self.lname.."',")531 print(ident.." args = {")532 local i=1533 while self.args[i] do534 self.args[i]:print(ident.." ",",")535 i = i+1536 end537 print(ident.." }")538 print(ident.."}"..close)522 print(ident.."Function{") 523 print(ident.." mod = '"..self.mod.."',") 524 print(ident.." type = '"..self.type.."',") 525 print(ident.." ptr = '"..self.ptr.."',") 526 print(ident.." name = '"..self.name.."',") 527 print(ident.." lname = '"..self.lname.."',") 528 print(ident.." const = '"..self.const.."',") 529 print(ident.." cname = '"..self.cname.."',") 530 print(ident.." lname = '"..self.lname.."',") 531 print(ident.." args = {") 532 local i=1 533 while self.args[i] do 534 self.args[i]:print(ident.." ",",") 535 i = i+1 536 end 537 print(ident.." }") 538 print(ident.."}"..close) 539 539 end 540 540 541 541 -- check if it returns an object by value 542 542 function classFunction:requirecollection (t) 543 544 545 546 547 548 549 550 551 552 553 554 543 local r = false 544 if self.type ~= '' and not isbasic(self.type) and self.ptr=='' then 545 local type = gsub(self.type,"%s*const%s+","") 546 t[type] = "tolua_collect_" .. clean_template(type) 547 r = true 548 end 549 local i=1 550 while self.args[i] do 551 r = self.args[i]:requirecollection(t) or r 552 i = i+1 553 end 554 return r 555 555 end 556 556 557 557 -- determine lua function name overload 558 558 function classFunction:overload () 559 return self.parent:overload(self.lname)559 return self.parent:overload(self.lname) 560 560 end 561 561 … … 563 563 function param_object(par) -- returns true if the parameter has an object as its default value 564 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 --if string.find(def, ":") or string.find(def, "^%s*new%s+") then590 591 ---- it's a reference with default to something like Class::member, or 'new Class'592 --return true593 --end594 595 596 565 if not string.find(par, '=') then return false end -- it has no default value 566 567 local _,_,def = string.find(par, "=(.*)$") 568 569 if string.find(par, "|") then -- a list of flags 570 571 return true 572 end 573 574 if string.find(par, "%*") then -- it's a pointer with a default value 575 576 if string.find(par, '=%s*new') then -- it's a pointer with an instance as default parameter.. is that valid? 577 return true 578 end 579 return false -- default value is 'NULL' or something 580 end 581 582 583 if string.find(par, "[%(&]") then 584 return true 585 end -- default value is a constructor call (most likely for a const reference) 586 587 --if string.find(par, "&") then 588 589 -- if string.find(def, ":") or string.find(def, "^%s*new%s+") then 590 591 -- -- it's a reference with default to something like Class::member, or 'new Class' 592 -- return true 593 -- end 594 --end 595 596 return false -- ? 597 597 end 598 598 599 599 function strip_last_arg(all_args, last_arg) -- strips the default value from the last argument 600 600 601 602 603 604 601 local _,_,s_arg = string.find(last_arg, "^([^=]+)") 602 last_arg = string.gsub(last_arg, "([%%%(%)])", "%%%1"); 603 all_args = string.gsub(all_args, "%s*,%s*"..last_arg.."%s*%)%s*$", ")") 604 return all_args, s_arg 605 605 end 606 606 … … 609 609 -- Internal constructor 610 610 function _Function (t) 611 setmetatable(t,classFunction)612 613 if t.const ~= 'const' and t.const ~= '' then614 error("#invalid 'const' specification")615 end616 617 append(t)618 if t:inclass() then619 --print ('t.name is '..t.name..', parent.name is '..t.parent.name)620 if string.gsub(t.name, "%b<>", "") == string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then621 t.name = 'new'622 t.lname = 'new'623 t.parent._new = true624 t.type = t.parent.name625 t.ptr = '*'626 elseif string.gsub(t.name, "%b<>", "") == '~'..string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then627 t.name = 'delete'628 t.lname = 'delete'629 t.parent._delete = true630 end631 end632 t.cname = t:cfuncname("tolua")..t:overload(t)633 return t611 setmetatable(t,classFunction) 612 613 if t.const ~= 'const' and t.const ~= '' then 614 error("#invalid 'const' specification") 615 end 616 617 append(t) 618 if t:inclass() then 619 --print ('t.name is '..t.name..', parent.name is '..t.parent.name) 620 if string.gsub(t.name, "%b<>", "") == string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then 621 t.name = 'new' 622 t.lname = 'new' 623 t.parent._new = true 624 t.type = t.parent.name 625 t.ptr = '*' 626 elseif string.gsub(t.name, "%b<>", "") == '~'..string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then 627 t.name = 'delete' 628 t.lname = 'delete' 629 t.parent._delete = true 630 end 631 end 632 t.cname = t:cfuncname("tolua")..t:overload(t) 633 return t 634 634 end 635 635 … … 639 639 -- the "const" or empty string. 640 640 function Function (d,a,c) 641 --local t = split(strsub(a,2,-2),',') -- eliminate braces642 --local t = split_params(strsub(a,2,-2))643 644 645 646 647 648 649 650 651 local i=1652 local l = {n=0}653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 while t[i] do670 l.n = l.n+1671 l[l.n] = Declaration(t[i],'var',true)672 i = i+1673 end674 local f = Declaration(d,'func')675 f.args = l676 f.const = c677 return _Function(f)641 --local t = split(strsub(a,2,-2),',') -- eliminate braces 642 --local t = split_params(strsub(a,2,-2)) 643 644 if not flags['W'] and string.find(a, "%.%.%.%s*%)") then 645 646 warning("Functions with variable arguments (`...') are not supported. Ignoring "..d..a..c) 647 return nil 648 end 649 650 651 local i=1 652 local l = {n=0} 653 654 a = string.gsub(a, "%s*([%(%)])%s*", "%1") 655 local t,strip,last = strip_pars(strsub(a,2,-2)); 656 if strip then 657 --local ns = string.sub(strsub(a,1,-2), 1, -(string.len(last)+1)) 658 local ns = join(t, ",", 1, last-1) 659 660 ns = "("..string.gsub(ns, "%s*,%s*$", "")..')' 661 --ns = strip_defaults(ns) 662 663 Function(d, ns, c) 664 for i=1,last do 665 t[i] = string.gsub(t[i], "=.*$", "") 666 end 667 end 668 669 while t[i] do 670 l.n = l.n+1 671 l[l.n] = Declaration(t[i],'var',true) 672 i = i+1 673 end 674 local f = Declaration(d,'func') 675 f.args = l 676 f.const = c 677 return _Function(f) 678 678 end 679 679 680 680 function join(t, sep, first, last) 681 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 682 first = first or 1 683 last = last or table.getn(t) 684 local lsep = "" 685 local ret = "" 686 local loop = false 687 for i = first,last do 688 689 ret = ret..lsep..t[i] 690 lsep = sep 691 loop = true 692 end 693 if not loop then 694 return "" 695 end 696 697 return ret 698 698 end 699 699 700 700 function strip_pars(s) 701 701 702 703 704 705 706 707 708 709 710 711 712 713 --t[i] = string.gsub(t[i], "=.*$", "")714 715 716 717 702 local t = split_c_tokens(s, ',') 703 local strip = false 704 local last 705 706 for i=t.n,1,-1 do 707 708 if not strip and param_object(t[i]) then 709 last = i 710 strip = true 711 end 712 --if strip then 713 -- t[i] = string.gsub(t[i], "=.*$", "") 714 --end 715 end 716 717 return t,strip,last 718 718 719 719 end … … 721 721 function strip_defaults(s) 722 722 723 724 725 726 727 728 729 730 731 732 733 734 735 end 736 737 723 s = string.gsub(s, "^%(", "") 724 s = string.gsub(s, "%)$", "") 725 726 local t = split_c_tokens(s, ",") 727 local sep, ret = "","" 728 for i=1,t.n do 729 t[i] = string.gsub(t[i], "=.*$", "") 730 ret = ret..sep..t[i] 731 sep = "," 732 end 733 734 return "("..ret..")" 735 end 736 737 -
code/branches/buildsystem3/src/tolua/lua/module.lua
r2087 r2664 17 17 -- {i} = list of objects in the module. 18 18 classModule = { 19 classtype = 'module'19 classtype = 'module' 20 20 } 21 21 classModule.__index = classModule … … 24 24 -- register module 25 25 function classModule:register (pre) 26 pre = pre or ''27 push(self)28 output(pre..'tolua_module(tolua_S,"'..self.name..'",',self:hasvar(),');')29 output(pre..'tolua_beginmodule(tolua_S,"'..self.name..'");')30 local i=131 while self[i] do32 self[i]:register(pre..' ')33 i = i+134 end35 output(pre..'tolua_endmodule(tolua_S);')36 26 pre = pre or '' 27 push(self) 28 output(pre..'tolua_module(tolua_S,"'..self.name..'",',self:hasvar(),');') 29 output(pre..'tolua_beginmodule(tolua_S,"'..self.name..'");') 30 local i=1 31 while self[i] do 32 self[i]:register(pre..' ') 33 i = i+1 34 end 35 output(pre..'tolua_endmodule(tolua_S);') 36 pop() 37 37 end 38 38 39 39 -- Print method 40 40 function classModule:print (ident,close) 41 print(ident.."Module{")42 print(ident.." name = '"..self.name.."';")43 local i=144 while self[i] do45 self[i]:print(ident.." ",",")46 i = i+147 end48 print(ident.."}"..close)41 print(ident.."Module{") 42 print(ident.." name = '"..self.name.."';") 43 local i=1 44 while self[i] do 45 self[i]:print(ident.." ",",") 46 i = i+1 47 end 48 print(ident.."}"..close) 49 49 end 50 50 51 51 -- Internal constructor 52 52 function _Module (t) 53 setmetatable(t,classModule)54 append(t)55 return t53 setmetatable(t,classModule) 54 append(t) 55 return t 56 56 end 57 57 … … 59 59 -- Expects two string representing the module name and body. 60 60 function Module (n,b) 61 local t = _Module(_Container{name=n})62 push(t)63 t:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces64 pop()65 return t61 local t = _Module(_Container{name=n}) 62 push(t) 63 t:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces 64 pop() 65 return t 66 66 end 67 67 -
code/branches/buildsystem3/src/tolua/lua/namespace.lua
r2087 r2664 17 17 -- {i} = list of members 18 18 classNamespace = { 19 classtype = 'namespace',20 name = '',19 classtype = 'namespace', 20 name = '', 21 21 } 22 22 classNamespace.__index = classNamespace … … 25 25 -- Print method 26 26 function classNamespace:print (ident,close) 27 print(ident.."Namespace{")28 print(ident.." name = '"..self.name.."',")29 local i=130 while self[i] do31 self[i]:print(ident.." ",",")32 i = i+133 end34 print(ident.."}"..close)27 print(ident.."Namespace{") 28 print(ident.." name = '"..self.name.."',") 29 local i=1 30 while self[i] do 31 self[i]:print(ident.." ",",") 32 i = i+1 33 end 34 print(ident.."}"..close) 35 35 end 36 36 37 37 -- Internal constructor 38 38 function _Namespace (t) 39 setmetatable(t,classNamespace)40 append(t)41 return t39 setmetatable(t,classNamespace) 40 append(t) 41 return t 42 42 end 43 43 … … 45 45 -- Expects the name and the body of the namespace. 46 46 function Namespace (n,b) 47 local c = _Namespace(_Container{name=n})48 push(c)49 c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces50 pop()47 local c = _Namespace(_Container{name=n}) 48 push(c) 49 c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces 50 pop() 51 51 end 52 52 -
code/branches/buildsystem3/src/tolua/lua/operator.lua
r2087 r2664 16 16 -- kind = set of character representing the operator (as it appers in C++ code) 17 17 classOperator = { 18 kind = '',18 kind = '', 19 19 } 20 20 classOperator.__index = classOperator … … 22 22 23 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 } 24 _TM = { 25 ['+'] = 'add', 26 ['-'] = 'sub', 27 ['*'] = 'mul', 28 ['/'] = 'div', 29 ['<'] = 'lt', 30 ['<='] = 'le', 31 ['=='] = 'eq', 32 ['[]'] = 'geti', 33 ['&[]'] = 'seti', 34 --['->'] = 'flechita', 35 } 35 36 36 37 37 38 -- Print method 38 39 function 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=150 while self.args[i] do51 self.args[i]:print(ident.." ",",")52 i = i+153 end54 print(ident.." }")55 print(ident.."}"..close)40 print(ident.."Operator{") 41 print(ident.." kind = '"..self.kind.."',") 42 print(ident.." mod = '"..self.mod.."',") 43 print(ident.." type = '"..self.type.."',") 44 print(ident.." ptr = '"..self.ptr.."',") 45 print(ident.." name = '"..self.name.."',") 46 print(ident.." const = '"..self.const.."',") 47 print(ident.." cname = '"..self.cname.."',") 48 print(ident.." lname = '"..self.lname.."',") 49 print(ident.." args = {") 50 local i=1 51 while self.args[i] do 52 self.args[i]:print(ident.." ",",") 53 i = i+1 54 end 55 print(ident.." }") 56 print(ident.."}"..close) 56 57 end 57 58 58 59 function classOperator:supcode_tmp() 59 60 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 61 if not _TM[self.kind] then 62 return classFunction.supcode(self) 63 end 64 65 -- no overload, no parameters, always inclass 66 output("/* method:",self.name," of class ",self:inclass()," */") 67 68 output("#ifndef TOLUA_DISABLE_"..self.cname) 69 output("\nstatic int",self.cname,"(lua_State* tolua_S)") 70 71 if overload < 0 then 72 output('#ifndef TOLUA_RELEASE\n') 73 end 74 output(' tolua_Error tolua_err;') 75 output(' if (\n') 76 -- check self 77 output(' !'..'tolua_isusertype(tolua_S,1,"'..self.parent.type..'",0,&tolua_err) ||\n') 78 output(' !tolua_isnoobj(tolua_S,2,&tolua_err)\n )') 79 output(' goto tolua_lerror;') 80 81 output(' else\n') 82 output('#endif\n') -- tolua_release 83 output(' {') 84 85 -- declare self 86 output(' ',self.const,self.parent.type,'*','self = ') 87 output('(',self.const,self.parent.type,'*) ') 88 output('tolua_tousertype(tolua_S,1,0);') 89 90 -- check self 91 output('#ifndef TOLUA_RELEASE\n') 92 output(' if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);'); 93 output('#endif\n') 94 95 -- cast self 96 output(' ',self.mod,self.type,self.ptr,'tolua_ret = ') 97 output('(',self.mod,self.type,self.ptr,')(*self);') 98 99 -- return value 100 local t,ct = isbasic(self.type) 101 if t then 102 output(' tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);') 103 else 104 t = self.type 105 new_t = string.gsub(t, "const%s+", "") 106 if self.ptr == '' then 107 output(' {') 108 output('#ifdef __cplusplus\n') 109 output(' void* tolua_obj = new',new_t,'(tolua_ret);') 110 output(' tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");') 111 output('#else\n') 112 output(' void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));') 113 output(' tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");') 114 output('#endif\n') 115 output(' }') 116 elseif self.ptr == '&' then 117 output(' tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");') 118 else 119 if local_constructor then 120 output(' tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");') 121 else 122 output(' tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");') 123 end 124 end 125 end 126 127 output(' }') 128 output(' return 1;') 129 130 output('#ifndef TOLUA_RELEASE\n') 131 output('tolua_lerror:\n') 132 output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);') 133 output(' return 0;') 134 output('#endif\n') 135 136 137 output('}') 138 output('#endif //#ifndef TOLUA_DISABLE\n') 139 output('\n') 139 140 end 140 141 141 142 -- Internal constructor 142 143 function _Operator (t) 143 setmetatable(t,classOperator)144 145 if t.const ~= 'const' and t.const ~= '' then146 error("#invalid 'const' specification")147 end148 149 append(t)150 if not t:inclass() then151 error("#operator can only be defined as class member")152 end153 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 name157 return t144 setmetatable(t,classOperator) 145 146 if t.const ~= 'const' and t.const ~= '' then 147 error("#invalid 'const' specification") 148 end 149 150 append(t) 151 if not t:inclass() then 152 error("#operator can only be defined as class member") 153 end 154 155 --t.name = t.name .. "_" .. (_TM[t.kind] or t.kind) 156 t.cname = t:cfuncname("tolua")..t:overload(t) 157 t.name = "operator" .. t.kind -- set appropriate calling name 158 return t 158 159 end 159 160 … … 161 162 function Operator (d,k,a,c) 162 163 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 local t = split_c_tokens(strsub(a,2,strlen(a)-1),',') -- eliminate braces181 local i=1182 local l = {n=0}183 while t[i] do184 l.n = l.n+1185 l[l.n] = Declaration(t[i],'var')186 i = i+1187 end188 if k == '[]' then189 190 191 d = gsub(d,'&','')192 elseif k=='&[]' then193 l.n = l.n+1194 l[l.n] = Declaration(d,'var')195 l[l.n].name = 'tolua_value'196 end197 local f = Declaration(d,'func')198 if k == '[]' and (l[1]==nil or isbasic(l[1].type)~='number') then199 error('operator[] can only be defined for numeric index.')200 end201 f.args = l202 f.const = c203 f.kind = op_k204 f.lname = "."..(_TM[f.kind] or f.kind)205 if not _TM[f.kind] then206 207 end208 if f.kind == '[]' and ref=='&' and f.const~='const' then209 Operator(d,'&'..k,a,c)-- create correspoding set operator210 end211 return _Operator(f)212 end 213 214 164 local op_k = string.gsub(k, "^%s*", "") 165 op_k = string.gsub(k, "%s*$", "") 166 --if string.find(k, "^[%w_:%d<>%*%&]+$") then 167 if d == "operator" and k ~= '' then 168 169 d = k.." operator" 170 elseif not _TM[op_k] then 171 172 if flags['W'] then 173 error("tolua: no support for operator" .. f.kind) 174 else 175 warning("No support for operator "..op_k..", ignoring") 176 return nil 177 end 178 end 179 180 local ref = '' 181 local t = split_c_tokens(strsub(a,2,strlen(a)-1),',') -- eliminate braces 182 local i=1 183 local l = {n=0} 184 while t[i] do 185 l.n = l.n+1 186 l[l.n] = Declaration(t[i],'var') 187 i = i+1 188 end 189 if k == '[]' then 190 local _ 191 _, _, ref = strfind(d,'(&)') 192 d = gsub(d,'&','') 193 elseif k=='&[]' then 194 l.n = l.n+1 195 l[l.n] = Declaration(d,'var') 196 l[l.n].name = 'tolua_value' 197 end 198 local f = Declaration(d,'func') 199 if k == '[]' and (l[1]==nil or isbasic(l[1].type)~='number') then 200 error('operator[] can only be defined for numeric index.') 201 end 202 f.args = l 203 f.const = c 204 f.kind = op_k 205 f.lname = "."..(_TM[f.kind] or f.kind) 206 if not _TM[f.kind] then 207 f.cast_operator = true 208 end 209 if f.kind == '[]' and ref=='&' and f.const~='const' then 210 Operator(d,'&'..k,a,c) -- create correspoding set operator 211 end 212 return _Operator(f) 213 end 214 215 -
code/branches/buildsystem3/src/tolua/lua/package.lua
r2087 r2664 17 17 -- {i} = list of objects in the package. 18 18 classPackage = { 19 classtype = 'package'19 classtype = 'package' 20 20 } 21 21 classPackage.__index = classPackage … … 24 24 -- Print method 25 25 function classPackage:print () 26 print("Package: "..self.name)27 local i=128 while self[i] do29 self[i]:print("","")30 i = i+131 end26 print("Package: "..self.name) 27 local i=1 28 while self[i] do 29 self[i]:print("","") 30 i = i+1 31 end 32 32 end 33 33 34 34 function classPackage:preprocess () 35 35 36 -- avoid preprocessing embedded Lua code37 local L = {}38 self.code = gsub(self.code,"\n%s*%$%[","\1") -- deal with embedded lua code39 self.code = gsub(self.code,"\n%s*%$%]","\2")40 self.code = gsub(self.code,"(%b\1\2)",function (c)36 -- avoid preprocessing embedded Lua code 37 local L = {} 38 self.code = gsub(self.code,"\n%s*%$%[","\1") -- deal with embedded lua code 39 self.code = gsub(self.code,"\n%s*%$%]","\2") 40 self.code = gsub(self.code,"(%b\1\2)", function (c) 41 41 tinsert(L,c) 42 42 return "\n#["..getn(L).."]#" 43 end) 44 -- avoid preprocessing embedded C code 45 local C = {} 46 self.code = gsub(self.code,"\n%s*%$%<","\3") -- deal with embedded C code 47 self.code = gsub(self.code,"\n%s*%$%>","\4") 48 self.code = gsub(self.code,"(%b\3\4)", function (c) 43 end 44 ) 45 -- avoid preprocessing embedded C code 46 local C = {} 47 self.code = gsub(self.code,"\n%s*%$%<","\3") -- deal with embedded C code 48 self.code = gsub(self.code,"\n%s*%$%>","\4") 49 self.code = gsub(self.code,"(%b\3\4)", function (c) 49 50 tinsert(C,c) 50 51 return "\n#<"..getn(C)..">#" 51 end) 52 -- avoid preprocessing embedded C code 53 self.code = gsub(self.code,"\n%s*%$%{","\5") -- deal with embedded C code 54 self.code = gsub(self.code,"\n%s*%$%}","\6") 55 self.code = gsub(self.code,"(%b\5\6)", function (c) 52 end 53 ) 54 -- avoid preprocessing embedded C code 55 self.code = gsub(self.code,"\n%s*%$%{","\5") -- deal with embedded C code 56 self.code = gsub(self.code,"\n%s*%$%}","\6") 57 self.code = gsub(self.code,"(%b\5\6)", function (c) 56 58 tinsert(C,c) 57 59 return "\n#<"..getn(C)..">#" 58 end) 59 60 --self.code = gsub(self.code,"\n%s*#[^d][^\n]*\n", "\n\n") -- eliminate preprocessor directives that don't start with 'd' 61 self.code = gsub(self.code,"\n[ \t]*#[ \t]*[^d%<%[]", "\n//") -- eliminate preprocessor directives that don't start with 'd' 62 63 -- avoid preprocessing verbatim lines 64 local V = {} 65 self.code = gsub(self.code,"\n(%s*%$[^%[%]][^\n]*)",function (v) 66 tinsert(V,v) 67 return "\n#"..getn(V).."#" 68 end) 69 70 -- perform global substitution 71 72 self.code = gsub(self.code,"(//[^\n]*)","") -- eliminate C++ comments 73 self.code = gsub(self.code,"/%*","\1") 74 self.code = gsub(self.code,"%*/","\2") 75 self.code = gsub(self.code,"%b\1\2","") 76 self.code = gsub(self.code,"\1","/%*") 77 self.code = gsub(self.code,"\2","%*/") 78 self.code = gsub(self.code,"%s*@%s*","@") -- eliminate spaces beside @ 79 self.code = gsub(self.code,"%s?inline(%s)","%1") -- eliminate 'inline' keyword 80 --self.code = gsub(self.code,"%s?extern(%s)","%1") -- eliminate 'extern' keyword 81 --self.code = gsub(self.code,"%s?virtual(%s)","%1") -- eliminate 'virtual' keyword 82 --self.code = gsub(self.code,"public:","") -- eliminate 'public:' keyword 83 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*' 84 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*' 85 self.code = gsub(self.code,"([^%w_])char%s*%*","%1_cstring ") -- substitute 'char*' 86 self.code = gsub(self.code,"([^%w_])lua_State%s*%*","%1_lstate ") -- substitute 'lua_State*' 87 88 -- restore embedded Lua code 89 self.code = gsub(self.code,"%#%[(%d+)%]%#",function (n) 90 return L[tonumber(n)] 91 end) 92 -- restore embedded C code 93 self.code = gsub(self.code,"%#%<(%d+)%>%#",function (n) 94 return C[tonumber(n)] 95 end) 96 -- restore verbatim lines 97 self.code = gsub(self.code,"%#(%d+)%#",function (n) 98 return V[tonumber(n)] 99 end) 100 101 self.code = string.gsub(self.code, "\n%s*%$([^\n]+)", function (l) 102 Verbatim(l.."\n") 103 return "\n" 104 end) 60 end 61 ) 62 63 --self.code = gsub(self.code,"\n%s*#[^d][^\n]*\n", "\n\n") -- eliminate preprocessor directives that don't start with 'd' 64 self.code = gsub(self.code,"\n[ \t]*#[ \t]*[^d%<%[]", "\n//") -- eliminate preprocessor directives that don't start with 'd' 65 66 -- avoid preprocessing verbatim lines 67 local V = {} 68 self.code = gsub(self.code,"\n(%s*%$[^%[%]][^\n]*)", function (v) 69 tinsert(V,v) 70 return "\n#"..getn(V).."#" 71 end 72 ) 73 74 -- perform global substitution 75 76 self.code = gsub(self.code,"(//[^\n]*)","") -- eliminate C++ comments 77 self.code = gsub(self.code,"/%*","\1") 78 self.code = gsub(self.code,"%*/","\2") 79 self.code = gsub(self.code,"%b\1\2","") 80 self.code = gsub(self.code,"\1","/%*") 81 self.code = gsub(self.code,"\2","%*/") 82 self.code = gsub(self.code,"%s*@%s*","@") -- eliminate spaces beside @ 83 self.code = gsub(self.code,"%s?inline(%s)","%1") -- eliminate 'inline' keyword 84 --self.code = gsub(self.code,"%s?extern(%s)","%1") -- eliminate 'extern' keyword 85 --self.code = gsub(self.code,"%s?virtual(%s)","%1") -- eliminate 'virtual' keyword 86 --self.code = gsub(self.code,"public:","") -- eliminate 'public:' keyword 87 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*' 88 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*' 89 self.code = gsub(self.code,"([^%w_])char%s*%*","%1_cstring ") -- substitute 'char*' 90 self.code = gsub(self.code,"([^%w_])lua_State%s*%*","%1_lstate ") -- substitute 'lua_State*' 91 92 -- restore embedded Lua code 93 self.code = gsub(self.code,"%#%[(%d+)%]%#", function (n) 94 return L[tonumber(n)] 95 end 96 ) 97 -- restore embedded C code 98 self.code = gsub(self.code,"%#%<(%d+)%>%#", function (n) 99 return C[tonumber(n)] 100 end 101 ) 102 -- restore verbatim lines 103 self.code = gsub(self.code,"%#(%d+)%#", function (n) 104 return V[tonumber(n)] 105 end 106 ) 107 108 self.code = string.gsub(self.code, "\n%s*%$([^\n]+)", function (l) 109 Verbatim(l.."\n") 110 return "\n" 111 end 112 ) 105 113 end 106 114 107 115 -- translate verbatim 108 116 function classPackage:preamble () 109 output('/*\n') 110 output('** Lua binding: '..self.name..'\n') 111 output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n') 112 output('*/\n\n') 113 114 output('#ifndef __cplusplus\n') 115 output('#include "stdlib.h"\n') 116 output('#endif\n') 117 output('#include "string.h"\n\n') 118 output('#include "tolua/tolua++.h"\n\n') 119 120 if not flags.h then 121 -- local temp = string.reverse(flags.H) 122 -- local start1, end1 = string.find(temp, '/') 123 -- local start2, end2 = string.find(temp, '\\') 124 -- local res 125 -- if not start1 == nil then 126 -- if not start2 == nil then 127 -- if start1 > start2 then 128 -- res = string.sub(temp, 1, start2) 129 -- else 130 -- res = string.sub(temp, 1, start1) 131 -- end 132 -- else 133 -- res = string.sub(temp, 1, start1) 134 -- end 135 -- elseif not start2 == nil then 136 -- res = string.sub(temp, 1, start2) 137 -- end 138 -- res = string.reverse(res) 139 output('#include "tolua_bind.h"') 140 output('\n') 141 end 142 143 local i=1 144 while self[i] do 145 self[i]:preamble() 146 i = i+1 147 end 148 149 if self:requirecollection(_collect) then 150 output('\n') 151 output('/* function to release collected object via destructor */') 152 output('#ifdef __cplusplus\n') 153 for i,v in pairs(_collect) do 154 output('\nstatic int '..v..' (lua_State* tolua_S)') 155 output('{') 156 output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);') 157 output(' delete self;') 158 output(' return 0;') 159 output('}') 160 end 161 output('#endif\n\n') 162 end 163 164 output('\n') 165 output('/* function to register type */') 166 output('static void tolua_reg_types (lua_State* tolua_S)') 167 output('{') 168 foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end) 169 if flags.t then 170 output("#ifndef Mtolua_typeid\n#define Mtolua_typeid(L,TI,T)\n#endif\n") 171 foreach(_usertype,function(n,v) output(' Mtolua_typeid(tolua_S,typeid(',v,'), "',v,'");') end) 172 end 173 output('}') 174 output('\n') 117 output('/*\n') 118 output('** Lua binding: '..self.name..'\n') 119 output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n') 120 output('*/\n\n') 121 122 output('#ifndef __cplusplus\n') 123 output('#include <stdlib.h>\n') 124 output('#endif\n') 125 output('#include <string.h>\n\n') 126 output('#include <tolua/tolua++.h>\n\n') 127 128 if flags.H then 129 local header = gsub(flags.H, '^.-([%w_]*%.[%w_]*)$', '%1') 130 local package_lower = string.lower(self.name) 131 output('#include "'..header..'"\n') 132 end 133 134 local i=1 135 while self[i] do 136 self[i]:preamble() 137 i = i+1 138 end 139 140 if self:requirecollection(_collect) then 141 output('\n') 142 output('/* function to release collected object via destructor */') 143 output('#ifdef __cplusplus\n') 144 for i,v in pairs(_collect) do 145 output('\nstatic int '..v..' (lua_State* tolua_S)') 146 output('{') 147 output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);') 148 output(' delete self;') 149 output(' return 0;') 150 output('}') 151 end 152 output('#endif\n\n') 153 end 154 155 output('\n') 156 output('/* function to register type */') 157 output('static void tolua_reg_types (lua_State* tolua_S)') 158 output('{') 159 foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end) 160 if flags.t then 161 output("#ifndef Mtolua_typeid\n#define Mtolua_typeid(L,TI,T)\n#endif\n") 162 foreach(_usertype,function(n,v) output(' Mtolua_typeid(tolua_S,typeid(',v,'), "',v,'");') end) 163 end 164 output('}') 165 output('\n') 175 166 end 176 167 … … 178 169 -- write package open function 179 170 function classPackage:register (pre) 180 pre = pre or ''181 push(self)182 output(pre.."/* Open function */")183 output(pre.."int tolua_"..self.name.."_open (lua_State* tolua_S)")184 output(pre.."{")185 output(pre.." tolua_open(tolua_S);")186 output(pre.." tolua_reg_types(tolua_S);")187 output(pre.." tolua_module(tolua_S,NULL,",self:hasvar(),");")188 output(pre.." tolua_beginmodule(tolua_S,NULL);")189 local i=1190 while self[i] do191 self[i]:register(pre.." ")192 i = i+1193 end194 output(pre.." tolua_endmodule(tolua_S);")195 output(pre.." return 1;")196 output(pre.."}")197 198 output("\n\n")199 output("#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501\n");200 output(pre.."int luaopen_"..self.name.." (lua_State* tolua_S) {")201 output(pre.." return tolua_"..self.name.."_open(tolua_S);")202 output(pre.."};")203 output("#endif\n\n")204 205 171 pre = pre or '' 172 push(self) 173 output(pre.."/* Open function */") 174 output(pre.."int tolua_"..self.name.."_open (lua_State* tolua_S)") 175 output(pre.."{") 176 output(pre.." tolua_open(tolua_S);") 177 output(pre.." tolua_reg_types(tolua_S);") 178 output(pre.." tolua_module(tolua_S,NULL,",self:hasvar(),");") 179 output(pre.." tolua_beginmodule(tolua_S,NULL);") 180 local i=1 181 while self[i] do 182 self[i]:register(pre.." ") 183 i = i+1 184 end 185 output(pre.." tolua_endmodule(tolua_S);") 186 output(pre.." return 1;") 187 output(pre.."}") 188 189 output("\n\n") 190 output("#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501\n"); 191 output(pre.."int luaopen_"..self.name.." (lua_State* tolua_S) {") 192 output(pre.." return tolua_"..self.name.."_open(tolua_S);") 193 output(pre.."};") 194 output("#endif\n\n") 195 196 pop() 206 197 end 207 198 208 199 -- write header file 209 200 function classPackage:header () 210 output('/*\n') output('** Lua binding: '..self.name..'\n') 211 output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n') 212 output('*/\n\n') 213 214 if not flags.h then 215 output('#include "../'..self.name..'Prereqs.h"\n') 216 output('/* Exported function */') 217 output('_'..self.name..'Export int tolua_'..self.name..'_open (lua_State* tolua_S);') 218 output('\n') 219 end 201 output('/*\n') output('** Lua binding: '..self.name..'\n') 202 output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n') 203 output('*/\n\n') 204 205 if flags.H then 206 local package_lower = string.lower(self.name) 207 output('#include "'..package_lower..'/'..self.name..'Prereqs.h"\n') 208 output('/* Exported function */') 209 output('_'..self.name..'Export') 210 output('int tolua_'..self.name..'_open (lua_State* tolua_S);') 211 output('\n') 212 end 220 213 end 221 214 222 215 -- Internal constructor 223 216 function _Package (self) 224 setmetatable(self,classPackage)225 return self217 setmetatable(self,classPackage) 218 return self 226 219 end 227 220 … … 229 222 -- *** Thanks to Ariel Manzur for fixing bugs in nested directives *** 230 223 function extract_code(fn,s) 231 local code = '\n$#include "'..fn..'"\n' 232 s= "\n" .. s .. "\n" -- add blank lines as sentinels 233 local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n") 234 while e do 235 t = strlower(t) 236 if t == "begin" then 237 _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e) 238 if not e then 239 tolua_error("Unbalanced 'tolua_begin' directive in header file") 240 end 241 end 242 code = code .. c .. "\n" 243 _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e) 244 end 245 return code 224 local code = '\n$#include "'..string.lower(flags.n)..'/'..fn..'"\n' 225 s= "\n" .. s .. "\n" -- add blank lines as sentinels 226 227 -- eliminate export macro problems in class declarations 228 s = gsub(s, ' _%w*Export ', ' ') 229 230 local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n") 231 while e do 232 t = strlower(t) 233 if t == "begin" then 234 _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e) 235 if not e then 236 tolua_error("Unbalanced 'tolua_begin' directive in header file") 237 end 238 end 239 code = code .. c .. "\n" 240 _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e) 241 end 242 return code 246 243 end 247 244 … … 249 246 -- Expects the package name, the file extension, and the file text. 250 247 function Package (name,fn) 251 local ext = "pkg" 252 253 -- open input file, if any 254 if fn then 255 local st, msg = readfrom(flags.f) 256 if not st then 257 error('#'..msg) 258 end 259 local _; _, _, ext = strfind(fn,".*%.(.*)$") 260 end 261 local code = "\n" .. read('*a') 262 if ext == 'h' or ext == 'hpp' then 263 code = extract_code(fn,code) 264 end 265 266 -- close file 267 if fn then 268 readfrom() 269 end 270 271 -- deal with include directive 272 local nsubst 273 repeat 274 code,nsubst = gsub(code,'\n%s*%$(.)file%s*"(.-)"([^\n]*)\n', 275 function (kind,fn,extra) 276 local _, _, ext = strfind(fn,".*%.(.*)$") 277 local fp,msg = openfile(fn,'r') 278 if not fp then 279 error('#'..msg..': '..fn) 280 end 281 local s = read(fp,'*a') 282 closefile(fp) 283 if kind == 'c' or kind == 'h' then 284 return extract_code(fn,s) 285 elseif kind == 'p' then 286 return "\n\n" .. s 287 elseif kind == 'l' then 288 return "\n$[--##"..fn.."\n" .. s .. "\n$]\n" 289 elseif kind == 'i' then 290 local t = {code=s} 291 extra = string.gsub(extra, "^%s*,%s*", "") 292 local pars = split_c_tokens(extra, ",") 293 include_file_hook(t, fn, unpack(pars)) 294 return "\n\n" .. t.code 295 else 296 error('#Invalid include directive (use $cfile, $pfile, $lfile or $ifile)') 297 end 298 end) 299 until nsubst==0 300 301 -- deal with renaming directive 302 repeat -- I don't know why this is necesary 303 code,nsubst = gsub(code,'\n%s*%$renaming%s*(.-)%s*\n', function (r) appendrenaming(r) return "\n" end) 304 until nsubst == 0 305 306 local t = _Package(_Container{name=name, code=code}) 307 push(t) 308 preprocess_hook(t) 309 t:preprocess() 310 preparse_hook(t) 311 t:parse(t.code) 312 pop() 313 return t 314 end 315 316 248 local ext = "pkg" 249 250 -- open input file, if any 251 if fn then 252 local file 253 if flags.f then 254 if string.sub(flags.f, 1, 1) == '/' or string.sub(flags.f, 1, 1) == '\\' or (string.len(flags.f) > 1 and string.sub(flags.f, 2, 2) == ':') then 255 file = flags.f 256 else 257 file = flags.w..'/'..flags.f 258 end 259 else 260 file = flags.f 261 end 262 local st, msg = readfrom(file) 263 if not st then 264 error('#'..msg..' path: '..flags.f) 265 end 266 local _; _, _, ext = strfind(fn,".*%.(.*)$") 267 end 268 local code = "\n" .. read('*a') 269 if ext == 'h' or ext == 'hpp' then 270 code = extract_code(fn,code) 271 end 272 273 -- close file 274 if fn then 275 readfrom() 276 end 277 278 -- prepare working directory 279 local current_path 280 if not flags.w and flags.f then 281 current_path = gsub(flags.f, '(/)[^/]*%.?[^/]*$', '%1') 282 elseif flags.w then 283 if not (string.sub(flags.w, string.len(flags.w)) == '/') then 284 current_path = flags.w..'/' 285 else 286 current_path = flags.w 287 end 288 else 289 current_path = '' 290 end 291 292 -- deal with include directive 293 local nsubst 294 repeat 295 code,nsubst = gsub(code,'\n%s*%$(.)file%s*"(.-)"([^\n]*)\n', 296 function (kind,fn,extra) 297 local _, _, ext = strfind(fn,".*%.(.*)$") 298 local fp,msg = openfile(current_path..fn,'r') 299 if not fp then 300 error('#'..msg..': '..fn) 301 end 302 local s = read(fp,'*a') 303 closefile(fp) 304 if kind == 'c' or kind == 'h' then 305 return extract_code(fn,s) 306 elseif kind == 'p' then 307 return "\n\n" .. s 308 elseif kind == 'l' then 309 return "\n$[--##"..fn.."\n" .. s .. "\n$]\n" 310 elseif kind == 'i' then 311 local t = {code=s} 312 extra = string.gsub(extra, "^%s*,%s*", "") 313 local pars = split_c_tokens(extra, ",") 314 include_file_hook(t, fn, unpack(pars)) 315 return "\n\n" .. t.code 316 else 317 error('#Invalid include directive (use $cfile, $pfile, $lfile or $ifile)') 318 end 319 end 320 ) 321 until nsubst==0 322 323 -- deal with renaming directive 324 repeat -- I don't know why this is necesary 325 code,nsubst = gsub(code,'\n%s*%$renaming%s*(.-)%s*\n', function (r) appendrenaming(r) return "\n" end) 326 until nsubst == 0 327 328 local t = _Package(_Container{name=name, code=code}) 329 push(t) 330 preprocess_hook(t) 331 t:preprocess() 332 preparse_hook(t) 333 t:parse(t.code) 334 pop() 335 return t 336 end 337 338 -
code/branches/buildsystem3/src/tolua/lua/typedef.lua
r2087 r2664 21 21 -- mod = modifiers to the 'de facto' type 22 22 classTypedef = { 23 utype = '',24 mod = '',25 type = ''23 utype = '', 24 mod = '', 25 type = '' 26 26 } 27 27 classTypedef.__index = classTypedef … … 29 29 -- Print method 30 30 function classTypedef:print (ident,close) 31 print(ident.."Typedef{")32 print(ident.." utype = '"..self.utype.."',")33 print(ident.." mod = '"..self.mod.."',")34 print(ident.." type = '"..self.type.."',")35 print(ident.."}"..close)31 print(ident.."Typedef{") 32 print(ident.." utype = '"..self.utype.."',") 33 print(ident.." mod = '"..self.mod.."',") 34 print(ident.." type = '"..self.type.."',") 35 print(ident.."}"..close) 36 36 end 37 37 38 38 -- Return it's not a variable 39 39 function classTypedef:isvariable () 40 return false40 return false 41 41 end 42 42 43 43 -- Internal constructor 44 44 function _Typedef (t) 45 setmetatable(t,classTypedef)46 t.type = resolve_template_types(t.type)47 appendtypedef(t)48 return t45 setmetatable(t,classTypedef) 46 t.type = resolve_template_types(t.type) 47 appendtypedef(t) 48 return t 49 49 end 50 50 … … 52 52 -- Expects one string representing the type definition. 53 53 function Typedef (s) 54 if strfind(string.gsub(s, '%b<>', ''),'[%*&]') then55 tolua_error("#invalid typedef: pointers (and references) are not supported")56 end57 local o = {mod = ''}58 if string.find(s, "[<>]") then59 60 else61 62 63 64 65 66 67 end68 return _Typedef(o)54 if strfind(string.gsub(s, '%b<>', ''),'[%*&]') then 55 tolua_error("#invalid typedef: pointers (and references) are not supported") 56 end 57 local o = {mod = ''} 58 if string.find(s, "[<>]") then 59 _,_,o.type,o.utype = string.find(s, "^%s*([^<>]+%b<>[^%s]*)%s+(.-)$") 60 else 61 local t = split(gsub(s,"%s%s*"," ")," ") 62 o = { 63 utype = t[t.n], 64 type = t[t.n-1], 65 mod = concat(t,1,t.n-2), 66 } 67 end 68 return _Typedef(o) 69 69 end 70 70 -
code/branches/buildsystem3/src/tolua/lua/variable.lua
r2087 r2664 15 15 -- Stores all fields present in a declaration. 16 16 classVariable = { 17 _get = {}, -- mapped get functions18 _set = {}, -- mapped set functions17 _get = {}, -- mapped get functions 18 _set = {}, -- mapped set functions 19 19 } 20 20 classVariable.__index = classVariable … … 23 23 -- Print method 24 24 function 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.."',") end31 print(ident.." def = '"..self.def.."',")32 print(ident.." ret = '"..self.ret.."',")33 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) 34 34 end 35 35 36 36 -- Generates C function name 37 37 function 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 then45 46 47 48 49 50 end51 52 if strfind(self.mod,"(unsigned)") then53 unsigned = "_unsigned"54 end55 56 if self.ptr == "*" then ptr = "_ptr"57 elseif self.ptr == "&" then ptr = "_ref"58 end59 60 local name = prefix .. parent .. unsigned .. "_" .. gsub(self.lname or self.name,".*::","") .. ptr61 62 63 return name38 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 64 65 65 end … … 67 67 -- check if it is a variable 68 68 function classVariable:isvariable () 69 return true69 return true 70 70 end 71 71 … … 73 73 function classVariable:getvalue (class,static, prop_get) 74 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 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 90 90 end 91 91 92 92 -- get variable pointer value 93 93 function classVariable:getpointervalue (class,static) 94 if class and static then95 return class..'::p'96 elseif class then97 return 'self->p'98 else99 return 'p'100 end94 if class and static then 95 return class..'::p' 96 elseif class then 97 return 'self->p' 98 else 99 return 'p' 100 end 101 101 end 102 102 … … 106 106 local class = self:inclass() 107 107 108 109 110 111 112 113 114 115 116 117 -- get function ------------------------------------------------118 if class then119 output("/* get function:",self.name," of class ",class," */")120 else121 output("/* get function:",self.name," */")122 end123 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 case129 local _,_,static = strfind(self.mod,'^%s*(static)')130 if class and static==nil then131 output(' ',self.parent.type,'*','self = ')132 output('(',self.parent.type,'*) ')133 output('tolua_tousertype(tolua_S,1,0);')134 elseif static then135 _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')136 end137 138 139 -- check self value140 if class and static==nil then141 142 output(' if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');143 144 end145 146 -- return value147 if string.find(self.mod, 'tolua_inherits') then148 149 150 151 152 153 else154 155 156 157 158 159 160 161 162 163 164 165 end166 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')) then173 if class then174 output("/* set function:",self.name," of class ",class," */")175 else176 output("/* set function:",self.name," */")177 end178 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 case184 if class and static==nil then185 output(' ',self.parent.type,'*','self = ')186 output('(',self.parent.type,'*) ')187 output('tolua_tousertype(tolua_S,1,0);')188 -- check self value189 190 -- check types191 192 193 if class and static==nil then194 output(' if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');195 elseif static then196 _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')197 end198 199 -- check variable type200 output(' if (!'..self:outchecktype(2)..')')201 output(' tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);')202 203 204 -- assign value205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 output(' return 0;')255 output('}')256 output('#endif //#ifndef TOLUA_DISABLE\n')257 output('\n')258 end108 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 259 260 260 end … … 262 262 function classVariable:register (pre) 263 263 264 265 266 267 pre = pre or ''268 local parent = self:inmodule() or self:innamespace() or self:inclass()269 if not parent then270 if classVariable._warning==nil then271 warning("Mapping variable to global may degrade performance")272 classVariable._warning = 1273 end274 end275 if self.csetname then276 output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')277 else278 output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')279 end264 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 280 280 end 281 281 282 282 -- Internal constructor 283 283 function _Variable (t) 284 setmetatable(t,classVariable)285 append(t)286 return t284 setmetatable(t,classVariable) 285 append(t) 286 return t 287 287 end 288 288 … … 290 290 -- Expects a string representing the variable declaration. 291 291 function Variable (s) 292 return _Variable (Declaration(s,'var'))293 end 294 295 292 return _Variable (Declaration(s,'var')) 293 end 294 295 -
code/branches/buildsystem3/src/tolua/lua/verbatim.lua
r2087 r2664 17 17 -- line = line text 18 18 classVerbatim = { 19 line = '',20 19 line = '', 20 cond = nil, -- condition: where to generate the code (s=suport, r=register) 21 21 } 22 22 classVerbatim.__index = classVerbatim … … 25 25 -- preamble verbatim 26 26 function classVerbatim:preamble () 27 if self.cond == '' then28 write(self.line)29 end27 if self.cond == '' then 28 write(self.line) 29 end 30 30 end 31 31 32 32 -- support code 33 33 function classVerbatim:supcode () 34 if strfind(self.cond,'s') then35 write(self.line)36 write('\n')37 end34 if strfind(self.cond,'s') then 35 write(self.line) 36 write('\n') 37 end 38 38 end 39 39 40 40 -- register code 41 41 function classVerbatim:register (pre) 42 if strfind(self.cond,'r') then43 write(self.line)44 end42 if strfind(self.cond,'r') then 43 write(self.line) 44 end 45 45 end 46 46 … … 48 48 -- Print method 49 49 function classVerbatim:print (ident,close) 50 print(ident.."Verbatim{")51 print(ident.." line = '"..self.line.."',")52 print(ident.."}"..close)53 end50 print(ident.."Verbatim{") 51 print(ident.." line = '"..self.line.."',") 52 print(ident.."}"..close) 53 end 54 54 55 55 56 56 -- Internal constructor 57 57 function _Verbatim (t) 58 setmetatable(t,classVerbatim)59 append(t)60 return t58 setmetatable(t,classVerbatim) 59 append(t) 60 return t 61 61 end 62 62 … … 64 64 -- Expects a string representing the text line 65 65 function Verbatim (l,cond) 66 if strsub(l,1,1) == "'" then67 l = strsub(l,2)68 elseif strsub(l,1,1) == '$' then69 cond = 'sr' -- generates in both suport and register fragments70 l = strsub(l,2)71 end72 return _Verbatim {73 line = l,74 cond = cond or '',75 }66 if strsub(l,1,1) == "'" then 67 l = strsub(l,2) 68 elseif strsub(l,1,1) == '$' then 69 cond = 'sr' -- generates in both suport and register fragments 70 l = strsub(l,2) 71 end 72 return _Verbatim { 73 line = l, 74 cond = cond or '', 75 } 76 76 end 77 77
Note: See TracChangeset
for help on using the changeset viewer.