Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/archive/tutorial4/src/external/tolua/lua/class.lua

Last change on this file was 5738, checked in by landauf, 15 years ago

merged libraries2 back to trunk

  • Property svn:eol-style set to native
File size: 6.2 KB
Line 
1-- tolua: class 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-- Class class
14-- Represents a class definition.
15-- Stores the following fields:
16--    name = class name
17--    base = class base, if any (only single inheritance is supported)
18--    {i}  = list of members
19classClass = {
20    classtype = 'class',
21    name = '',
22    base = '',
23    type = '',
24    btype = '',
25    ctype = '',
26}
27classClass.__index = classClass
28setmetatable(classClass,classContainer)
29
30
31-- register class
32function classClass:register (pre)
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()
62end
63
64-- return collection requirement
65function classClass:requirecollection (t)
66    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
85end
86
87-- output tags
88function classClass:decltype ()
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()
104end
105
106
107-- Print method
108function 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=1
117    while self[i] do
118        self[i]:print(ident.." ",",")
119        i = i+1
120    end
121    print(ident.."}"..close)
122end
123
124function classClass:set_protected_destructor(p)
125self.flags.protected_destructor = self.flags.protected_destructor or p
126end
127
128-- Internal constructor
129function _Class (t)
130    setmetatable(t,classClass)
131    t:buildnames()
132    append(t)
133    return t
134end
135
136-- Constructor
137-- Expects the name, the base (array) and the body of the class.
138function Class (n,p,b)
139
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()
219end
220
Note: See TracBrowser for help on using the repository browser.