aboutsummaryrefslogtreecommitdiffstats
path: root/pyGHDL/dom
diff options
context:
space:
mode:
authorPatrick Lehmann <Patrick.Lehmann@plc2.de>2021-08-13 22:21:04 +0200
committerumarcor <unai.martinezcorral@ehu.eus>2021-08-23 16:35:35 +0200
commitc4326161ce97d3286e8dffe31d0c168e05f3f9ea (patch)
tree954166bc0eb0dcf1a538716aadf840dab62bb871 /pyGHDL/dom
parent357cb9746c53e3f32fc9c2f28686c25e388918c3 (diff)
downloadghdl-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.py50
-rw-r--r--pyGHDL/dom/Expression.py17
-rw-r--r--pyGHDL/dom/Sequential.py51
-rw-r--r--pyGHDL/dom/Type.py35
-rw-r--r--pyGHDL/dom/_Translate.py3
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