def kooc_resolution(self: nodes.Defn, ast: cnorm.nodes.BlockStmt, _mangler: mangler.Mangler, parents): new_mangler = copy.copy(_mangler) new_mangler.enable() new_mangler.container(self.name) namespace = ast.search_in_tree(lambda namespace, _parents: namespace if isinstance(namespace, nodes.Namespace) and namespace.name == self.name and parents == _parents else None) self.body = [declaration for declaration in namespace.body if hasattr(declaration, '_assign_expr')] + self.body parents.append(self.name) array = sub_resolution(self.body, ast, new_mangler, parents) parents.pop() return array
def kooc_resolution(self: nodes.New, ast: cnorm.nodes.BlockStmt, _mangler: mangler.Mangler, parents: list): new_mangler = copy.copy(_mangler) for name in self._type.split('@')[:-1]: new_mangler.container(name) new_mangler.enable() attribute = ast.search_in_tree(lambda attribute, _parents: attribute if type(attribute) is nodes.Attribute and attribute._name == self._type.split('@')[-1] and _parents == self._type.split('@')[ :-1] else None) if attribute is None: print("error: no attribute: ", self._type.split('@')[-1], " declared in class:", '@'.join(self._type.split('@')[:-1]), file=sys.stderr) exit(-1) if attribute.accessibility.set == 'private' and parents != self._type.split('@')[:-1]: print("error: access to attribute: ", self._type.split('@')[-1], " declared in class:", '@'.join(self._type.split('@')[:-1]), " which is private", file=sys.stderr) self.expr.params[0].params[0].value = new_mangler.name(self._type.split('@')[-1]).variable().mangle() return self
def kooc_resolution(self: nodes.Impl, ast: cnorm.nodes.BlockStmt, _mangler: mangler.Mangler, parents: list): impl_mangler = copy.copy(_mangler) impl_mangler.enable() klass = ast.search_in_tree(lambda klass, _parents: klass if type(klass) is nodes.Class and klass.class_name == self.name and parents == _parents else None) if klass is None: print("error: klass implementation: ", self.name, " doesn't match any declaration", file=sys.stderr) exit(0) gen_klass = copy.deepcopy(klass).kooc_resolution(ast, _mangler, parents)[-1] _this = cnorm.nodes.Decl('this', cnorm.nodes.PrimaryType( impl_mangler.name(klass._ctype._identifier).type_definition().mangle())) _vtable = cnorm.nodes.Decl('vtable', cnorm.nodes.PrimaryType( '__6vtable' + impl_mangler.name(klass._ctype._identifier).type_definition().mangle())) methods_pair = {} for pos, methodImpl in enumerate(self.body): methodDef = None if type(methodImpl) is nodes.MethodImplementation: methodDef = next((method for method in klass._ctype.fields if (type(method) is nodes.Method) and method._name == methodImpl._name and method._ctype._identifier == methodImpl._ctype._identifier and len(method._ctype.params) == len(methodImpl._ctype.params) and verify_parameters(method._ctype.params, methodImpl._ctype.params)), None) elif type(methodImpl) is nodes.ConstructorImplementation: methodDef = next((method for method in klass._ctype.fields if (type(method) is nodes.Constructor) and method._name == methodImpl._name and method._ctype._identifier == methodImpl._ctype._identifier and len(method._ctype.params) == len(methodImpl._ctype.params) and verify_parameters(method._ctype.params, methodImpl._ctype.params)), None) elif type(methodImpl) is nodes.DestructorImplementation: methodDef = next((method for method in klass._ctype.fields if (type(method) is nodes.Destructor))) if methodDef is None: del methodImpl.body print("error: No matching definition for method: ", str(methodImpl.to_c()).strip('\n'), "in class: ", self.name, file=sys.stderr) exit(0) methods_pair[methodImpl._name] = methodDef _override_table = {} generate_override_table(self, klass, ast, methods_pair, _override_table) generated_function = [] impl_mangler.container(self.name) for pos, methodImpl in enumerate(self.body): methodImpl._ctype._params.insert(0, _this) if type(methods_pair[methodImpl._name]) is nodes.Constructor: methodImpl._ctype._params.insert(1, _vtable) generated_function.append( construct_new_operator(methods_pair[methodImpl._name], methodImpl, _this, impl_mangler, gen_klass)) fill_constructor(methodImpl, klass, copy.copy(impl_mangler), _this, _override_table) if type(methods_pair[methodImpl._name]) is nodes.Destructor: generated_function.append( construct_delete_operator(methods_pair[methodImpl._name], methodImpl, _this, impl_mangler)) if type(methods_pair[methodImpl._name]) is nodes.Method and (methods_pair[ methodImpl._name].accessibility.virtual is True): methodImpl.virtual = True if type(methods_pair[methodImpl._name]) is nodes.Destructor and (methods_pair[ methodImpl._name].accessibility.virtual is True): methodImpl.virtual = True methods_pair[methodImpl._name].defined = True for method in klass._ctype.fields: if not hasattr(method, 'defined') or method.defined is not True: if type(method) is nodes.Constructor: print("error: cons", str(method.to_c()).split("void cons")[1].strip('\n'), " declared but not defined in class: ", self.name, sep='', file=sys.stderr) exit(0) elif type(method) is nodes.Destructor: print("error: dest", str(method.to_c()).split("void dest")[1].strip('\n'), " declared but not defined in class: ", self.name, sep='', file=sys.stderr) exit(0) elif type(method) is nodes.Method: print("warning: undefined method: ", str(method.to_c()).strip('\n'), " in class: ", self.name, file=sys.stderr) return sub_resolution(self.body + generated_function, ast, impl_mangler, parents)
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]