aboutsummaryrefslogtreecommitdiffstats
path: root/pyGHDL/dom/Type.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyGHDL/dom/Type.py')
-rw-r--r--pyGHDL/dom/Type.py77
1 files changed, 66 insertions, 11 deletions
diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py
index efe32afc2..deb315d9d 100644
--- a/pyGHDL/dom/Type.py
+++ b/pyGHDL/dom/Type.py
@@ -34,7 +34,7 @@ from typing import List, Union, Iterator, Tuple
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
AnonymousType as VHDLModel_AnonymousType,
PhysicalType as VHDLModel_PhysicalType,
IntegerType as VHDLModel_IntegerType,
@@ -52,9 +52,8 @@ from pyVHDLModel.VHDLModel import (
)
from pyGHDL.libghdl import utils
from pyGHDL.libghdl._types import Iir
-from pyGHDL.libghdl.vhdl import nodes
-from pyGHDL.dom import DOMMixin, DOMException
-from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode
+from pyGHDL.libghdl.vhdl import nodes, flists
+from pyGHDL.dom import DOMMixin, DOMException, Position
from pyGHDL.dom.Symbol import SimpleSubtypeSymbol
from pyGHDL.dom.Literal import EnumerationLiteral, PhysicalIntegerLiteral
from pyGHDL.dom.Range import Range
@@ -69,6 +68,8 @@ class IncompleteType(VHDLModel_AnonymousType, DOMMixin):
@classmethod
def parse(cls, node: Iir) -> "IncompleteType":
+ from pyGHDL.dom._Utils import GetNameOfNode
+
name = GetNameOfNode(node)
return cls(node, name)
@@ -113,9 +114,25 @@ class PhysicalType(VHDLModel_PhysicalType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "PhysicalType":
- from pyGHDL.dom._Translate import GetRangeFromNode
-
- rng = GetRangeFromNode(nodes.Get_Range_Constraint(typeDefinitionNode))
+ from pyGHDL.dom._Utils import GetIirKindOfNode, GetNameOfNode
+ from pyGHDL.dom._Translate import GetRangeFromNode, GetNameFromNode
+
+ rangeConstraint = nodes.Get_Range_Constraint(typeDefinitionNode)
+ rangeKind = GetIirKindOfNode(rangeConstraint)
+ if rangeKind == nodes.Iir_Kind.Range_Expression:
+ rng = GetRangeFromNode(rangeConstraint)
+ elif rangeKind in (
+ nodes.Iir_Kind.Attribute_Name,
+ nodes.Iir_Kind.Parenthesis_Name,
+ ):
+ rng = GetNameFromNode(rangeConstraint)
+ else:
+ pos = Position.parse(typeDefinitionNode)
+ raise DOMException(
+ "Unknown range kind '{kind}' in physical type definition at line {line}.".format(
+ kind=rangeKind.name, line=pos.Line
+ )
+ )
primaryUnit = nodes.Get_Primary_Unit(typeDefinitionNode)
primaryUnitName = GetNameOfNode(primaryUnit)
@@ -145,6 +162,7 @@ class ArrayType(VHDLModel_ArrayType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "ArrayType":
+ from pyGHDL.dom._Utils import GetIirKindOfNode
from pyGHDL.dom._Translate import (
GetSimpleTypeFromNode,
GetSubtypeIndicationFromIndicationNode,
@@ -176,12 +194,13 @@ class ArrayType(VHDLModel_ArrayType, DOMMixin):
@export
class RecordTypeElement(VHDLModel_RecordTypeElement, DOMMixin):
- def __init__(self, node: Iir, identifier: str, subtype: SubtypeOrSymbol):
- super().__init__(identifier, subtype)
+ def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol):
+ super().__init__(identifiers, subtype)
DOMMixin.__init__(self, node)
@classmethod
def parse(cls, elementDeclarationNode: Iir) -> "RecordTypeElement":
+ from pyGHDL.dom._Utils import GetNameOfNode
from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode
elementName = GetNameOfNode(elementDeclarationNode)
@@ -189,7 +208,13 @@ class RecordTypeElement(VHDLModel_RecordTypeElement, DOMMixin):
elementDeclarationNode, "record element", elementName
)
- return cls(elementDeclarationNode, elementName, elementType)
+ return cls(
+ elementDeclarationNode,
+ [
+ elementName,
+ ],
+ elementType,
+ )
@export
@@ -202,10 +227,36 @@ class RecordType(VHDLModel_RecordType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "RecordType":
+ from pyGHDL.dom._Utils import GetNameOfNode
+
elements = []
elementDeclarations = nodes.Get_Elements_Declaration_List(typeDefinitionNode)
- for elementDeclaration in utils.flist_iter(elementDeclarations):
+
+ elementCount = flists.Flast(elementDeclarations) + 1
+ index = 0
+ while index < elementCount:
+ elementDeclaration = flists.Get_Nth_Element(elementDeclarations, index)
+
element = RecordTypeElement.parse(elementDeclaration)
+
+ # Lookahead for elements with multiple identifiers at once
+ if nodes.Get_Has_Identifier_List(elementDeclaration):
+ index += 1
+ while index < elementCount:
+ nextNode: Iir = flists.Get_Nth_Element(elementDeclarations, index)
+ # Consecutive identifiers are found, if the subtype indication is Null
+ if nodes.Get_Subtype_Indication(nextNode) == nodes.Null_Iir:
+ element.Identifiers.append(GetNameOfNode(nextNode))
+ else:
+ break
+ index += 1
+
+ # The last consecutive identifiers has no Identifier_List flag
+ if not nodes.Get_Has_Identifier_List(nextNode):
+ break
+ else:
+ index += 1
+
elements.append(element)
return cls(typeDefinitionNode, typeName, elements)
@@ -221,6 +272,8 @@ class ProtectedType(VHDLModel_ProtectedType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "ProtectedType":
+ from pyGHDL.dom._Utils import GetIirKindOfNode
+
# FIXME: change this to a generator
methods = []
for item in utils.chain_iter(nodes.Get_Declaration_Chain(typeDefinitionNode)):
@@ -243,6 +296,7 @@ class ProtectedTypeBody(VHDLModel_ProtectedTypeBody, DOMMixin):
@classmethod
def parse(cls, protectedBodyNode: Iir) -> "ProtectedTypeBody":
+ from pyGHDL.dom._Utils import GetNameOfNode
from pyGHDL.dom._Translate import GetDeclaredItemsFromChainedNodes
typeName = GetNameOfNode(protectedBodyNode)
@@ -283,6 +337,7 @@ class FileType(VHDLModel_FileType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "FileType":
+ from pyGHDL.dom._Utils import GetNameOfNode
designatedSubtypeMark = nodes.Get_File_Type_Mark(typeDefinitionNode)
designatedSubtypeName = GetNameOfNode(designatedSubtypeMark)