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
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
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
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
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
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())
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())
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
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
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
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
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
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
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
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
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