def kooc_resolution(self: cnorm.nodes.Decl, ast: cnorm.nodes.BlockStmt, _mangler: mangler.Mangler, parents): res = node.Node.kooc_resolution(self, ast, _mangler, parents) if res is not None: if hasattr(res, '_ctype'): if res._ctype._storage == 0: _mangler.type(res._ctype._identifier).variable() if hasattr(res._ctype, '_params'): _mangler.callable().params(res._ctype._params) elif res._ctype._storage == 2 or res._ctype._storage == 1: _mangler.type_definition() if '@' in res._ctype._identifier: res._ctype._identifier = identifier_mangling(res._ctype._identifier) self._name = _mangler.name(self._name).mangle() return res
def make_vtable(klass: nodes.Class, name: str, _mangler: mangler.Mangler, _this: cnorm.nodes.Decl, parents: list, ast): vtable_mangler = copy.deepcopy(_mangler) vtable_mangler.container(klass.class_name) res = cnorm.nodes.Decl('', cnorm.nodes.ComposedType('__6vtable' + name)) res._ctype.fields = [] res._ctype._specifier = 1 res._ctype._attr_composed = ['__attribute__((packed)) '] for declaration in klass._ctype.fields: if type(declaration) is not nodes.Attribute and declaration.accessibility.virtual is True: _declaration_pointer = cnorm.nodes.Decl( vtable_mangler.name(declaration._name).type(declaration._ctype._identifier).params( declaration._ctype._params).callable().mangle(), cnorm.nodes.PrimaryType(declaration._ctype._identifier)) _declaration_pointer._ctype._decltype = cnorm.nodes.PointerType() _declaration_pointer._ctype._decltype._decltype = cnorm.nodes.ParenType( [_this] + declaration._ctype._params) res._ctype.fields.append(_declaration_pointer) if len(parents): self = parents[0] super_supers = [] for parent_name in self.parents: _parent = ast.search_in_tree(lambda super, _parents: super if type(super) is nodes.Class and super.class_name == parent_name.value and _parents == parent_name.scope else None) if _parent is None: print("error: super class of " + self.class_name + " named " + '@'.join( parent_name.scope + [parent_name.value]) + " doesn't exist", file=sys.stderr) exit(-1) super_supers.append(_parent) _super_this = cnorm.nodes.Decl('', cnorm.nodes.PrimaryType( _mangler.name(klass.class_name).type_definition().mangle())) res._ctype.fields = \ make_vtable(parents[0], _mangler.class_definition().name(klass.class_name).mangle(), _mangler, _super_this, super_supers, ast)[0]._ctype.fields + res._ctype.fields _typedef = cnorm.nodes.Decl('__6vtable' + _mangler.type_definition().name(klass.class_name).mangle(), cnorm.nodes.ComposedType(res._ctype._identifier)) _typedef._ctype._decltype = cnorm.nodes.PointerType() _typedef._ctype._specifier = 1 _typedef._ctype._storage = 2 return [res, _typedef]
def kooc_resolution(self: nodes.Class, ast: cnorm.nodes.BlockStmt, _mangler: mangler.Mangler, parents): new_mangler = copy.copy(_mangler) new_mangler.enable() new_mangler.container(self._ctype._identifier) global nm nm.push(nodes.Destructor, lambda destructor: False) nm.push(nodes.Constructor, lambda destructor: False) nm.push(nodes.Method, lambda destructor: False) supers = [] for parent_name in self.parents: _parent = ast.search_in_tree(lambda super, _parents: super if type(super) is nodes.Class and super.class_name == parent_name.value and _parents == parent_name.scope else None) if _parent is None: print("error: super class of " + self.class_name + " named " + '@'.join( parent_name.scope + [parent_name.value]) + " doesn't exist", file=sys.stderr) exit(-1) supers.append(_parent) self._ctype._identifier = _mangler.name(self._ctype._identifier).class_definition().mangle() _this = cnorm.nodes.Decl('', cnorm.nodes.PrimaryType(_mangler.type_definition().mangle())) vtable = make_vtable(self, self._ctype._identifier, _mangler, _this, supers, ast) _typedef = cnorm.nodes.Decl(_mangler.type_definition().mangle(), cnorm.nodes.ComposedType(self._ctype._identifier)) _typedef._ctype._decltype = cnorm.nodes.PointerType() _typedef._ctype._specifier = 1 _typedef._ctype._storage = 2 method_mangler = copy.copy(new_mangler) methods_declaration = [] for method in self._ctype.fields: if type(method) is nodes.Method: for decl in method._ctype._params: decl._ctype.kooc_resolution(ast, _mangler, parents) method._ctype._params = [_this] + method._ctype._params if method.accessibility.virtual is True: virtual = copy.deepcopy(method) method_mangler._symtype = "__7virtual" virtual._name = method_mangler.name(method._name).params(virtual._ctype._params).mangle() methods_declaration.append(virtual) method._name = method_mangler.name(method._name).callable().params(method._ctype._params).mangle() methods_declaration.append(method) elif type(method) is nodes.Constructor: newer = copy.deepcopy(method) method._ctype._params = [_this, cnorm.nodes.Decl('', cnorm.nodes.PrimaryType( vtable[1]._name))] + method._ctype._params method._name = method_mangler.name(method._name).callable().params(method._ctype._params).mangle() newer._name = method_mangler.name("new").params(newer._ctype._params).mangle() newer._ctype._identifier = _typedef._name; methods_declaration.append(method) methods_declaration.append(newer) elif type(method) is nodes.Destructor: method._ctype._params = [_this] + method._ctype._params newer = copy.deepcopy(method) if method.accessibility.virtual is True: virtual = copy.deepcopy(method) method_mangler._symtype = "__7virtual" virtual._name = method_mangler.name(method._name).mangle() methods_declaration.append(virtual) method._name = method_mangler.name(method._name).callable().params(method._ctype._params).mangle() newer._name = method_mangler.name("delete").mangle() methods_declaration.append(method) methods_declaration.append(newer) self._ctype.fields = sub_resolution(self._ctype.fields, ast, new_mangler, parents) for _super in reversed(supers): res = copy.deepcopy(_super).kooc_resolution(ast, _mangler, parents) self._ctype.fields = res[-1]._ctype.fields + self._ctype.fields self._ctype.fields.insert(0, cnorm.nodes.Decl( '__6vtable__' + str(len(self.class_name)) + self.class_name + '__' + str( len(_super.class_name)) + _super.class_name, cnorm.nodes.PrimaryType(res[1]._name))) self._ctype.fields[0]._ctype._decltype = cnorm.nodes.PointerType() if len(supers): self._ctype.fields = self._ctype.fields[1:] nm.pop(nodes.Destructor) nm.pop(nodes.Constructor) nm.pop(nodes.Method) return [_typedef, vtable[1]] + methods_declaration + [vtable[0]] + [self]