Exemple #1
0
def test_class_method_overload():
    cls = cpp.cpp_class('MyTest')
    cls.qualname = "MyTest"

    method = cpp.cpp_method('method', 
              params=[cpp.cpp_variable('myvar', cpp.cpp_type('MyTestClass', const=True))])

    method1 = cpp.cpp_method('method', 
              params=[cpp.cpp_variable('myvar', cpp.cpp_type('int', const=True))])

    method2 = cpp.cpp_method('method', 
              params=[cpp.cpp_variable('myvar', cpp.cpp_type('int', const=True)),
                      cpp.cpp_variable('othervar', cpp.cpp_type('int', const=True))])    
    
    cls.public.append(method)
    method.parent = cls

    cls.public.append(method1)
    method1.parent = cls

    cls.public.append(method2)
    method2.parent = cls

    context = lua.lua_context_builder.bake([cls])

    assert len(context.translated) == 1

    t_cls = context.translated[0]
    
    assert t_cls
    assert t_cls.name == 'lua_munch_MyTest'
Exemple #2
0
def init_translated_method(orig_method, context):
    assert 'translation' not in orig_method.__dict__

    logging.debug('entered [init_translated_method] with method:' + repr(orig_method))

    method = cpp.cpp_method('lua_munch_' + orig_method.name,
            static=True, returns= cpp.cpp_type('int'),
            params=[cpp.cpp_variable('L', cpp.cpp_type('lua_State', pointer=True))])

    if orig_method.is_virtual:
        method.parameters.append(cpp.cpp_type(orig_method.parent.qualname, pointer= True))

    method.public = True

    #now we embed the default object with a very specific format that will be useful later
    method.initialization = [] # will contain initialization steps
    method.validation = [] # will contain validation steps
    method.recover = [] # will contain the steps to translate the lua arg to a C++ arg
    method.execution = [] # will contain execution steps, i.e, calling the native method
    method.lua_return = [] # will contain the steps to push a value back to lua

    if not 'is_overload' in method.__dict__:
        method.is_overload = False

    if orig_method.parent and orig_method.is_virtual:
        method.parameters.append(cpp.cpp_variable('lua_self', cpp.cpp_type(orig_method.parent.qualname, pointer=True)))

    if orig_method.is_constructor:
        method.name = 'lua_munch_' + orig_method.parent.name + '_constructor'

    method.return_value = cpp.cpp_return(0)

    #we 'tie' the translated method on the original method
    #so it's easier to work with them without needing to search for them on every callback
    orig_method.translation = method
Exemple #3
0
def test_class_base():    
    base = cpp.cpp_class('base')
    base.qualname = 'MyBaseClass'

    bmethod = cpp.cpp_method('base_method', 
              params=[cpp.cpp_variable('variable', cpp.cpp_type('int'))])
    
    bmethod.is_virtual = True

    base.public.append(bmethod)
    
    bmethod.parent = base

    cls = cpp.cpp_class('MyTest')
    cls.qualname = 'MyTestClass'
    
    cls.bases.append(base)

    method = cpp.cpp_method('method', 
              params=[cpp.cpp_variable('myvar', cpp.cpp_type('MyTestClass', const=True))])

    method1 = cpp.cpp_method('method', 
              params=[cpp.cpp_variable('myvar', cpp.cpp_type('int', const=True))])
    
    cls.public.append(method)
    method.parent = cls

    cls.public.append(method1)
    method1.parent = cls

    context = lua.lua_context_builder.bake([base, cls])

    assert len(context.translated) == 2

    t_cls = context.translated[1]
    
    assert t_cls
    assert t_cls.name == 'lua_munch_MyTest'

    print context.translated[0] 
    
    print t_cls

    assert False
Exemple #4
0
def test_method_return():
    method = cpp.cpp_method('method', returns=cpp.cpp_type('int'), return_value = 10)

    context = lua.lua_context_builder.bake([method])
    assert len(context.translated) == 1
    t_method = context.translated[0]
    
    assert t_method.static
    assert t_method.name == 'lua_munch_method'

    assert t_method.lua_return         
Exemple #5
0
def test_method_1():
    method = cpp.cpp_method('method')

    context = lua.lua_context_builder.bake([method])

    assert len(context.translated) == 1

    t_method = context.translated[0]
    
    assert t_method.static
    assert t_method.name == 'lua_munch_method'

    assert not t_method.lua_return
Exemple #6
0
def test_method_param_lua_primitives():  
    method = cpp.cpp_method('method', 
                params=[cpp.cpp_variable('myvar', cpp.cpp_type('int'))])

    context = lua.lua_context_builder.bake([method])

    assert len(context.translated) == 1
    t_method = context.translated[0]
    
    assert t_method.static
    assert t_method.name == 'lua_munch_method'
    assert t_method.initialization
    assert t_method.initialization[0]

    assert t_method.initialization[0] ==  method.parameters[0]
Exemple #7
0
def init_translated_class(orig_class, context):
    assert 'translation' not in orig_class.__dict__

    lua_cls = cpp.cpp_class('lua_munch_' + orig_class.identifier_name)

    luaReg = cpp.cpp_variable_array('lua_reg_' + orig_class.identifier_name, 
                                cpp.cpp_type('luaL_Reg', static=True))

    logging.debug('baking methods for class: %s : %s' % (orig_class.name ,orig_class.public))
    #we now bake all methods and subclasses from this class, but not preprocess them
    class_ctx = lua_context_builder.bake(orig_class.public, preprocess=False)

    for item in class_ctx.translated:
        if item.public:
            lua_cls.public.append(item)
        else:
            lua_cls.protected.append(item)

        if type(item) == cpp.cpp_method and not item.is_constructor and item.public:
            luaReg.expr.append('{ "%s" , lua_munch_%s::lua_munch_%s }' % (item.name, orig_class.name, item.name)) 

    #the base methods are shims that only retrieve it's self and pass it down to the
    #base class
    for base in orig_class.bases:
        for item in base.public:
            if type(item) != cpp.cpp_method:
                continue

            method = cpp.cpp_method('lua_munch_' + item.name,
                static=True, returns=cpp.cpp_type('int'),
                params=[cpp.cpp_variable('L', cpp.cpp_type('lua_State', pointer=True))])

            if item.parent:
                item.parameters.append(cpp.cpp_variable('lua_self', cpp.cpp_type(item.parent.name, pointer=True)))
                method.exprs.append('%s* lua_self = lua_munch_%s::get(L)' % (orig_class.qualname, orig_class.identifier_name))

            method.exprs.append(cpp.cpp_return(cpp.cpp_method_call('lua_munch_%s::lua_munch_%s' % (item.parent.name, item.name), params=['L', 'lua_self'])))

            lua_cls.public.append(method)

            if not item.is_constructor:
                luaReg.expr.append('{ "%s" , lua_munch_%s::lua_munch_%s }' % (item.name, orig_class.name, item.name))             

    luaReg.expr.append('{ 0, 0 }')

    lua_cls.public.append(luaReg)
    orig_class.translation = lua_cls
Exemple #8
0
def test_class():
    cls = cpp.cpp_class('MyTest')
    cls.qualname = "MyTest"

    method = cpp.cpp_method('method', 
              params=[cpp.cpp_variable('myvar', cpp.cpp_type('MyTestClass', const=True))])

    cls.public.append(method)

    context = lua.lua_context_builder.bake([cls])

    assert len(context.translated) == 1

    t_cls = context.translated[0]
    
    assert t_cls
    assert t_cls.name == 'lua_munch_MyTest'
Exemple #9
0
def test_method_param_class():
    method = cpp.cpp_method('method', 
                params=[cpp.cpp_variable('myvar', cpp.cpp_type('MyTestClass', const=True))])

    var = lua.lua_context_builder.apply_variable_initialization(method.parameters[0], None)

    assert type(var.ctype) == cpp.cpp_qual_type
    assert var.ctype.pointer == True

    context = lua.lua_context_builder.bake([method])

    assert len(context.translated) == 1

    t_method = context.translated[0]
    
    assert t_method.static
    assert t_method.name == 'lua_munch_method'
    assert t_method.initialization
    assert t_method.initialization[0]
Exemple #10
0
def process_functions(cls):
    overloads = {}
    
    for item in cls.public:
        if type(item) == cpp.cpp_method:
            if item.name in overloads:
                overloads[item.name].append(item)
            else:
                overloads[item.name] = [item]

    final_functions = []

    overload_count = 0

    for func in overloads:
        #if there is only one function with this name, it's not an overload it safely
        if len(overloads[func]) == 1:
            overloads[func][0].is_overload = False
            final_functions.append(overloads[func][0])
        else:
            newfun = cpp.cpp_method(func)
            newfun.is_overload = True
            newfun.overloads = {
                'by_arg_count' : [],
                'by_lua_type' : [],
                'by_cpp_type' : []
            }

            newfun.is_virtual = overloads[func][0].is_virtual
            newfun.is_constructor =  overloads[func][0].is_constructor

            newfun.parent = cls

            for i, function in enumerate(overloads[func]):
                function.name = '%s_overload_%d' % (function.name, overload_count)
                function.is_overload = False
                overload_count += 1

                #resolving functions that can be deduced by the count of it's arguments    
                same_qnt = False
                
                for other_f in  overloads[func]:

                    if other_f == function: continue

                    if len(function.parameters) == len(other_f.parameters):
                        same_qnt = True
                        break

                if not same_qnt:
                    newfun.overloads['by_arg_count'].append(function)
                    continue

                #resolving functions that can be deduced by the type of it's lua arguments
                for other_f in overloads[func]:
                    if other_f == function: continue

                    same_basic_types = False

                    for a,b in zip(function.parameters, other_f.parameters):
                        if a.ctype == b.ctype and not is_basic(a):
                            same_basic_types = True
                            break

                    if same_basic_types:
                        break

                if not same_basic_types:
                    newfun.overloads['by_lua_type'].append(function)
                    continue

                newfun.overloads['by_cpp_type'].append(function)

            print repr(newfun), newfun.is_overload
            final_functions.append(newfun)

    #filter every
    final_public = filter(lambda item: type(item) != cpp.cpp_method, cls.public)
    cls.public = final_public + final_functions

    print cls.public