From 9fca189af9677e435a42eaae1edd91e1098596ac Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 23 Jun 2021 10:06:39 +0200 Subject: Added handling of enumeration, array and record types. --- pyGHDL/dom/Literal.py | 22 ++++++++++++++----- pyGHDL/dom/Type.py | 56 ++++++++++++++++++++++++++++++++++++++++++++--- pyGHDL/dom/_Translate.py | 57 +++++++++++++++++++++++++++++++++--------------- 3 files changed, 108 insertions(+), 27 deletions(-) (limited to 'pyGHDL/dom') diff --git a/pyGHDL/dom/Literal.py b/pyGHDL/dom/Literal.py index 209712ba3..10d30b0fa 100644 --- a/pyGHDL/dom/Literal.py +++ b/pyGHDL/dom/Literal.py @@ -30,9 +30,11 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ +from pyGHDL.libghdl._types import Iir from pydecor import export from pyVHDLModel.VHDLModel import ( + EnumerationLiteral as VHDLModel_EnumerationLiteral, IntegerLiteral as VHDLModel_IntegerLiteral, FloatingPointLiteral as VHDLModel_FloatingPointLiteral, PhysicalIntegerLiteral as VHDLModel_PhysicalIntegerLiteral, @@ -47,10 +49,18 @@ from pyGHDL.dom._Utils import GetNameOfNode __all__ = [] +@export +class EnumerationLiteral(VHDLModel_EnumerationLiteral): + @classmethod + def parse(cls, literalNode: Iir) -> 'EnumerationLiteral': + literalName = GetNameOfNode(literalNode) + return cls(literalName) + + @export class IntegerLiteral(VHDLModel_IntegerLiteral): @classmethod - def parse(cls, node): + def parse(cls, node: Iir) -> 'IntegerLiteral': value = nodes.Get_Value(node) return cls(value) @@ -58,7 +68,7 @@ class IntegerLiteral(VHDLModel_IntegerLiteral): @export class FloatingPointLiteral(VHDLModel_FloatingPointLiteral): @classmethod - def parse(cls, node): + def parse(cls, node: Iir) -> 'FloatingPointLiteral': value = nodes.Get_Fp_Value(node) return cls(value) @@ -66,7 +76,7 @@ class FloatingPointLiteral(VHDLModel_FloatingPointLiteral): @export class PhysicalIntegerLiteral(VHDLModel_PhysicalIntegerLiteral): @classmethod - def parse(cls, node): + def parse(cls, node: Iir) -> 'PhysicalIntegerLiteral': value = nodes.Get_Value(node) unit = nodes.Get_Unit_Name(node) unitName = GetNameOfNode(unit) @@ -77,7 +87,7 @@ class PhysicalIntegerLiteral(VHDLModel_PhysicalIntegerLiteral): @export class PhysicalFloatingLiteral(VHDLModel_PhysicalFloatingLiteral): @classmethod - def parse(cls, node): + def parse(cls, node: Iir) -> 'PhysicalFloatingLiteral': value = nodes.Get_Fp_Value(node) unit = nodes.Get_Unit_Name(node) unitName = GetNameOfNode(unit) @@ -88,7 +98,7 @@ class PhysicalFloatingLiteral(VHDLModel_PhysicalFloatingLiteral): @export class CharacterLiteral(VHDLModel_CharacterLiteral): @classmethod - def parse(cls, node): + def parse(cls, node: Iir) -> 'CharacterLiteral': identifier = nodes.Get_Identifier(node) value = name_table.Get_Character(identifier) return cls(value) @@ -97,7 +107,7 @@ class CharacterLiteral(VHDLModel_CharacterLiteral): @export class StringLiteral(VHDLModel_StringLiteral): @classmethod - def parse(cls, node): + def parse(cls, node: Iir) -> 'StringLiteral': stringID = nodes.Get_String8_Id(node) value = name_table.Get_Name_Ptr(stringID) return cls(value) diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py index 1576eb849..38cd8f5a4 100644 --- a/pyGHDL/dom/Type.py +++ b/pyGHDL/dom/Type.py @@ -30,6 +30,14 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ +from pyGHDL.dom.Common import DOMException +from pyGHDL.dom.Literal import EnumerationLiteral +from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode +from pyGHDL.libghdl import utils + +from pyGHDL.libghdl.vhdl import nodes + +from pyGHDL.libghdl._types import Iir from pydecor import export from pyGHDL.dom.Range import Range @@ -55,12 +63,41 @@ class IntegerType(VHDLModel_IntegerType): @export class EnumeratedType(VHDLModel_EnumeratedType): - pass + @classmethod + def parse(cls, typeName: str, typeDefinitionNode: Iir): + literals = [] + enumerationLiterals = nodes.Get_Enumeration_Literal_List(typeDefinitionNode) + for enumerationLiteral in utils.flist_iter(enumerationLiterals): + literal = EnumerationLiteral.parse(enumerationLiteral) + literals.append(literal) + + return cls(typeName, literals) @export class ArrayType(VHDLModel_ArrayType): - pass + @classmethod + def parse(cls, typeName: str, typeDefinitionNode: Iir): + from pyGHDL.dom._Translate import GetSimpleTypeFromNode, GetSubTypeIndicationFromNode + + indices = [] + indexDefinitions = nodes.Get_Index_Subtype_Definition_List(typeDefinitionNode) + for index in utils.flist_iter(indexDefinitions): + indexKind = GetIirKindOfNode(index) + if indexKind == nodes.Iir_Kind.Simple_Name: + indexSubType = GetSimpleTypeFromNode(index) + indices.append(indexSubType) + else: + raise DOMException( + "Unknown kind '{kind}' for an index in the array definition of `{typeName}`.".format( + kind=indexKind.name, typeName=typeName + ) + ) + + elementSubTypeIndication = nodes.Get_Element_Subtype_Indication(typeDefinitionNode) + elementSubType = GetSubTypeIndicationFromNode(elementSubTypeIndication, "array declaration", typeName) + + return cls(typeName, indices, elementSubType) @export @@ -70,7 +107,20 @@ class RecordTypeElement(VHDLModel_RecordTypeElement): @export class RecordType(VHDLModel_RecordType): - pass + @classmethod + def parse(cls, typeName: str, typeDefinitionNode: Iir): + from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode + + elements = [] + elementDeclarations = nodes.Get_Elements_Declaration_List(typeDefinitionNode) + for elementDeclaration in utils.flist_iter(elementDeclarations): + elementName = GetNameOfNode(elementDeclaration) + elementType = GetSubtypeIndicationFromNode(elementDeclaration, "record element", elementName) + + element = RecordTypeElement(elementName, elementType) + elements.append(element) + + return cls(typeName, elements) @export diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index a3e3a7c96..8cb1639fd 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -64,6 +64,7 @@ from pyGHDL.dom.Type import ( RecordType, EnumeratedType, RecordTypeElement, + AccessType, ) from pyGHDL.dom.Range import Range, RangeExpression from pyGHDL.dom.Literal import ( @@ -72,7 +73,7 @@ from pyGHDL.dom.Literal import ( FloatingPointLiteral, StringLiteral, PhysicalIntegerLiteral, - PhysicalFloatingLiteral, + PhysicalFloatingLiteral, EnumerationLiteral, ) from pyGHDL.dom.Expression import ( SubtractionExpression, @@ -195,25 +196,19 @@ def GetTypeFromNode(node: Iir) -> BaseType: return IntegerType(typeName, r) elif kind == nodes.Iir_Kind.Enumeration_Type_Definition: - - return EnumeratedType(typeName) + return EnumeratedType.parse(typeName, typeDefinition) elif kind == nodes.Iir_Kind.Array_Type_Definition: - indexSubTypeDefinitionList = nodes.Get_Index_Subtype_Definition_List( - typeDefinition - ) - elementSubTypeIndication = nodes.Get_Element_Subtype_Indication(typeDefinition) + return ArrayType.parse(typeName, typeDefinition) + elif kind == nodes.Iir_Kind.Array_Subtype_Definition: + print("Array_Subtype_Definition") - return ArrayType(typeName) + return ArrayType elif kind == nodes.Iir_Kind.Record_Type_Definition: - elements = [] - elementDeclarations = nodes.Get_Elements_Declaration_List(typeDefinition) - for element in utils.flist_iter(elementDeclarations): - elementName = GetNameOfNode(element) - elementType = None # GetSubtypeIndicationFromNode(element) + return RecordType.parse(typeName, typeDefinition) + elif kind == nodes.Iir_Kind.Access_Type_Definition: + designatedType = nodes.Get_Designated_Type(typeDefinition) - elements.append(RecordTypeElement(elementName, elementType)) - - return RecordType(typeName, elements) + return AccessType(typeName, designatedType) else: position = GetPositionOfNode(typeDefinition) raise DOMException( @@ -229,12 +224,38 @@ def GetTypeFromNode(node: Iir) -> BaseType: @export -def GetSubTypeFromNode(node: Iir) -> BaseType: +def GetSubTypeIndicationFromNode(subTypeIndicationNode: Iir, entity: str, name: str) -> SubTypeOrSymbol: + kind = GetIirKindOfNode(subTypeIndicationNode) + if kind == nodes.Iir_Kind.Simple_Name: + return GetSimpleTypeFromNode(subTypeIndicationNode) + elif kind == nodes.Iir_Kind.Array_Subtype_Definition: + return GetConstrainedSubTypeFromNode(subTypeIndicationNode) + else: + raise DOMException( + "Unknown kind '{kind}' for an subtype indication in a {entity} of `{name}`.".format( + kind=kind.name, entity=entity, name=name + ) + ) + +@export +def GetSimpleTypeFromNode(subTypeIndicationNode: Iir) -> SimpleSubTypeSymbol: + subTypeName = GetNameOfNode(subTypeIndicationNode) + return SimpleSubTypeSymbol(subTypeName) + +@export +def GetConstrainedSubTypeFromNode(subTypeIndicationNode: Iir) -> ConstrainedSubTypeSymbol: + typeMark = nodes.Get_Subtype_Type_Mark(subTypeIndicationNode) + typeMarkName = GetNameOfNode(typeMark) + + constraints = GetArrayConstraintsFromSubtypeIndication(subTypeIndicationNode) + return ConstrainedSubTypeSymbol(typeMarkName, constraints) + +@export +def GetSubTypeFromNode(node: Iir) -> SubTypeOrSymbol: subTypeName = GetNameOfNode(node) return SubType(subTypeName) - @export def GetRangeFromNode(node: Iir) -> Range: direction = nodes.Get_Direction(node) -- cgit v1.2.3