Ejemplo n.º 1
0
def export_function_setup(f):
    block = SourceBlock()
    block.add_line("def _init_function():")
    block.add_block(export_callable_setup(f), 1)
    block.add_line("%s._meta = {'signatures': signatures}" % f.name, 1)
    block.add_line("_init_function()")
    return block
Ejemplo n.º 2
0
def export_class_setup(cls):
    blocks = []

    for method in cls.methods.values():
        block = export_callable_setup(method)
        block.add_line("%s._meta['%s'] = {'signatures': signatures}" % (cls.name, method.name))
        blocks.append(block)

    for member in cls.members.values():
        getter, setter = False, False
        if member.getter:
            blocks.append(export_callable_setup(member.getter, "getter_signatures"))
            getter = True
        if member.setter:
            blocks.append(export_callable_setup(member.setter, "setter_signatures"))
            setter = True

        getter = "{'signatures': getter_signatures}" if getter else "None"
        setter = "{'signatures': setter_signatures}" if setter else "None"
        format = "%s._meta['%s'] = {'getter': %s, 'setter': %s}"
        blocks.append(SourceBlock(format % (cls.name, member.name, getter, setter)))

    if cls.vtable:
        blocks.append(export_vtable_setup(cls))

    block = SourceBlock()
    block.add_line("def _init_cls():")
    block.add_line("%s._meta = {}" % cls.name, 1)
    block.add_line("", 1)
    block.add_block(SourceBlock("").join(blocks, 1))
    block.add_line("_init_cls()")
    return block
Ejemplo n.º 3
0
def export_type_checks_for_call(call, call_var="sig"):
    block = SourceBlock()
    for arg, num in zip(call.args, count()):
        type_var = "%s['arguments'][%d]" % (call_var, num)
        type_check = export_type_check(arg.name, arg.type, type_var)
        block.add_block(type_check)

    return block
Ejemplo n.º 4
0
def export_callable_setup(f, result_name="signatures"):
    module = f.get_closest_parent_module()

    block = SourceBlock("%s = []" % result_name)
    for call in f.calls:
        block.add_block(export_library_import(module, call.get_library(), "lib"))
        block.add_block(export_call_setup(call, "signature", "lib"))
        block.add_line("%s.append(signature)" % result_name)
    return block
Ejemplo n.º 5
0
def export_function(f):
    result_name = "result" if f.returns_anything() else None

    block = SourceBlock()
    block.add_block(export_function_signature(f))
    block.add_block(export_calls(f, result_name), 1)
    if result_name:
        block.add_line("return " + result_name, 1)
    return block
Ejemplo n.º 6
0
    def export(self, importer, path):
        self.setup(importer)

        block = SourceBlock('extern "C" {')
        block.add_block(self.export_namespace(importer.root_namespace))
        block.add_line("}")

        with open(path, 'w') as f:
            f.write(block.as_text())
Ejemplo n.º 7
0
    def export(self, importer, path):
        self.setup(importer)

        block = SourceBlock()
        includes = self.get_includes()
        if includes:
            block.add_line('%s\n\n' % includes)
        block.add_block(self.export_namespace(importer.root_namespace))

        with open(path, 'w') as f:
            f.write(block.as_text())
Ejemplo n.º 8
0
    def export_class(self, cls):
        full_name = cls.get_full_name()
        full_name_underscore = cls.get_full_name("__")

        block = SourceBlock()
        block.add_line("")
        block.add_line("//")
        block.add_line("// Begin class '%s'" % cls.get_full_name())
        block.add_line("//")

        # Constructor
        if not cls.is_abstract():
            constructors = self.export_constructors(cls, full_name,
                                                    full_name_underscore)
            block.add_block(constructors)

        # Destructor
        if not cls.destructor or cls.destructor.access == AccessSpecifier.Public:
            destructors = self.export_destructors(cls, full_name, full_name_underscore)
            block.add_block(destructors)

        # Class size
        block.add_line("unsigned int %s(){" % self.symbol_for_class_size(
            cls, full_name_underscore))
        block.add_line("return sizeof(%s);" % full_name, 1)
        block.add_line("}")

        # Get array element
        block.add_line("void* %s(void* arr, unsigned int idx){" % self.symbol_for_array_element(
            cls, full_name_underscore
        ))
        block.add_line("return &((%s*)arr)[idx];" % full_name, 1)
        block.add_line("}")

        # Methods
        block.add_block(self.export_methods(cls, full_name,
                                            full_name_underscore))

        # Members
        block.add_block(self.export_members(cls, full_name,
                                            full_name_underscore))

        # C++ class to inherit from a virtual base
        if cls.is_dynamic():
            inheritance_class = self.export_inherited_class(
                cls,
                full_name,
                full_name_underscore
            )
            block.add_block(inheritance_class)

        return block
Ejemplo n.º 9
0
    def export_namespace(self, ns):
        block = SourceBlock()
        if not self.filter.filter_namespace(ns):
            return block

        for node in ns.nodes:
            if isinstance(node, Class):
                if self.filter.filter_class(node):
                    block.add_block(self.export_class(node))
        for child in ns.children.values():
            block.add_block(self.export_namespace(child))

        return block
Ejemplo n.º 10
0
def export_class(cls):
    members = []
    if cls.vtable:
        members.append(SourceBlock("_polymorphism_info_ = wrappyr.runtime.PolymorphismInfo()"))

    for block in (export_constructor(cls), export_destructor(cls)):
        if block:
            members.append(block)

    for method in sorted(cls.methods.values(), key=cmp_to_key(sort_methods(lambda method: method.name))):
        members.append(export_method(cls, method))
    for member in sorted(cls.members.values(), key=lambda member: member.name):
        members.append(export_member(cls, member))

    from_c = SourceBlock()
    from_c.add_line("@staticmethod")
    from_c.add_line("def _from_c(inst, ownership = False):")
    from_c.add_line("cls = %s.__new__(%s)" % (cls.name, cls.name), 1)
    from_c.add_line("cls._inst = inst", 1)
    from_c.add_line("cls._ownership = ownership", 1)
    from_c.add_line("cls._valid = True", 1)
    from_c.add_line("return cls", 1)
    members.append(from_c)

    parent_module = cls.get_closest_parent_module()

    base_imports = []
    bases = []
    for base, num in zip(cls.bases, count()):
        base_var = "_Base%d" % num
        base_import = get_node_import(parent_module, base.type, base_var)
        base_imports.append(base_import)
        bases.append(base_var)
    bases = ", ".join(bases) if bases else "wrappyr.runtime.CPPClass"

    block = SourceBlock()
    for base_import in base_imports:
        block.add_line(base_import)
    block.add_line("class %s(%s):" % (cls.name, bases))
    block.add_block(SourceBlock("").join(members, 1))
    return block
Ejemplo n.º 11
0
    def export_inherited_class(self, cls, full_name, full_name_underscore):
        block = SourceBlock()

        overridable = cls.get_overridable_signatures()
        if not overridable:
            return block

        filtered_out = [i for method in overridable
                          for i in method
                          if not self.filter.filter_method_signature(cls, i, True)]
        if any(sig.pure for sig in filtered_out):
            msg = ("A pure virtual signature for class %s "
                   "was not overridden because it was filtered out.")
            raise self.PureMethodNotOverridden(msg % full_name)

        overridable = [[i for i in method if i not in filtered_out]
                        for method in overridable]
        overridable = [method for method in overridable if method]

        vtable = self.export_class_vtable(full_name_underscore, overridable)
        block.add_block(vtable)

        block.add_line("class %s__Inherited : public %s {" % (full_name_underscore, full_name))
        block.add_line("public:", 1)
        block.add_block(self.export_inherited_constructors(cls, full_name, full_name_underscore), 2)
        block.add_block(self.export_inherited_methods(cls, full_name, full_name_underscore, overridable), 2)
        block.add_line("private:", 1)
        #               block.add_line("%s* m_obj;" % full_name, 2)
        block.add_line("void* m_script_obj;", 2)
        block.add_line("void* m_vtable;", 2)
        block.add_line("};")

        if cls.constructors:
            for constructor in cls.constructors:
                if not self.filter.filter_method_signature(cls, constructor, inherited = True):
                    continue

                args = constructor.args_as_string(self.letters)
                if args:
                    args = ", " + args

                params = self.args_as_params(constructor)
                if params:
                    params = "script_obj, vtable, " + params
                else:
                    params = "script_obj, vtable"

                symbol = self.symbol_for_inheritance_constructor(cls, full_name_underscore,
                                                                 constructor)
                block.add_line("void* %s(void* script_obj, void* vtable%s){" % (symbol, args))
                block.add_line("return new %s__Inherited(%s);" % (full_name_underscore, params), 1)
                block.add_line("}")
        else:
            block.add_line("void* %s(void* script_obj, void* vtable){" % (
            self.symbol_for_inheritance_constructor(cls, full_name_underscore, None),
            ))
            block.add_line("return new %s__Inherited(script_obj, vtable);" % full_name_underscore, 1)
            block.add_line("}")

        return block
Ejemplo n.º 12
0
def export_member(cls, member):
    block = SourceBlock()

    if member.getter:
        getter = member.getter
        getter_name = "__get_%s" % member.name
        call = getter.calls[0]

        block.add_line("def %s(self):" % getter_name)
        block.add_block(export_call(call, "result"), 1)
        block.add_line("return result", 1)

    if member.setter:
        setter = member.setter
        setter_name = "__set_%s" % member.name
        call = setter.calls[0]

        block.add_line("def %s(self, v):" % setter_name)
        type = call.args[0].type
        block.add_line("sig = " + get_call(call), 1)
        if isinstance(type, (Class, PointerType)):
            check = export_type_check("v", type, "sig['arguments'][0]")
            block.add_block(check, 1)

        call = export_call(call, arg_names=("v",), export_type_checks=False, call_var="call")
        block.add_block(call, 1)

    prop = "property(%s, %s)" % (getter_name if member.getter else "None", setter_name if member.setter else "None")
    block.add_line("%s = %s" % (member.name, prop))
    if member.getter:
        block.add_line("del " + getter_name)
    if member.setter:
        block.add_line("del " + setter_name)

    return block
Ejemplo n.º 13
0
def export_constructor(cls):
    vtable = cls.vtable
    alloc = cls.methods.get("__alloc__")
    #    allocderived = cls.methods.get('__alloc_derived__')

    if not alloc and not vtable:
        return SourceBlock()

    signature = SourceBlock("def __init__(self, *args, **kwargs):")

    # What to do if the class is instantiated directly
    if alloc:
        constructor_block = SourceBlock("inst = self.__alloc__(*args, **kwargs)")
    else:
        error = "raise TypeError('This class cannot be instantiated directly')"
        constructor_block = SourceBlock(error)

    # What to do if a derived class is instantiated.
    if vtable:
        derived_block = SourceBlock("inst = self.__alloc_derived__(self, self._vtable_, *args, **kwargs)")
    else:
        error = "raise TypeError('You cannot inherit from this class')"
        derived_block = SourceBlock(error)

    block = SourceBlock()
    block.add_block(signature)
    block.add_line("if type(self) == %s:" % cls.name, 1)
    block.add_block(constructor_block, 2)
    block.add_line("else:", 1)
    block.add_block(derived_block, 2)
    block.add_line("self._inst = inst", 1)
    block.add_line("self._ownership = True", 1)
    block.add_line("self._valid = True", 1)

    return block
Ejemplo n.º 14
0
def export_call(call, result_name="", arg_names=(), export_type_checks=True, call_var=None):
    if result_name:
        action = "{result_name} = sig['call']({args})"
    else:
        action = "sig['call']({args})"

    block = SourceBlock()
    if not call_var:
        call_var = "sig"
        block.add_line("%s = %s" % (call_var, get_call(call)))
    if export_type_checks:
        block.add_block(export_type_checks_for_call(call))

    block.add_block(export_memory_management_before_call(call))
    block.add_line(action.format(result_name=result_name, args=get_converted_argument_list(call, arg_names)))
    block.add_block(export_memory_management_after_call(call))

    if not result_name or not call.returns:
        return block

    if isinstance(call.returns.type, Class):
        conversion = "{0} = {1}['returns']._from_c({0}, {2})"
        conversion = conversion.format(result_name, call_var, repr(call.returns.ownership))
    elif isinstance(call.returns, PointerType):
        conversion = ""
    else:
        conversion = ""

    if conversion:
        block.add_line(conversion)

    return block
Ejemplo n.º 15
0
def export_method(cls, method, result_name=""):
    """
    Exports method and stores result in result_name variable in generated code
    if result_name is given. If it is not given, the result will be returned.
    """

    block = SourceBlock()

    call_args = get_call_args(method)

    if not result_name:
        result_name = method.name == "__init__" or method.returns_anything()
        result_name = "result" if result_name else ""
        return_result = True
    else:
        return_result = False
    block.add_block(export_function_signature(method, call_args))
    block.add_block(export_calls(method, result_name, call_args), 1)

    if return_result and method.returns_anything():
        block.add_line("return " + result_name, 1)

    return block
Ejemplo n.º 16
0
def export_calls(f, result_name="", call_args=None, export_call=export_call):
    block = SourceBlock()

    call_args = call_args or get_call_args(f)

    if len(call_args) > 1:
        call, args = call_args[-1]
        block.add_line("if %s:" % " and ".join("%s != wrappyr.runtime.NoArgument" % arg.name for arg in args))
        block.add_block(export_call(call, result_name), 1)
    for call, args in reversed(call_args[1:-1]):
        block.add_line("elif %s:" % " and ".join("%s != wrappyr.runtime.NoArgument" % arg.name for arg in args))
        block.add_block(export_call(call, result_name), 1)
    if len(call_args) > 1:
        block.add_line("else:")
    block.add_block(export_call(call_args[0][0], result_name), int(len(call_args) > 1))

    return block