Example #1
0
    def struct_decl(self, tree: Tree):
        nodes = tree.children
        node = nodes[0]
        full_name = node.metadata['struct_name']
        function_decls = node.metadata['functions']

        struct = ParserState.search_structs(full_name)

        if struct is None:
            raise KeyError(
                f"Expected a struct {full_name} but couldn't find it!")

        self.llvmgen.current_struct = struct

        # Create functions
        for function_decl in function_decls:
            self.visit(function_decl)

        self.llvmgen.finish_struct()
Example #2
0
    def struct_decl(self, tree: Tree):
        nodes: List = tree.children
        access_modifier = nodes[0].access_modifier
        name = nodes[1].value

        full_name = f"{ParserState.module().name}:{name}"

        if ParserState.search_structs(full_name) is not None:
            log_fail(f"Struct {full_name} has been previously declared!")
            raise Discard()

        body: List[RIALVariable] = list()
        function_decls: List[Tree] = list()
        bases: List[str] = list()

        # Find body of struct (variables)
        i = 2
        while i < len(nodes):
            node: Tree = nodes[i]

            if isinstance(node,
                          Tree) and node.data == "struct_property_declaration":
                variable = node.children
                acc_modifier = variable[0].access_modifier
                rial_type = variable[1].value
                variable_name = variable[2].value
                variable_value = None

                if len(variable) > 3:
                    variable_value = variable[3]

                body.append(
                    RIALVariable(variable_name,
                                 rial_type,
                                 backing_value=variable_value,
                                 access_modifier=acc_modifier))
            elif isinstance(node, Tree) and node.data == "function_decl":
                function_decls.append(node)
            elif isinstance(node, Token) and node.type == "IDENTIFIER":
                bases.append(node.value)
            i += 1

        base_llvm_structs = list()

        for base in bases:
            llvm_struct = ParserState.find_struct(base)

            if llvm_struct is not None:
                base_llvm_structs.append(llvm_struct)
            else:
                log_fail(f"Derived from undeclared type {base}")

        base_constructor = Tree('function_decl', [
            RIALFunctionDeclarationModifier(access_modifier),
            Token('IDENTIFIER', "void"),
            Token('IDENTIFIER', "constructor"), *[
                Tree('function_call', [
                    Token(
                        'IDENTIFIER',
                        mangle_function_name("constructor", [base],
                                             base.name)),
                    Tree('function_args', [
                        Tree('cast', [
                            Token('IDENTIFIER', base.name),
                            Tree('var', [Token('IDENTIFIER', "this")])
                        ])
                    ])
                ]) for base in base_llvm_structs
            ], *[
                Tree('variable_assignment', [
                    Tree('var', [Token('IDENTIFIER', f"this.{bod.name}")]),
                    Token('ASSIGN', '='), bod.backing_value
                ]) for bod in body
            ],
            Tree('return', [Token('IDENTIFIER', "void")])
        ])
        function_decls.insert(0, base_constructor)

        llvm_struct = self.llvmgen.create_identified_struct(
            full_name, access_modifier.get_linkage(), access_modifier,
            base_llvm_structs, body)

        declared_functions = list()

        # Create functions
        for function_decl in function_decls:
            metadata_node = self.fdt.visit(function_decl)
            if metadata_node is not None:
                declared_functions.append(metadata_node)
            try:
                nodes.remove(function_decl)
            except ValueError:
                pass

        self.llvmgen.finish_struct()

        node: Token = nodes[1]
        md_node = MetadataToken(node.type, node.value)

        md_node.metadata['struct_name'] = full_name
        md_node.metadata['functions'] = declared_functions
        nodes.remove(node)
        nodes.insert(0, md_node)

        return Tree('struct_decl', nodes)