Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 17, 2008, 8:59:48 PM (16 years ago)
Author:
rgrieder
Message:

Merged revisions 1875-2278 of the buildsystem branch to buildsystem2.

Location:
code/branches/buildsystem2
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/buildsystem2

  • code/branches/buildsystem2/src/tolua/lua/container.lua

    r2087 r2509  
    1919classContainer =
    2020{
    21  curr = nil,
     21    curr = nil,
    2222}
    2323classContainer.__index = classContainer
     
    2626-- output tags
    2727function classContainer:decltype ()
    28  push(self)
    29  local i=1
    30  while self[i] do
    31   self[i]:decltype()
    32   i = i+1
    33  end
    34  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()
    3535end
    3636
     
    3939function classContainer:supcode ()
    4040
    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()
     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()
    5454end
    5555
    5656function classContainer:hasvar ()
    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
     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
    6565end
    6666
    6767-- Internal container constructor
    6868function _Container (self)
    69  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
     69    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
    7676end
    7777
    7878-- push container
    7979function push (t)
    80         t.prox = classContainer.curr
    81  classContainer.curr = t
     80    t.prox = classContainer.curr
     81    classContainer.curr = t
    8282end
    8383
    8484-- pop container
    8585function pop ()
    86 --print("name",classContainer.curr.name)
    87 --foreach(classContainer.curr.usertypes,print)
    88 --print("______________")
    89  classContainer.curr = classContainer.curr.prox
     86    --print("name",classContainer.curr.name)
     87    --foreach(classContainer.curr.usertypes,print)
     88    --print("______________")
     89    classContainer.curr = classContainer.curr.prox
    9090end
    9191
    9292-- get current namespace
    9393function getcurrnamespace ()
    94         return getnamespace(classContainer.curr)
     94    return getnamespace(classContainer.curr)
    9595end
    9696
    9797-- append to current container
    9898function append (t)
    99  return classContainer.curr:append(t)
     99    return classContainer.curr:append(t)
    100100end
    101101
    102102-- append typedef to current container
    103103function appendtypedef (t)
    104  return classContainer.curr:appendtypedef(t)
     104    return classContainer.curr:appendtypedef(t)
    105105end
    106106
    107107-- append usertype to current container
    108108function appendusertype (t)
    109  return classContainer.curr:appendusertype(t)
     109    return classContainer.curr:appendusertype(t)
    110110end
    111111
    112112-- append enum to current container
    113113function appendenum (t)
    114  return classContainer.curr:appendenum(t)
     114    return classContainer.curr:appendenum(t)
    115115end
    116116
    117117-- substitute typedef
    118118function applytypedef (mod,type)
    119  return classContainer.curr:applytypedef(mod,type)
     119    return classContainer.curr:applytypedef(mod,type)
    120120end
    121121
    122122-- check if is type
    123123function findtype (type)
    124  local t = classContainer.curr:findtype(type)
    125         return t
     124    local t = classContainer.curr:findtype(type)
     125    return t
    126126end
    127127
    128128-- check if is typedef
    129129function istypedef (type)
    130  return classContainer.curr:istypedef(type)
     130    return classContainer.curr:istypedef(type)
    131131end
    132132
    133133-- get fulltype (with namespace)
    134134function fulltype (t)
    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
     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
    147147end
    148148
    149149-- checks if it requires collection
    150150function classContainer:requirecollection (t)
    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
     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
    160160end
    161161
     
    163163-- get namesapce
    164164function getnamespace (curr)
    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
     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
    176176end
    177177
    178178-- get namespace (only namespace)
    179179function getonlynamespace ()
    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
     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
    191191end
    192192
    193193-- check if is enum
    194194function isenum (type)
    195  return classContainer.curr:isenum(type)
     195    return classContainer.curr:isenum(type)
    196196end
    197197
    198198-- append feature to container
    199199function classContainer:append (t)
    200  self.n = self.n + 1
    201  self[self.n] = t
    202  t.parent = self
     200    self.n = self.n + 1
     201    self[self.n] = t
     202    t.parent = self
    203203end
    204204
    205205-- append typedef
    206206function 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
    219218end
    220219
    221220-- append usertype: return full type
    222221function classContainer:appendusertype (t)
    223         local container
    224         if t == (self.original_name or self.name) then
    225                 container = self.prox
    226         else
    227                 container = self
    228         end
    229         local ft = getnamespace(container) .. t
    230         container.usertypes[t] = ft
    231         _usertype[ft] = ft
    232         return ft
     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
    233232end
    234233
    235234-- append enum
    236235function classContainer:appendenum (t)
    237  local namespace = getnamespace(classContainer.curr)
    238  self.enums.tolua_n = self.enums.tolua_n + 1
    239  self.enums[self.enums.tolua_n] = t
    240         global_enums[namespace..t.name] = t
     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
    241240end
    242241
    243242-- determine lua function name overload
    244243function classContainer:overload (lname)
    245  if not self.lnames[lname] then
    246   self.lnames[lname] = 0
    247  else
    248   self.lnames[lname] = self.lnames[lname] + 1
    249  end
    250  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])
    251250end
    252251
    253252-- applies typedef: returns the 'the facto' modifier and type
    254253function classContainer:applytypedef (mod,type)
    255         if global_typedefs[type] then
    256                 --print("found typedef "..global_typedefs[type].type)
    257                 local mod1, type1 = global_typedefs[type].mod, global_typedefs[type].ftype
    258                 local mod2, type2 = applytypedef(mod.." "..mod1, type1)
    259                 --return mod2 .. ' ' .. mod1, type2
    260                 return mod2, type2
    261         end
    262         do return mod,type end
     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
    263262end
    264263
    265264-- check if it is a typedef
    266265function classContainer:istypedef (type)
    267  local env = self
    268  while env do
    269   if env.typedefs then
    270    local i=1
    271    while env.typedefs[i] do
    272     if env.typedefs[i].utype == type then
    273          return type
    274         end
    275         i = i+1
    276    end
    277   end
    278   env = env.parent
    279  end
    280  return nil
     266    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
    281280end
    282281
    283282function find_enum_var(var)
    284283
    285         if tonumber(var) then return var end
    286 
    287         local c = classContainer.curr
    288         while c do
    289                 local ns = getnamespace(c)
    290                 for k,v in pairs(_global_enums) do
    291                         if match_type(var, v, ns) then
    292                                 return v
    293                         end
    294                 end
    295                 if c.base and c.base ~= '' then
    296                         c = _global_classes[c:findtype(c.base)]
    297                 else
    298                         c = nil
    299                 end
    300         end
    301 
    302         return var
     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
    303302end
    304303
     
    306305function classContainer:findtype (t)
    307306
    308         t = string.gsub(t, "=.*", "")
    309         if _basic[t] then
    310         return t
    311         end
    312 
    313         local _,_,em = string.find(t, "([&%*])%s*$")
    314         t = string.gsub(t, "%s*([&%*])%s*$", "")
    315         p = self
    316         while p and type(p)=='table' do
    317                 local st = getnamespace(p)
    318 
    319                 for i=_global_types.n,1,-1 do -- in reverse order
    320 
    321                         if match_type(t, _global_types[i], st) then
    322                                 return _global_types[i]..(em or "")
    323                         end
    324                 end
    325                 if p.base and p.base ~= '' and p.base ~= t then
    326                         --print("type is "..t..", p is "..p.base.." self.type is "..self.type.." self.name is "..self.name)
    327                         p = _global_classes[p:findtype(p.base)]
    328                 else
    329                         p = nil
    330                 end
    331         end
    332 
    333         return nil
     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
    334333end
    335334
    336335function append_global_type(t, class)
    337         _global_types.n = _global_types.n +1
    338         _global_types[_global_types.n] = t
    339         _global_types_hash[t] = 1
    340         if class then append_class_type(t, class) end
     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
    341340end
    342341
    343342function append_class_type(t,class)
    344         if _global_classes[t] then
    345                 class.flags = _global_classes[t].flags
    346                 class.lnames = _global_classes[t].lnames
    347                 if _global_classes[t].base and (_global_classes[t].base ~= '') then
    348                         class.base = _global_classes[t].base or class.base
    349                 end
    350         end
    351         _global_classes[t] = class
    352         class.flags = class.flags or {}
     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 {}
    353352end
    354353
    355354function match_type(childtype, regtype, st)
    356355--print("findtype "..childtype..", "..regtype..", "..st)
    357         local b,e = string.find(regtype, childtype, -string.len(childtype), true)
    358         if b then
    359 
    360                 if e == string.len(regtype) and
    361                                 (b == 1 or (string.sub(regtype, b-1, b-1) == ':' and
    362                                 string.sub(regtype, 1, b-1) == string.sub(st, 1, b-1))) then
    363                         return true
    364                 end
    365         end
    366 
    367         return false
     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
    368367end
    369368
    370369function findtype_on_childs(self, t)
    371370
    372         local tchild
    373         if self.classtype == 'class' or self.classtype == 'namespace' then
    374                 for k,v in ipairs(self) do
    375                         if v.classtype == 'class' or v.classtype == 'namespace' then
    376                                 if v.typedefs and v.typedefs[t] then
    377                                 return v.typedefs[t]
    378                                 elseif v.usertypes and v.usertypes[t] then
    379                                 return v.usertypes[t]
    380                                 end
    381                                 tchild = findtype_on_childs(v, t)
    382                                 if tchild then return tchild end
    383                         end
    384                 end
    385         end
    386         return nil
     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
    387386
    388387end
    389388
    390389function classContainer:isenum (type)
    391  if global_enums[type] then
    392         return type
    393  else
    394         return false
    395  end
    396 
    397  local basetype = gsub(type,"^.*::","")
    398  local env = self
    399  while env do
    400   if env.enums then
    401    local i=1
    402    while env.enums[i] do
    403     if env.enums[i].name == basetype then
    404          return true
    405         end
    406         i = i+1
    407    end
    408   end
    409   env = env.parent
    410  end
    411  return false
     390    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
    412411end
    413412
     
    416415-- parse chunk
    417416function classContainer:doparse (s)
    418 --print ("parse "..s)
    419 
    420  -- try the parser hook
    421  do
    422         local sub = parser_hook(s)
    423         if sub then
    424                 return sub
    425         end
    426  end
    427 
    428  -- try the null statement
    429  do
    430         local b,e,code = string.find(s, "^%s*;")
    431         if b then
    432                 return strsub(s,e+1)
    433         end
    434  end
    435 
    436  -- try empty verbatim line
    437  do
    438         local b,e,code = string.find(s, "^%s*$\n")
    439         if b then
    440                 return strsub(s,e+1)
    441         end
    442  end
    443 
    444  -- try Lua code
    445  do
    446   local b,e,code = strfind(s,"^%s*(%b\1\2)")
    447   if b then
    448    Code(strsub(code,2,-2))
    449    return strsub(s,e+1)
    450   end
    451  end
    452 
    453  -- try C code
    454  do
    455   local b,e,code = strfind(s,"^%s*(%b\3\4)")
    456   if b then
    457         code = '{'..strsub(code,2,-2)..'\n}\n'
    458         Verbatim(code,'r')        -- verbatim code for 'r'egister fragment
    459         return strsub(s,e+1)
    460   end
    461  end
    462 
    463  -- try C code for preamble section
    464  do
    465         local b,e,code = string.find(s, "^%s*(%b\5\6)")
    466         if b then
    467                 code = string.sub(code, 2, -2).."\n"
    468                 Verbatim(code, '')
    469                 return string.sub(s, e+1)
    470         end
    471  end
    472 
    473  -- try default_property directive
    474  do
    475         local b,e,ptype = strfind(s, "^%s*TOLUA_PROPERTY_TYPE%s*%(+%s*([^%)%s]*)%s*%)+%s*;?")
    476         if b then
    477                 if not ptype or ptype == "" then
    478                         ptype = "default"
    479                 end
    480                 self:set_property_type(ptype)
    481                 return strsub(s, e+1)
    482         end
    483  end
    484 
    485  -- try protected_destructor directive
    486  do
    487         local b,e = string.find(s, "^%s*TOLUA_PROTECTED_DESTRUCTOR%s*;?")
    488         if b then
    489                 if self.set_protected_destructor then
    490                         self:set_protected_destructor(true)
    491                 end
    492                 return strsub(s, e+1)
    493         end
    494  end
    495 
    496  -- try 'extern' keyword
    497  do
    498         local b,e = string.find(s, "^%s*extern%s+")
    499         if b then
    500                 -- do nothing
    501                 return strsub(s, e+1)
    502         end
    503  end
    504        
    505  -- try 'virtual' keyworkd
    506  do
    507         local b,e = string.find(s, "^%s*virtual%s+")
    508         if b then
    509                 methodisvirtual = true
    510                 return strsub(s, e+1)
    511         end
    512  end
    513 
    514  -- try labels (public, private, etc)
    515  do
    516         local b,e = string.find(s, "^%s*%w*%s*:[^:]")
    517         if b then
    518                 return strsub(s, e) -- preserve the [^:]
    519         end
    520  end
    521 
    522  -- try module
    523  do
    524   local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*")
    525   if b then
    526    _curr_code = strsub(s,b,e)
    527    Module(name,body)
    528    return strsub(s,e+1)
    529   end
    530  end
    531 
    532  -- try namesapce
    533  do
    534   local b,e,name,body = strfind(s,"^%s*namespace%s%s*([_%w][_%w]*)%s*(%b{})%s*;?")
    535   if b then
    536    _curr_code = strsub(s,b,e)
    537    Namespace(name,body)
    538    return strsub(s,e+1)
    539   end
    540  end
    541 
    542  -- try define
    543  do
    544   local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*")
    545   if b then
    546    _curr_code = strsub(s,b,e)
    547    Define(name)
    548    return strsub(s,e+1)
    549   end
    550  end
    551 
    552  -- try enumerates
    553 
    554  do
    555   local b,e,name,body,varname = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*([^%s;]*)%s*;?%s*")
    556   if b then
    557    --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   end
    562  end
    563 
    564 -- do
    565 --  local b,e,name,body = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*;?%s*")
    566 --  if b then
    567 --   _curr_code = strsub(s,b,e)
    568 --   Enumerate(name,body)
    569 --  return strsub(s,e+1)
    570 --  end
    571 -- end
    572 
    573  do
    574   local b,e,body,name = strfind(s,"^%s*typedef%s+enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*")
    575   if b then
    576    _curr_code = strsub(s,b,e)
    577    Enumerate(name,body)
    578    return strsub(s,e+1)
    579   end
    580  end
    581 
    582  -- try operator
    583  do
    584   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 then
    586                 -- try inline
    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   end
    589   if not b then
    590         -- try cast operator
    591         b,e,decl,kind,arg,const = strfind(s, "^%s*(operator)%s+([%w_:%d<>%*%&%s]+)%s*(%b())%s*(c?o?n?s?t?)");
    592         if b then
    593                 local _,ie = string.find(s, "^%s*%b{}", e+1)
    594                 if ie then
    595                         e = ie
    596                 end
    597         end
    598   end
    599   if b then
    600    _curr_code = strsub(s,b,e)
    601    Operator(decl,kind,arg,const)
    602    return strsub(s,e+1)
    603   end
    604  end
    605 
    606  -- try function
    607  do
    608   --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 then
    611         -- try function with template
    612         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*")
    613   end
    614   if not b then
    615    -- try a single letter function name
    616    b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
    617   end
    618   if b then
    619         if virt and string.find(virt, "[=0]") then
    620                 if self.flags then
    621                         self.flags.pure_virtual = true
    622                 end
    623         end
    624    _curr_code = strsub(s,b,e)
    625    Function(decl,arg,const)
    626    return strsub(s,e+1)
    627   end
    628  end
    629 
    630  -- try inline function
    631  do
    632   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 then
    635    -- try a single letter function name
    636    b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?).-%b{}%s*;?%s*")
    637   end
    638   if b then
    639    _curr_code = strsub(s,b,e)
    640    Function(decl,arg,const)
    641    return strsub(s,e+1)
    642   end
    643  end
    644 
    645  -- try class
    646  do
    647         local b,e,name,base,body
    648                 base = '' body = ''
    649                 b,e,name = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*;")  -- dummy class
    650                 if not b then
    651                         b,e,name = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*;")    -- dummy struct
    652                         if not b then
    653                                 b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
    654                                 if not b then
    655                                         b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
    656                                         if not b then
    657                                                 b,e,name,base,body = strfind(s,"^%s*union%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
    658                                                 if not b then
    659                                                         base = ''
    660                                                         b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w@]*)%s*;%s*")
    661                                                 end
    662                                         end
    663                                 end
    664                         end
    665                 end
    666                 if b then
    667                         if base ~= '' then
    668                                 base = string.gsub(base, "^%s*:%s*", "")
    669                                 base = string.gsub(base, "%s*public%s*", "")
    670                                 base = split(base, ",")
    671                                 --local b,e
    672                                 --b,e,base = strfind(base,".-([_%w][_%w<>,:]*)$")
    673                         else
    674                                 base = {}
    675                         end
    676                         _curr_code = strsub(s,b,e)
    677                         Class(name,base,body)
    678                         return strsub(s,e+1)
    679                 end
    680         end
    681 
    682  -- try typedef
    683  do
    684   local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*")
    685   if b then
    686    _curr_code = strsub(s,b,e)
    687    Typedef(types)
    688    return strsub(s,e+1)
    689   end
    690  end
    691 
    692  -- try variable
    693  do
    694   local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&:<>,]*[_%w%d])%s*;%s*")
    695   if b then
    696    _curr_code = strsub(s,b,e)
    697 
    698         local list = split_c_tokens(decl, ",")
    699         Variable(list[1])
    700         if list.n > 1 then
    701                 local _,_,type = strfind(list[1], "(.-)%s+([^%s]*)$");
    702 
    703                 local i =2;
    704                 while list[i] do
    705                         Variable(type.." "..list[i])
    706                         i=i+1
    707                 end
    708         end
    709    --Variable(decl)
    710    return strsub(s,e+1)
    711   end
    712  end
    713 
    714         -- try string
    715  do
    716   local b,e,decl = strfind(s,"^%s*([_%w]?[_%s%w%d]-char%s+[_@%w%d]*%s*%[%s*%S+%s*%])%s*;%s*")
    717   if b then
    718    _curr_code = strsub(s,b,e)
    719    Variable(decl)
    720    return strsub(s,e+1)
    721   end
    722  end
    723 
    724  -- try array
    725  do
    726   local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:]*[]_%w%d])%s*;%s*")
    727   if b then
    728    _curr_code = strsub(s,b,e)
    729    Array(decl)
    730    return strsub(s,e+1)
    731   end
    732  end
    733 
    734  -- no matching
    735  if gsub(s,"%s%s*","") ~= "" then
    736   _curr_code = s
    737   error("#parse error")
    738  else
    739   return ""
    740  end
     417    --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
    741740
    742741end
     
    744743function classContainer:parse (s)
    745744
    746         self.curr_member_access = nil
    747 
    748  while s ~= '' do
    749   s = self:doparse(s)
    750   methodisvirtual = false
    751  end
     745    self.curr_member_access = nil
     746
     747    while s ~= '' do
     748        s = self:doparse(s)
     749        methodisvirtual = false
     750    end
    752751end
    753752
     
    757756function get_property_type()
    758757
    759         return classContainer.curr:get_property_type()
     758    return classContainer.curr:get_property_type()
    760759end
    761760
    762761function classContainer:set_property_type(ptype)
    763         ptype = string.gsub(ptype, "^%s*", "")
    764         ptype = string.gsub(ptype, "%s*$", "")
    765 
    766         self.property_type = ptype
     762    ptype = string.gsub(ptype, "^%s*", "")
     763    ptype = string.gsub(ptype, "%s*$", "")
     764
     765    self.property_type = ptype
    767766end
    768767
    769768function classContainer:get_property_type()
    770         return self.property_type or (self.parent and self.parent:get_property_type()) or "default"
    771 end
     769    return self.property_type or (self.parent and self.parent:get_property_type()) or "default"
     770end
Note: See TracChangeset for help on using the changeset viewer.