diff options
author | Patrick Lehmann <Patrick.Lehmann@plc2.de> | 2021-08-13 22:21:04 +0200 |
---|---|---|
committer | umarcor <unai.martinezcorral@ehu.eus> | 2021-08-23 16:35:35 +0200 |
commit | c4326161ce97d3286e8dffe31d0c168e05f3f9ea (patch) | |
tree | 954166bc0eb0dcf1a538716aadf840dab62bb871 /pyGHDL/dom | |
parent | 357cb9746c53e3f32fc9c2f28686c25e388918c3 (diff) | |
download | ghdl-c4326161ce97d3286e8dffe31d0c168e05f3f9ea.tar.gz ghdl-c4326161ce97d3286e8dffe31d0c168e05f3f9ea.tar.bz2 ghdl-c4326161ce97d3286e8dffe31d0c168e05f3f9ea.zip |
Improved handling of ranges (e.g. via attribute names).
Diffstat (limited to 'pyGHDL/dom')
-rw-r--r-- | pyGHDL/dom/Concurrent.py | 50 | ||||
-rw-r--r-- | pyGHDL/dom/Expression.py | 17 | ||||
-rw-r--r-- | pyGHDL/dom/Sequential.py | 51 | ||||
-rw-r--r-- | pyGHDL/dom/Type.py | 35 | ||||
-rw-r--r-- | pyGHDL/dom/_Translate.py | 3 |
5 files changed, 136 insertions, 20 deletions
diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index a23bb8cf6..de4e70539 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -58,12 +58,13 @@ from pyVHDLModel.SyntaxModel import ( ConcurrentStatement, SequentialStatement, Expression, - ConcurrentChoice, ConcurrentCase, + ConcurrentChoice, + ConcurrentCase, ) from pyGHDL.libghdl import Iir, utils from pyGHDL.libghdl.vhdl import nodes -from pyGHDL.dom import DOMMixin +from pyGHDL.dom import DOMMixin, DOMException, Position from pyGHDL.dom._Utils import GetNameOfNode @@ -186,10 +187,10 @@ class ProcessStatement(VHDLModel_ProcessStatement, DOMMixin): def parse( cls, processNode: Iir, label: str, hasSensitivityList: bool ) -> "ProcessStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, GetSequentialStatementsFromChainedNodes, - GetIirKindOfNode ) sensitivityList = None @@ -453,10 +454,11 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "CaseGenerateStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetExpressionFromNode, - GetIirKindOfNode, GetRangeFromNode, + GetNameFromNode, ) # TODO: get choices @@ -480,7 +482,23 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): cases.append(GenerateCase(alternative, choices)) choices = [] elif choiceKind is nodes.Iir_Kind.Choice_By_Range: - rng = GetRangeFromNode(nodes.Get_Choice_Range(alternative)) + 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(generateNode) + raise DOMException( + "Unknown choice range kind '{kind}' in case...generate statement at line {line}.".format( + kind=choiceRangeKind.name, line=pos.Line + ) + ) + choices.append(RangedGenerateChoice(alternative, rng)) cases.append(GenerateCase(alternative, choices)) choices = [] @@ -508,15 +526,33 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "ForGenerateStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, GetConcurrentStatementsFromChainedNodes, GetRangeFromNode, + GetNameFromNode, ) spec = nodes.Get_Parameter_Specification(generateNode) loopIndex = GetNameOfNode(spec) - rng = GetRangeFromNode(nodes.Get_Discrete_Range(spec)) + + discreteRange = nodes.Get_Discrete_Range(spec) + rangeKind = GetIirKindOfNode(discreteRange) + if rangeKind == nodes.Iir_Kind.Range_Expression: + rng = GetRangeFromNode(discreteRange) + elif rangeKind in ( + nodes.Iir_Kind.Attribute_Name, + nodes.Iir_Kind.Parenthesis_Name, + ): + rng = GetNameFromNode(discreteRange) + else: + pos = Position.parse(generateNode) + raise DOMException( + "Unknown discete range kind '{kind}' in for...generate statement at line {line}.".format( + kind=rangeKind.name, line=pos.Line + ) + ) body = nodes.Get_Generate_Statement_Body(generateNode) declarationChain = nodes.Get_Declaration_Chain(body) @@ -584,7 +620,7 @@ class ConcurrentProcedureCall(VHDLModel_ConcurrentProcedureCall, DOMMixin): @classmethod def parse(cls, callNode: Iir, label: str) -> "ConcurrentProcedureCall": - from pyGHDL.dom._Translate import GetNameFromNode, GetIirKindOfNode + from pyGHDL.dom._Translate import GetNameFromNode call = nodes.Get_Procedure_Call(callNode) prefix = nodes.Get_Prefix(call) diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py index 83a3f65df..3b871f7dd 100644 --- a/pyGHDL/dom/Expression.py +++ b/pyGHDL/dom/Expression.py @@ -571,6 +571,23 @@ class Aggregate(VHDLModel_Aggregate, DOMMixin): choices.append(IndexedAggregateElement(item, index, value)) elif kind == nodes.Iir_Kind.Choice_By_Range: r = GetRangeFromNode(nodes.Get_Choice_Range(item)) + + rangeKind = GetIirKindOfNode(discreteRange) + if rangeKind == nodes.Iir_Kind.Range_Expression: + rng = GetRangeFromNode(discreteRange) + elif rangeKind in ( + nodes.Iir_Kind.Attribute_Name, + nodes.Iir_Kind.Parenthesis_Name, + ): + rng = GetNameFromNode(discreteRange) + else: + pos = Position.parse(generateNode) + raise DOMException( + "Unknown discete range kind '{kind}' in for...generate statement at line {line}.".format( + kind=rangeKind.name, line=pos.Line + ) + ) + choices.append(RangedAggregateElement(item, r, value)) elif kind == nodes.Iir_Kind.Choice_By_Name: name = GetNameFromNode(nodes.Get_Choice_Name(item)) diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 896b09544..cc5a58d15 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -34,7 +34,7 @@ from typing import Iterable from pydecor import export -from pyGHDL.dom.Concurrent import WaveformElement # TODO: move out from concurrent? +from pyGHDL.dom.Concurrent import WaveformElement # TODO: move out from concurrent? from pyGHDL.dom.Range import Range from pyVHDLModel.SyntaxModel import ( IfBranch as VHDLModel_IfBranch, @@ -52,13 +52,14 @@ from pyVHDLModel.SyntaxModel import ( Name, SequentialStatement, Expression, - SequentialChoice, SequentialCase, + SequentialChoice, + SequentialCase, ) from pyGHDL.libghdl import Iir, utils from pyGHDL.libghdl.vhdl import nodes -from pyGHDL.dom import DOMMixin +from pyGHDL.dom import DOMMixin, Position, DOMException from pyGHDL.dom._Utils import GetNameOfNode @@ -257,10 +258,11 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "CaseStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetExpressionFromNode, - GetIirKindOfNode, GetRangeFromNode, + GetNameFromNode, ) # TODO: get choices @@ -284,7 +286,23 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): cases.append(Case(alternative, choices)) choices = [] elif choiceKind is nodes.Iir_Kind.Choice_By_Range: - rng = GetRangeFromNode(nodes.Get_Choice_Range(alternative)) + 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(generateNode) + raise DOMException( + "Unknown choice range kind '{kind}' in case statement at line {line}.".format( + kind=choiceRangeKind.name, line=pos.Line + ) + ) + choices.append(RangedChoice(alternative, rng)) cases.append(Case(alternative, choices)) choices = [] @@ -311,14 +329,32 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "ForLoopStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, GetRangeFromNode, + GetNameFromNode, ) spec = nodes.Get_Parameter_Specification(generateNode) loopIndex = GetNameOfNode(spec) - rng = GetRangeFromNode(nodes.Get_Discrete_Range(spec)) + + discreteRange = nodes.Get_Discrete_Range(spec) + rangeKind = GetIirKindOfNode(discreteRange) + if rangeKind == nodes.Iir_Kind.Range_Expression: + rng = GetRangeFromNode(discreteRange) + elif rangeKind in ( + nodes.Iir_Kind.Attribute_Name, + nodes.Iir_Kind.Parenthesis_Name, + ): + rng = GetNameFromNode(discreteRange) + else: + pos = Position.parse(generateNode) + raise DOMException( + "Unknown discete range kind '{kind}' in for...loop statement at line {line}.".format( + kind=rangeKind.name, line=pos.Line + ) + ) body = nodes.Get_Generate_Statement_Body(generateNode) @@ -375,7 +411,8 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): @classmethod def parse(cls, callNode: Iir, label: str) -> "SequentialProcedureCall": - from pyGHDL.dom._Translate import GetNameFromNode, GetIirKindOfNode + from pyGHDL.dom._Utils import GetIirKindOfNode + from pyGHDL.dom._Translate import GetNameFromNode call = nodes.Get_Procedure_Call(callNode) prefix = nodes.Get_Prefix(call) diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py index 969ec5643..deb315d9d 100644 --- a/pyGHDL/dom/Type.py +++ b/pyGHDL/dom/Type.py @@ -53,8 +53,7 @@ from pyVHDLModel.SyntaxModel import ( from pyGHDL.libghdl import utils from pyGHDL.libghdl._types import Iir from pyGHDL.libghdl.vhdl import nodes, flists -from pyGHDL.dom import DOMMixin, DOMException -from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode +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, @@ -182,6 +200,7 @@ class RecordTypeElement(VHDLModel_RecordTypeElement, DOMMixin): @classmethod def parse(cls, elementDeclarationNode: Iir) -> "RecordTypeElement": + from pyGHDL.dom._Utils import GetNameOfNode from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode elementName = GetNameOfNode(elementDeclarationNode) @@ -208,6 +227,8 @@ 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) @@ -251,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)): @@ -273,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) @@ -313,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) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 2103064a4..6e3a95ea7 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -45,7 +45,8 @@ from pyVHDLModel.SyntaxModel import ( ParameterInterfaceItem, ModelEntity, Name, - ConcurrentStatement, SequentialStatement, + ConcurrentStatement, + SequentialStatement, ) from pyGHDL.libghdl import utils, name_table |