1-- tolua: container abstract class 2-- Written by Waldemar Celes 3-- TeCGraf/PUC-Rio 4-- Jul 1998 5-- $Id$ 6 7-- This code is free software; you can redistribute it and/or modify it. 8-- The software provided hereunder is on an "as is" basis, and 9-- the author has no obligation to provide maintenance, support, updates, 10-- enhancements, or modifications. 11 12 13-- Container class 14-- Represents a container of features to be bound 15-- to lua. 16classContainer = 17{ 18 curr = nil, 19 _base = classFeature, 20} 21settag(classContainer,tolua_tag) 22 23-- output tags 24function classContainer:decltag () 25 push(self) 26 local i=1 27 while self[i] do 28 self[i]:decltag() 29 i = i+1 30 end 31 pop() 32end 33 34 35-- write support code 36function classContainer:supcode () 37 push(self) 38 local i=1 39 while self[i] do 40 self[i]:supcode() 41 i = i+1 42 end 43 pop() 44end 45 46 47-- Internal container constructor 48function _Container (self) 49 self._base = classContainer 50 settag(self,tolua_tag) 51 self.n = 0 52 self.typedefs = {n=0} 53 self.lnames = {} 54 return self 55end 56 57-- push container 58function push (t) 59 classContainer.curr = t 60end 61 62-- pop container 63function pop () 64 classContainer.curr = classContainer.curr.parent 65end 66 67-- append to current container 68function append (t) 69 return classContainer.curr:append(t) 70end 71 72-- append typedef to current container 73function appendtypedef (t) 74 return classContainer.curr:appendtypedef(t) 75end 76 77-- substitute typedef 78function findtypedef (type) 79 return classContainer.curr:findtypedef(type) 80end 81 82-- check if is typedef 83function istypedef (type) 84 return classContainer.curr:istypedef(type) 85end 86 87-- append feature to container 88function classContainer:append (t) 89 self.n = self.n + 1 90 self[self.n] = t 91 t.parent = self 92end 93 94-- append typedef 95function classContainer:appendtypedef (t) 96 self.typedefs.n = self.typedefs.n + 1 97 self.typedefs[self.typedefs.n] = t 98end 99 100-- determine lua function name overload 101function classContainer:overload (lname) 102 if not self.lnames[lname] then 103 self.lnames[lname] = 0 104 else 105 self.lnames[lname] = self.lnames[lname] + 1 106 end 107 return format("%02d",self.lnames[lname]) 108end 109 110function classContainer:findtypedef (type) 111 local env = self 112 while env do 113 if env.typedefs then 114 local i=1 115 while env.typedefs[i] do 116 if env.typedefs[i].utype == type then 117 local mod1,type1 = env.typedefs[i].mod,env.typedefs[i].type 118 local mod2,type2 = findtypedef(type1) 119 return mod2..' '..mod1,type2 120 end 121 i = i+1 122 end 123 end 124 env = env.parent 125 end 126 return '',type 127end 128 129function classContainer:istypedef (type) 130 local env = self 131 while env do 132 if env.typedefs then 133 local i=1 134 while env.typedefs[i] do 135 if env.typedefs[i].utype == type then 136 return 1 137 end 138 i = i+1 139 end 140 end 141 env = env.parent 142 end 143 return nil 144end 145 146-- parse chunk 147function classContainer:doparse (s) 148 149 -- try module 150 do 151 local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*") 152 if b then 153 _curr_code = strsub(s,b,e) 154 Module(name,body) 155 return strsub(s,e+1) 156 end 157 end 158 159 -- try define 160 do 161 local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*") 162 if b then 163 _curr_code = strsub(s,b,e) 164 Define(name) 165 return strsub(s,e+1) 166 end 167 end 168 169 -- try enumerates 170 do 171 local b,e,body = strfind(s,"^%s*enum[^{]*(%b{})%s*;?%s*") 172 if b then 173 _curr_code = strsub(s,b,e) 174 Enumerate(body) 175 return strsub(s,e+1) 176 end 177 end 178 179 do 180 local b,e,body,name = strfind(s,"^%s*typedef%s%s*enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*") 181 if b then 182 _curr_code = strsub(s,b,e) 183 Enumerate(body) 184 Typedef("int "..name) 185 return strsub(s,e+1) 186 end 187 end 188 189 -- try operator 190 do 191 local b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&]*operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)%s*;%s*") 192 if b then 193 _curr_code = strsub(s,b,e) 194 Operator(decl,kind,arg,const) 195 return strsub(s,e+1) 196 end 197 end 198 199 -- try function 200 do 201 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*") 202 if not b then 203 -- try a single letter function name 204 b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*") 205 end 206 if b then 207 _curr_code = strsub(s,b,e) 208 Function(decl,arg,const) 209 return strsub(s,e+1) 210 end 211 end 212 213 -- try inline function 214 do 215 local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&]*[_%w])%s*(%b())%s*(c?o?n?s?t?)%s*%b{}%s*") 216 if not b then 217 -- try a single letter function name 218 b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*%b{}%s*") 219 end 220 if b then 221 _curr_code = strsub(s,b,e) 222 Function(decl,arg,const) 223 return strsub(s,e+1) 224 end 225 end 226 227 -- try class 228 do 229 local b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w]*)%s*(.-)%s*(%b{})%s*;%s*") 230 if not b then 231 b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w]*)%s*(.-)%s*(%b{})%s*;%s*") 232 if not b then 233 base = '' 234 b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w]*)%s*;%s*") 235 end 236 end 237 if b then 238 if base ~= '' then 239 local b,e 240 b,e,base = strfind(base,".-([_%w][_%w]*)$") 241 end 242 _curr_code = strsub(s,b,e) 243 Class(name,base,body) 244 return strsub(s,e+1) 245 end 246 end 247 248 -- try typedef 249 do 250 local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*") 251 if b then 252 _curr_code = strsub(s,b,e) 253 Typedef(types) 254 return strsub(s,e+1) 255 end 256 end 257 258 -- try variable 259 do 260 local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&]*[_%w%d])%s*;%s*") 261 if b then 262 _curr_code = strsub(s,b,e) 263 Variable(decl) 264 return strsub(s,e+1) 265 end 266 end 267 268 -- try array 269 do 270 local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&]*[]_%w%d])%s*;%s*") 271 if b then 272 _curr_code = strsub(s,b,e) 273 Array(decl) 274 return strsub(s,e+1) 275 end 276 end 277 278 -- try code 279 do 280 local b,e,code = strfind(s,"^%s*(%b\1\2)") 281 if b then 282 Code(strsub(code,2,-2)) 283 return strsub(s,e+1) 284 end 285 end 286 287 -- try verbatim 288 do 289 local b,e,line = strfind(s,"^%s*%$(.-\n)") 290 if b then 291 Verbatim(line) 292 return strsub(s,e+1) 293 end 294 end 295 296 -- no matching 297 if gsub(s,"%s%s*","") ~= "" then 298 _curr_code = s 299 error("#parse error") 300 else 301 return "" 302 end 303end 304 305function classContainer:parse (s) 306 while s ~= '' do 307 s = self:doparse(s) 308 end 309end 310 311 312