Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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)
Beispiel #4
0
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]