Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/tolua/lua/class.lua @ 2087

Last change on this file since 2087 was 2087, checked in by landauf, 16 years ago

merged objecthierarchy branch back to trunk

  • Property svn:eol-style set to native
File size: 5.5 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)
125        self.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.