Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/tolua/lua/class.lua @ 2030

Last change on this file since 2030 was 1650, checked in by rgrieder, 16 years ago

added preliminary automatic creation of tolua generator that creates the actual executable
(please don't ask about the egg-hen question…)

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.