Esempio n. 1
0
 def compute_anti_dependences(self):
     """Return a dictionnary of anti dependencies for design unit"""
     res = {}
     lib = libraries.Get_Libraries_Chain()
     while lib != nodes.Null_Iir:
         files = nodes.Get_Design_File_Chain(lib)
         while files != nodes.Null_Iir:
             units = nodes.Get_First_Design_Unit(files)
             while units != nodes.Null_Iir:
                 if nodes.Get_Date_State(units) == nodes.Date_State.Analyze:
                     # The unit has been analyzed, so the dependencies are know.
                     deps = nodes.Get_Dependence_List(units)
                     assert deps != nodes.Null_Iir_List
                     deps_it = lists.Iterate(deps)
                     while lists.Is_Valid(byref(deps_it)):
                         el = lists.Get_Element(byref(deps_it))
                         if nodes.Get_Kind(
                                 el) == nodes.Iir_Kind.Design_Unit:
                             if res.get(el, None):
                                 res[el].append(units)
                             else:
                                 res[el] = [units]
                         else:
                             assert False
                         lists.Next(byref(deps_it))
                 units = nodes.Get_Chain(units)
             files = nodes.Get_Chain(files)
         lib = nodes.Get_Chain(lib)
     return res
Esempio n. 2
0
def GetParameterFromChainedNodes(
    nodeChain: Iir, ) -> Generator[ParameterInterfaceItem, None, None]:

    parameter = nodeChain
    while parameter != nodes.Null_Iir:
        kind = GetIirKindOfNode(parameter)
        if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
            from pyGHDL.dom.InterfaceItem import ParameterConstantInterfaceItem

            param = ParameterConstantInterfaceItem.parse(parameter)
        elif kind == nodes.Iir_Kind.Interface_Variable_Declaration:
            from pyGHDL.dom.InterfaceItem import ParameterVariableInterfaceItem

            param = ParameterVariableInterfaceItem.parse(parameter)
        elif kind == nodes.Iir_Kind.Interface_Signal_Declaration:
            from pyGHDL.dom.InterfaceItem import ParameterSignalInterfaceItem

            param = ParameterSignalInterfaceItem.parse(parameter)
        elif kind == nodes.Iir_Kind.Interface_File_Declaration:
            from pyGHDL.dom.InterfaceItem import ParameterFileInterfaceItem

            param = ParameterFileInterfaceItem.parse(parameter)
        else:
            position = Position.parse(parameter)
            raise DOMException(
                "Unknown parameter kind '{kind}' in parameter '{param}' at {file}:{line}:{column}."
                .format(
                    kind=kind.name,
                    param=parameter,
                    file=position.Filename,
                    line=position.Line,
                    column=position.Column,
                ))

        # Lookahead for parameters with multiple identifiers at once
        if nodes.Get_Has_Identifier_List(parameter):
            nextNode = nodes.Get_Chain(parameter)
            for nextParameter in utils.chain_iter(nextNode):
                # Consecutive identifiers are found, if the subtype indication is Null
                if nodes.Get_Subtype_Indication(
                        nextParameter) == nodes.Null_Iir:
                    param.Identifiers.append(GetNameOfNode(nextParameter))
                else:
                    parameter = nextParameter
                    break

                # The last consecutive identifiers has no Identifier_List flag
                if not nodes.Get_Has_Identifier_List(nextParameter):
                    parameter = nodes.Get_Chain(nextParameter)
                    break
            else:
                parameter = nodes.Null_Iir
        else:
            parameter = nodes.Get_Chain(parameter)

        yield param
Esempio n. 3
0
    def parse(self):
        unit = nodes.Get_First_Design_Unit(self.__ghdlFile)
        while unit != nodes.Null_Iir:
            libraryUnit = nodes.Get_Library_Unit(unit)
            nodeKind = nodes.Get_Kind(libraryUnit)

            if (nodeKind == nodes.Iir_Kind.Entity_Declaration):
                entity = Entity.parse(libraryUnit)
                self.Entities.append(entity)

            elif (nodeKind == nodes.Iir_Kind.Architecture_Body):
                architecture = Architecture.parse(libraryUnit)
                self.Architectures.append(architecture)

            elif (nodeKind == nodes.Iir_Kind.Package_Declaration):
                package = Package.parse(libraryUnit)
                self.Packages.append(package)

            elif (nodeKind == nodes.Iir_Kind.Package_Body):
                packageBody = PackageBody.parse(libraryUnit)
                self.PackageBodies.append(packageBody)

            elif (nodeKind == nodes.Iir_Kind.Context_Declaration):
                context = Context.parse(libraryUnit)
                self.Contexts.append(context)

            elif (nodeKind == nodes.Iir_Kind.Configuration_Declaration):
                configuration = Configuration.parse(libraryUnit)
                self.Configurations.append(configuration)

            else:
                raise GHDLException("Unknown design unit kind.")

            unit = nodes.Get_Chain(unit)
Esempio n. 4
0
def find_def_chain(first, loc):
    n1 = first
    while n1 != nodes.Null_Iir:
        res = find_def(n1, loc)
        if res is not None:
            return res
        n1 = nodes.Get_Chain(n1)
    return None
Esempio n. 5
0
def GetPortsFromChainedNodes(
    nodeChain: Iir, ) -> Generator[PortInterfaceItem, None, None]:

    port = nodeChain
    while port != nodes.Null_Iir:
        kind = GetIirKindOfNode(port)
        if kind == nodes.Iir_Kind.Interface_Signal_Declaration:
            from pyGHDL.dom.InterfaceItem import PortSignalInterfaceItem

            portSignal = PortSignalInterfaceItem.parse(port)

            # Lookahead for ports with multiple identifiers at once
            if nodes.Get_Has_Identifier_List(port):
                nextNode = nodes.Get_Chain(port)
                for nextPort in utils.chain_iter(nextNode):
                    # Consecutive identifiers are found, if the subtype indication is Null
                    if nodes.Get_Subtype_Indication(
                            nextPort) == nodes.Null_Iir:
                        portSignal.Identifiers.append(GetNameOfNode(nextPort))
                    else:
                        port = nextPort
                        break

                    # The last consecutive identifiers has no Identifier_List flag
                    if not nodes.Get_Has_Identifier_List(nextPort):
                        port = nodes.Get_Chain(nextPort)
                        break
                else:
                    port = nodes.Null_Iir
            else:
                port = nodes.Get_Chain(port)

            yield portSignal
            continue
        else:
            position = Position.parse(port)
            raise DOMException(
                "Unknown port kind '{kind}' in port '{port}' at {file}:{line}:{column}."
                .format(
                    kind=kind.name,
                    port=port,
                    file=position.Filename,
                    line=position.Line,
                    column=position.Column,
                ))
Esempio n. 6
0
 def create_interfaces(inters):
     res = []
     while inters != nodes.Null_Iir:
         res.append({
             "name":
             name_table.Get_Name_Ptr(nodes.Get_Identifier(inters))
         })
         inters = nodes.Get_Chain(inters)
     return res
Esempio n. 7
0
def sequential_iter(n) -> Generator[Any, None, None]:
    """
    Iterate sequential statements. The first node must be either
    a process or a subprogram body.
    """
    if n == nodes.Null_Iir:
        return
    k = nodes.Get_Kind(n)
    if k in (
            nodes.Iir_Kind.Process_Statement,
            nodes.Iir_Kind.Sensitized_Process_Statement,
            nodes.Iir_Kind.Function_Body,
            nodes.Iir_Kind.Procedure_Body,
    ):
        for n1 in chain_iter(nodes.Get_Sequential_Statement_Chain(n)):
            yield n1
            for n2 in sequential_iter(n1):
                yield n2
    elif k == nodes.Iir_Kind.If_Statement:
        while True:
            n = nodes.Get_Chain(n)
            if n == nodes.Null_Iir:
                break
            yield n
            for n1 in sequential_iter(n):
                yield n1
    elif k == nodes.Iir_Kind.Case_Statement:
        for ch in chain_iter(nodes.Get_Case_Statement_Alternative_Chain(n)):
            stmt = nodes.Get_Associated_Chain(ch)
            if stmt != nodes.Null_Iir:
                for n1 in chain_iter(stmt):
                    yield n1
                    for n2 in sequential_iter(n1):
                        yield n2
    elif k in [
            nodes.Iir_Kind.For_Loop_Statement,
            nodes.Iir_Kind.While_Loop_Statement
    ]:
        for n1 in chain_iter(nodes.Get_Sequential_Statement_Chain(n)):
            yield n1
            for n2 in sequential_iter(n1):
                yield n2
    elif k in (
            nodes.Iir_Kind.Assertion_Statement,
            nodes.Iir_Kind.Wait_Statement,
            nodes.Iir_Kind.Null_Statement,
            nodes.Iir_Kind.Exit_Statement,
            nodes.Iir_Kind.Next_Statement,
            nodes.Iir_Kind.Return_Statement,
            nodes.Iir_Kind.Variable_Assignment_Statement,
            nodes.Iir_Kind.Simple_Signal_Assignment_Statement,
            nodes.Iir_Kind.Procedure_Call_Statement,
    ):
        return
    else:
        raise Exception("Unknown node of kind {}".format(kind_image(k)))
Esempio n. 8
0
 def x_get_all_entities(self):
     res = []
     lib = libraries.Get_Libraries_Chain()
     while lib != nodes.Null_Iir:
         files = nodes.Get_Design_File_Chain(lib)
         ents = []
         while files != nodes.Null_Iir:
             units = nodes.Get_First_Design_Unit(files)
             while units != nodes.Null_Iir:
                 unitlib = nodes.Get_Library_Unit(units)
                 if nodes.Get_Kind(
                         unitlib) == nodes.Iir_Kind.Entity_Declaration:
                     ents.append(unitlib)
                 units = nodes.Get_Chain(units)
             files = nodes.Get_Chain(files)
         ents = [pyutils.name_image(nodes.Get_Identifier(e)) for e in ents]
         lib_name = pyutils.name_image(nodes.Get_Identifier(lib))
         res.extend([{"name": n, "library": lib_name} for n in ents])
         lib = nodes.Get_Chain(lib)
     return res
Esempio n. 9
0
 def compute_diags(self):
     log.debug("parse doc %d %s", self._fe, self.uri)
     self.parse_document()
     if self._tree == nodes.Null_Iir:
         # No units, nothing to add.
         return
     # Semantic analysis.
     unit = nodes.Get_First_Design_Unit(self._tree)
     while unit != nodes.Null_Iir:
         sem.Semantic(unit)
         nodes.Set_Date_State(unit, nodes.Date_State.Analyze)
         unit = nodes.Get_Chain(unit)
Esempio n. 10
0
    def test_InitializeGHDL(self) -> None:
        """Initialization: set options and then load libaries."""
        libghdl.initialize()

        # Print error messages on the console.
        errorout_console.Install_Handler()

        # Set options. This must be done before analyze_init()
        libghdl.set_option("--std=08")

        # Finish initialization. This will load the standard package.
        if libghdl.analyze_init_status() != 0:
            self.fail("libghdl initialization error")

        # Load the file
        file_id = name_table.Get_Identifier(str(self._filename))
        sfe = files_map.Read_Source_File(name_table.Null_Identifier, file_id)
        if sfe == files_map.No_Source_File_Entry:
            self.fail("Cannot read file '{!s}'".format(self._filename))

        # Parse
        file = sem_lib.Load_File(sfe)

        # Display all design units
        designUnit = nodes.Get_First_Design_Unit(file)
        while designUnit != nodes.Null_Iir:
            libraryUnit = nodes.Get_Library_Unit(designUnit)

            if nodes.Get_Kind(
                    libraryUnit) == nodes.Iir_Kind.Entity_Declaration:
                entityName = self.getIdentifier(libraryUnit)
                self.assertEqual(
                    entityName,
                    "entity_1",
                    "expected entity name 'e1', got '{}'".format(entityName),
                )

            elif nodes.Get_Kind(
                    libraryUnit) == nodes.Iir_Kind.Architecture_Body:
                architectureName = self.getIdentifier(libraryUnit)
                self.assertEqual(
                    architectureName,
                    "behav",
                    "expected architecture name 'behav', got '{}'".format(
                        architectureName),
                )

            else:
                self.fail("Unknown unit.")

            designUnit = nodes.Get_Chain(designUnit)
Esempio n. 11
0
 def obsolete_doc(self, doc):
     if doc._tree == nodes.Null_Iir:
         return
     # Free old tree
     assert nodes.Get_Kind(doc._tree) == nodes.Iir_Kind.Design_File
     if self._last_linted_doc == doc:
         antideps = None
     else:
         antideps = self.compute_anti_dependences()
     unit = nodes.Get_First_Design_Unit(doc._tree)
     while unit != nodes.Null_Iir:
         if antideps is not None:
             self.obsolete_dependent_units(unit, antideps)
         # FIXME: free unit; it is not referenced.
         unit = nodes.Get_Chain(unit)
     libraries.Purge_Design_File(doc._tree)
     doc._tree = nodes.Null_Iir
Esempio n. 12
0
 def add_to_library(tree):
     # Detach the chain of units.
     unit = nodes.Get_First_Design_Unit(tree)
     nodes.Set_First_Design_Unit(tree, nodes.Null_Iir)
     # FIXME: free the design file ?
     tree = nodes.Null_Iir
     # Analyze unit after unit.
     while unit != nodes.Null_Iir:
         # Pop the first unit.
         next_unit = nodes.Get_Chain(unit)
         nodes.Set_Chain(unit, nodes.Null_Iir)
         lib_unit = nodes.Get_Library_Unit(unit)
         if lib_unit != nodes.Null_Iir and nodes.Get_Identifier(
                 unit) != name_table.Null_Identifier:
             # Put the unit (only if it has a library unit) in the library.
             libraries.Add_Design_Unit_Into_Library(unit, False)
             tree = nodes.Get_Design_File(unit)
         unit = next_unit
     return tree
Esempio n. 13
0
def nodes_iter(n) -> Generator[Any, None, None]:
    """
    Iterate all nodes of :obj:`n`, including :obj:`n`.
    Nodes are returned only once.
    """
    if n == nodes.Null_Iir:
        return
    #    print 'nodes_iter for {0}'.format(n)
    yield n
    for f in fields_iter(n):
        typ = nodes_meta.get_field_type(f)
        #        print ' {0}: field {1} (type: {2})'.format(
        #            n, fields_image(f), types_image(typ))
        if typ == nodes_meta.types.Iir:
            attr = nodes_meta.get_field_attribute(f)
            if attr == nodes_meta.Attr.ANone:
                for n1 in nodes_iter(nodes_meta.Get_Iir(n, f)):
                    yield n1
            elif attr == nodes_meta.Attr.Chain:
                n2 = nodes_meta.Get_Iir(n, f)
                while n2 != nodes.Null_Iir:
                    for n1 in nodes_iter(n2):
                        yield n1
                    n2 = nodes.Get_Chain(n2)
            elif attr == nodes_meta.Attr.Maybe_Ref:
                if not nodes.Get_Is_Ref(n, f):
                    for n1 in nodes_iter(nodes_meta.Get_Iir(n, f)):
                        yield n1
        elif typ == nodes_meta.types.Iir_List:
            attr = nodes_meta.get_field_attribute(f)
            if attr == nodes_meta.Attr.ANone:
                for n1 in list_iter(nodes_meta.Get_Iir_List(n, f)):
                    for n2 in nodes_iter(n1):
                        yield n2
        elif typ == nodes_meta.types.Iir_Flist:
            attr = nodes_meta.get_field_attribute(f)
            if attr == nodes_meta.Attr.ANone:
                for n1 in flist_iter(nodes_meta.Get_Iir_Flist(n, f)):
                    for n2 in nodes_iter(n1):
                        yield n2
Esempio n. 14
0
    def parse(cls, caseNode: Iir, label: str) -> "CaseStatement":
        from pyGHDL.dom._Utils import GetIirKindOfNode
        from pyGHDL.dom._Translate import (
            GetExpressionFromNode,
            GetRangeFromNode,
            GetNameFromNode,
        )

        expression = GetExpressionFromNode(nodes.Get_Expression(caseNode))

        cases = []
        choices = None
        alternative = nodes.Get_Case_Statement_Alternative_Chain(caseNode)
        cNode = alternative

        while alternative != nodes.Null_Iir:
            choiceKind = GetIirKindOfNode(alternative)
            sameAlternative = nodes.Get_Same_Alternative_Flag(alternative)

            if choiceKind in (
                nodes.Iir_Kind.Choice_By_Name,
                nodes.Iir_Kind.Choice_By_Expression,
            ):
                choiceExpression = GetExpressionFromNode(nodes.Get_Choice_Expression(alternative))

                choice = IndexedChoice(alternative, choiceExpression)
                if sameAlternative:
                    choices.append(choice)
                    alternative = nodes.Get_Chain(alternative)
                    continue
            elif choiceKind is nodes.Iir_Kind.Choice_By_Range:
                choiceRange = nodes.Get_Choice_Range(alternative)
                choiceRangeKind = GetIirKindOfNode(choiceRange)
                if choiceRangeKind == nodes.Iir_Kind.Range_Expression:
                    rng = GetRangeFromNode(choiceRange)
                elif choiceRangeKind in (
                    nodes.Iir_Kind.Attribute_Name,
                    nodes.Iir_Kind.Parenthesis_Name,
                ):
                    rng = GetNameFromNode(choiceRange)
                else:
                    pos = Position.parse(alternative)
                    raise DOMException(
                        "Unknown choice range kind '{kind}' in case statement at line {line}.".format(
                            kind=choiceRangeKind.name, line=pos.Line
                        )
                    )

                choice = RangedChoice(alternative, rng)
                if sameAlternative:
                    choices.append(choice)
                    alternative = nodes.Get_Chain(alternative)
                    continue
            elif choiceKind is nodes.Iir_Kind.Choice_By_Others:
                if choices is not None:
                    cases.append(Case.parse(alternative, choices, label))
                    choices = None
                cases.append(OthersCase.parse(alternative, label))
                alternative = nodes.Get_Chain(alternative)
                cNode = alternative
                continue
            else:
                pos = Position.parse(alternative)
                raise DOMException(
                    "Unknown choice kind '{kind}' in case statement at line {line}.".format(
                        kind=choiceKind.name, line=pos.Line
                    )
                )

            if choices is not None:
                cases.append(Case.parse(cNode, choices, label))

            cNode = alternative
            choices = [
                choice,
            ]

            alternative = nodes.Get_Chain(alternative)

        if choices is not None:
            cases.append(Case.parse(cNode, choices, label))

        return cls(caseNode, label, expression, cases)
Esempio n. 15
0
def GetDeclaredItemsFromChainedNodes(
        nodeChain: Iir, entity: str,
        name: str) -> Generator[ModelEntity, None, None]:
    item = nodeChain
    lastKind = None
    while item != nodes.Null_Iir:
        kind = GetIirKindOfNode(item)
        if kind == nodes.Iir_Kind.Constant_Declaration:
            from pyGHDL.dom.Object import Constant

            obj = Constant.parse(item)

        elif kind == nodes.Iir_Kind.Variable_Declaration:
            from pyGHDL.dom.Object import SharedVariable

            if nodes.Get_Shared_Flag(item):
                obj = SharedVariable.parse(item)
            else:
                obj = Variable.parse(item)
        elif kind == nodes.Iir_Kind.Signal_Declaration:
            from pyGHDL.dom.Object import Signal

            obj = Signal.parse(item)
        elif kind == nodes.Iir_Kind.File_Declaration:
            from pyGHDL.dom.Object import File

            obj = File.parse(item)
        else:
            if kind == nodes.Iir_Kind.Type_Declaration:
                yield GetTypeFromNode(item)

            elif kind == nodes.Iir_Kind.Anonymous_Type_Declaration:
                yield GetAnonymousTypeFromNode(item)

            elif kind == nodes.Iir_Kind.Subtype_Declaration:
                yield GetSubtypeFromNode(item)

            elif kind == nodes.Iir_Kind.Function_Declaration:
                if nodes.Get_Has_Body(item):
                    yield Function.parse(item)
                else:
                    print(
                        "[NOT IMPLEMENTED] function declaration without body")

                lastKind = kind
                item = nodes.Get_Chain(item)
                continue
            elif kind == nodes.Iir_Kind.Function_Body:
                if lastKind is nodes.Iir_Kind.Function_Declaration:
                    pass
                else:
                    position = Position.parse(item)
                    raise DOMException(
                        "Found unexpected function body '{functionName}' in {entity} '{name}' at {file}:{line}:{column}."
                        .format(
                            functionName=GetNameOfNode(item),
                            entity=entity,
                            name=name,
                            file=position.Filename,
                            line=position.Line,
                            column=position.Column,
                        ))
            elif kind == nodes.Iir_Kind.Procedure_Declaration:
                if nodes.Get_Has_Body(item):
                    yield Procedure.parse(item)
                else:
                    print(
                        "[NOT IMPLEMENTED] procedure declaration without body")

                lastKind = kind
                item = nodes.Get_Chain(item)
                continue
            elif kind == nodes.Iir_Kind.Procedure_Body:
                if lastKind is nodes.Iir_Kind.Procedure_Declaration:
                    pass
                else:
                    position = Position.parse(item)
                    raise DOMException(
                        "Found unexpected procedure body '{functionName}' in {entity} '{name}' at {file}:{line}:{column}."
                        .format(
                            functionName=GetNameOfNode(item),
                            entity=entity,
                            name=name,
                            file=position.Filename,
                            line=position.Line,
                            column=position.Column,
                        ))
            elif kind == nodes.Iir_Kind.Protected_Type_Body:
                yield ProtectedTypeBody.parse(item)
            elif kind == nodes.Iir_Kind.Object_Alias_Declaration:
                yield GetAliasFromNode(item)
            elif kind == nodes.Iir_Kind.Component_Declaration:
                from pyGHDL.dom.DesignUnit import Component

                yield Component.parse(item)
            elif kind == nodes.Iir_Kind.Attribute_Declaration:
                from pyGHDL.dom.Attribute import Attribute

                yield Attribute.parse(item)
            elif kind == nodes.Iir_Kind.Attribute_Specification:
                from pyGHDL.dom.Attribute import AttributeSpecification

                yield AttributeSpecification.parse(item)
            elif kind == nodes.Iir_Kind.Use_Clause:
                from pyGHDL.dom.DesignUnit import UseClause

                yield UseClause.parse(item)
            elif kind == nodes.Iir_Kind.Package_Declaration:
                from pyGHDL.dom.DesignUnit import Package

                yield Package.parse(item, None)  # TODO: Can it have a context?
            elif kind == nodes.Iir_Kind.Package_Instantiation_Declaration:
                from pyGHDL.dom.DesignUnit import PackageInstantiation

                yield PackageInstantiation.parse(item)
            elif kind == nodes.Iir_Kind.Configuration_Specification:
                print(
                    "[NOT IMPLEMENTED] Configuration specification in {name}".
                    format(name=name))
            elif kind == nodes.Iir_Kind.Psl_Default_Clock:
                yield DefaultClock.parse(item)
            elif kind == nodes.Iir_Kind.Group_Declaration:
                print("[NOT IMPLEMENTED] Group declaration in {name}".format(
                    name=name))
            elif kind == nodes.Iir_Kind.Group_Template_Declaration:
                print("[NOT IMPLEMENTED] Group template declaration in {name}".
                      format(name=name))
            elif kind == nodes.Iir_Kind.Disconnection_Specification:
                print("[NOT IMPLEMENTED] Disconnect specification in {name}".
                      format(name=name))
            else:
                position = Position.parse(item)
                raise DOMException(
                    "Unknown declared item kind '{kind}' in {entity} '{name}' at {file}:{line}:{column}."
                    .format(
                        kind=kind.name,
                        entity=entity,
                        name=name,
                        file=position.Filename,
                        line=position.Line,
                        column=position.Column,
                    ))

            lastKind = None
            item = nodes.Get_Chain(item)
            continue

        # Lookahead for objects with multiple identifiers at once
        if nodes.Get_Has_Identifier_List(item):
            nextNode = nodes.Get_Chain(item)
            for nextItem in utils.chain_iter(nextNode):
                # Consecutive identifiers are found, if the subtype indication is Null
                if nodes.Get_Subtype_Indication(nextItem) == nodes.Null_Iir:
                    obj.Identifiers.append(GetNameOfNode(nextItem))
                else:
                    item = nextItem
                    break

                # The last consecutive identifiers has no Identifier_List flag
                if not nodes.Get_Has_Identifier_List(nextItem):
                    item = nodes.Get_Chain(nextItem)
                    break
            else:
                item = nodes.Null_Iir
        else:
            item = nodes.Get_Chain(item)

        yield obj
Esempio n. 16
0
def chain_iter(n) -> Generator[Any, None, None]:
    """Iterate of a chain headed by node :obj:`n`."""
    while n != nodes.Null_Iir:
        yield n
        n = nodes.Get_Chain(n)
Esempio n. 17
0
def GetGenericsFromChainedNodes(
    nodeChain: Iir, ) -> Generator[GenericInterfaceItem, None, None]:
    from pyGHDL.dom.InterfaceItem import (
        GenericTypeInterfaceItem,
        GenericPackageInterfaceItem,
        GenericProcedureInterfaceItem,
        GenericFunctionInterfaceItem,
    )

    generic = nodeChain
    while generic != nodes.Null_Iir:
        kind = GetIirKindOfNode(generic)
        if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
            from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem

            genericConstant = GenericConstantInterfaceItem.parse(generic)

            # Lookahead for generics with multiple identifiers at once
            if nodes.Get_Has_Identifier_List(generic):
                nextNode = nodes.Get_Chain(generic)
                for nextGeneric in utils.chain_iter(nextNode):
                    # Consecutive identifiers are found, if the subtype indication is Null
                    if nodes.Get_Subtype_Indication(
                            nextGeneric) == nodes.Null_Iir:
                        genericConstant.Identifiers.append(
                            GetNameOfNode(nextGeneric))
                    else:
                        generic = nextGeneric
                        break

                    # The last consecutive identifiers has no Identifier_List flag
                    if not nodes.Get_Has_Identifier_List(nextGeneric):
                        generic = nodes.Get_Chain(nextGeneric)
                        break
                else:
                    generic = nodes.Null_Iir
            else:
                generic = nodes.Get_Chain(generic)

            yield genericConstant
            continue
        else:
            if kind == nodes.Iir_Kind.Interface_Type_Declaration:
                yield GenericTypeInterfaceItem.parse(generic)
            elif kind == nodes.Iir_Kind.Interface_Package_Declaration:
                yield GenericPackageInterfaceItem.parse(generic)
            elif kind == nodes.Iir_Kind.Interface_Procedure_Declaration:
                yield GenericProcedureInterfaceItem.parse(generic)
            elif kind == nodes.Iir_Kind.Interface_Function_Declaration:
                yield GenericFunctionInterfaceItem.parse(generic)
            else:
                position = Position.parse(generic)
                raise DOMException(
                    "Unknown generic kind '{kind}' in generic '{generic}' at {file}:{line}:{column}."
                    .format(
                        kind=kind.name,
                        generic=generic,
                        file=position.Filename,
                        line=position.Line,
                        column=position.Column,
                    ))

        generic = nodes.Get_Chain(generic)