Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pch/src/tolua/lua/operator.lua @ 3129

Last change on this file since 3129 was 3127, checked in by rgrieder, 15 years ago

Update to tolua 1.0.93

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1-- tolua: operator 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-- Operator class
14-- Represents an operator function or a class operator method.
15-- It stores the same fields as functions do plus:
16--  kind = set of character representing the operator (as it appers in C++ code)
17classOperator = {
18    kind = '',
19}
20classOperator.__index = classOperator
21setmetatable(classOperator,classFunction)
22
23-- table to transform operator kind into the appropriate tag method name
24_TM = {
25    ['+'] = 'add',
26    ['-'] = 'sub',
27    ['*'] = 'mul',
28    ['/'] = 'div',
29    ['<'] = 'lt',
30    ['<='] = 'le',
31    ['=='] = 'eq',
32    ['[]'] = 'geti',
33    ['&[]'] = 'seti',
34    --['->'] = 'flechita',
35}
36
37
38-- Print method
39function classOperator:print (ident,close)
40    print(ident.."Operator{")
41    print(ident.." kind  = '"..self.kind.."',")
42    print(ident.." mod  = '"..self.mod.."',")
43    print(ident.." type = '"..self.type.."',")
44    print(ident.." ptr  = '"..self.ptr.."',")
45    print(ident.." name = '"..self.name.."',")
46    print(ident.." const = '"..self.const.."',")
47    print(ident.." cname = '"..self.cname.."',")
48    print(ident.." lname = '"..self.lname.."',")
49    print(ident.." args = {")
50    local i=1
51    while self.args[i] do
52        self.args[i]:print(ident.."  ",",")
53        i = i+1
54    end
55    print(ident.." }")
56    print(ident.."}"..close)
57end
58
59function classOperator:supcode_tmp()
60
61    if not _TM[self.kind] then
62        return classFunction.supcode(self)
63    end
64
65    -- no overload, no parameters, always inclass
66    output("/* method:",self.name," of class ",self:inclass()," */")
67
68    output("#ifndef TOLUA_DISABLE_"..self.cname)
69    output("\nstatic int",self.cname,"(lua_State* tolua_S)")
70
71    if overload < 0 then
72        output('#ifndef TOLUA_RELEASE\n')
73    end
74    output(' tolua_Error tolua_err;')
75    output(' if (\n')
76    -- check self
77    local is_func = get_is_function(self.parent.type)
78    output('     !'..is_func..'(tolua_S,1,"'..self.parent.type..'",0,&tolua_err) ||\n')
79    output('     !tolua_isnoobj(tolua_S,2,&tolua_err)\n )')
80    output('  goto tolua_lerror;')
81
82    output(' else\n')
83    output('#endif\n') -- tolua_release
84    output(' {')
85
86    -- declare self
87    output(' ',self.const,self.parent.type,'*','self = ')
88    output('(',self.const,self.parent.type,'*) ')
89    local to_func = get_to_func(self.parent.type)
90    output(to_func,'(tolua_S,1,0);')
91
92    -- check self
93    output('#ifndef TOLUA_RELEASE\n')
94    output('  if (!self) tolua_error(tolua_S,"'..output_error_hook("invalid \'self\' in function \'%s\'", self.name)..'",NULL);');
95    output('#endif\n')
96
97    -- cast self
98    output('  ',self.mod,self.type,self.ptr,'tolua_ret = ')
99    output('(',self.mod,self.type,self.ptr,')(*self);')
100
101    -- return value
102    local t,ct = isbasic(self.type)
103    if t then
104        output('   tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);')
105    else
106        t = self.type
107        local push_func = get_push_function(t)
108        new_t = string.gsub(t, "const%s+", "")
109        if self.ptr == '' then
110            output('   {')
111            output('#ifdef __cplusplus\n')
112            output('    void* tolua_obj = Mtolua_new((',new_t,')(tolua_ret));')
113            output('    ',push_func,'(tolua_S,tolua_obj,"',t,'");')
114            output('    tolua_register_gc(tolua_S,lua_gettop(tolua_S));')
115            output('#else\n')
116            output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
117            output('    ',push_func,'(tolua_S,tolua_obj,"',t,'");')
118            output('    tolua_register_gc(tolua_S,lua_gettop(tolua_S));')
119            output('#endif\n')
120            output('   }')
121        elseif self.ptr == '&' then
122            output('   ',push_func,'(tolua_S,(void*)&tolua_ret,"',t,'");')
123        else
124            if local_constructor then
125                output('   ',push_func,'(tolua_S,(void *)tolua_ret,"',t,'");')
126                output('    tolua_register_gc(tolua_S,lua_gettop(tolua_S));')
127            else
128                output('   ',push_func,'(tolua_S,(void*)tolua_ret,"',t,'");')
129            end
130        end
131    end
132
133    output('  }')
134    output(' return 1;')
135
136    output('#ifndef TOLUA_RELEASE\n')
137    output('tolua_lerror:\n')
138    output(' tolua_error(tolua_S,"'..output_error_hook("#ferror in function \'%s\'.", self.lname)..'",&tolua_err);')
139    output(' return 0;')
140    output('#endif\n')
141
142
143    output('}')
144    output('#endif //#ifndef TOLUA_DISABLE\n')
145    output('\n')
146end
147
148-- Internal constructor
149function _Operator (t)
150    setmetatable(t,classOperator)
151
152    if t.const ~= 'const' and t.const ~= '' then
153        error("#invalid 'const' specification")
154    end
155
156    append(t)
157    if not t:inclass() then
158        error("#operator can only be defined as class member")
159    end
160
161    --t.name = t.name .. "_" .. (_TM[t.kind] or t.kind)
162    t.cname = t:cfuncname("tolua")..t:overload(t)
163    t.name = "operator" .. t.kind  -- set appropriate calling name
164    return t
165end
166
167-- Constructor
168function Operator (d,k,a,c)
169
170    local op_k = string.gsub(k, "^%s*", "")
171    op_k = string.gsub(k, "%s*$", "")
172    --if string.find(k, "^[%w_:%d<>%*%&]+$") then
173    if d == "operator" and k ~= '' then
174
175        d = k.." operator"
176    elseif not _TM[op_k] then
177
178        if flags['W'] then
179            error("tolua: no support for operator" .. f.kind)
180        else
181            warning("No support for operator "..op_k..", ignoring")
182            return nil
183        end
184    end
185
186    local ref = ''
187    local t = split_c_tokens(strsub(a,2,strlen(a)-1),',') -- eliminate braces
188    local i=1
189    local l = {n=0}
190    while t[i] do
191        l.n = l.n+1
192        l[l.n] = Declaration(t[i],'var')
193        i = i+1
194    end
195    if k == '[]' then
196        local _
197        _, _, ref = strfind(d,'(&)')
198        d = gsub(d,'&','')
199    elseif k=='&[]' then
200        l.n = l.n+1
201        l[l.n] = Declaration(d,'var')
202        l[l.n].name = 'tolua_value'
203    end
204    local f = Declaration(d,'func')
205    if k == '[]' and (l[1]==nil or isbasic(l[1].type)~='number') then
206        error('operator[] can only be defined for numeric index.')
207    end
208    f.args = l
209    f.const = c
210    f.kind = op_k
211    f.lname = "."..(_TM[f.kind] or f.kind)
212    if not _TM[f.kind] then
213        f.cast_operator = true
214    end
215    if f.kind == '[]' and ref=='&' and f.const~='const' then
216        Operator(d,'&'..k,a,c)     -- create correspoding set operator
217    end
218    return _Operator(f)
219end
220
221
Note: See TracBrowser for help on using the repository browser.