aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Lehmann <Patrick.Lehmann@plc2.de>2021-06-26 13:48:09 +0200
committerGitHub <noreply@github.com>2021-06-26 13:48:09 +0200
commit111fe055b2f0f3a0225d2553cf739572d691a14d (patch)
tree50d3a874bb78107627a6509fd4054c7fdc96cd25
parent15c6de72bc8dd316cb5262e1b5f373ca45b05f68 (diff)
downloadghdl-111fe055b2f0f3a0225d2553cf739572d691a14d.tar.gz
ghdl-111fe055b2f0f3a0225d2553cf739572d691a14d.tar.bz2
ghdl-111fe055b2f0f3a0225d2553cf739572d691a14d.zip
More DOM improvements (#1806)
* First try to handle names. * Reworked names. * Reworked range expressions. * Handle AttributeNames. * Added handling of file declaration and attribute declarations. * Improved error outputs. * Handle protected types. * Make black happy with ugly code. * Handle Null literal and File parameters. * File type and physical type. * Don't fail on reported syntax errors. Catch call errors into libghdl. * Improved Sanity checks for pyGHDL.dom. * Load sourcecode via Python and process in-memory. Fixed testcases. * Added package instantiations and packages with generics. * Added UseClause, AttributeSpecification and PhysicalTypes. * Improved pretty-printing. * Fixed AttributeName in subtype indication. * Get code position of IIR nodes. * Added DOMMixin into all derived classes. * Mark as not yet implemented. * Pinned pyVHDLModel version to v0.10.4. * Removed xfail in LSP test. Bumped requirement of pyVHDLModel to v0.10.4. Fixed some Codacy issues. (cherry picked from commit f64e7ed7c3d69cbf84cd60db8e9b085e90b846cb)
-rwxr-xr-xpyGHDL/cli/DOM.py34
-rw-r--r--pyGHDL/dom/Aggregates.py38
-rw-r--r--pyGHDL/dom/Attribute.py83
-rw-r--r--pyGHDL/dom/Common.py53
-rw-r--r--pyGHDL/dom/DesignUnit.py176
-rw-r--r--pyGHDL/dom/Expression.py303
-rw-r--r--pyGHDL/dom/InterfaceItem.py176
-rw-r--r--pyGHDL/dom/Literal.py99
-rw-r--r--pyGHDL/dom/Misc.py36
-rw-r--r--pyGHDL/dom/Names.py99
-rw-r--r--pyGHDL/dom/NonStandard.py79
-rw-r--r--pyGHDL/dom/Object.py141
-rw-r--r--pyGHDL/dom/Range.py8
-rw-r--r--pyGHDL/dom/Subprogram.py41
-rw-r--r--pyGHDL/dom/Symbol.py84
-rw-r--r--pyGHDL/dom/Type.py178
-rw-r--r--pyGHDL/dom/_Translate.py209
-rw-r--r--pyGHDL/dom/_Utils.py50
-rw-r--r--pyGHDL/dom/__init__.py73
-rw-r--r--pyGHDL/dom/formatting/prettyprint.py78
-rw-r--r--pyGHDL/libghdl/__init__.py10
-rw-r--r--pyGHDL/libghdl/_decorator.py26
-rw-r--r--pyGHDL/libghdl/files_map_editor.py4
-rw-r--r--pyGHDL/requirements.txt2
-rw-r--r--setup.py3
-rw-r--r--testsuite/pyunit/Current.vhdl42
-rw-r--r--testsuite/pyunit/dom/Expressions.py61
-rw-r--r--testsuite/pyunit/dom/Literals.py2
-rw-r--r--testsuite/pyunit/dom/Sanity.py15
-rw-r--r--testsuite/pyunit/lsp/LanguageServer.py1
30 files changed, 1640 insertions, 564 deletions
diff --git a/pyGHDL/cli/DOM.py b/pyGHDL/cli/DOM.py
index dceafc629..622a70d16 100755
--- a/pyGHDL/cli/DOM.py
+++ b/pyGHDL/cli/DOM.py
@@ -4,12 +4,13 @@ from sys import argv
from sys import exit as sysexit
from pathlib import Path
+from textwrap import dedent
from pydecor import export
from pyGHDL import GHDLBaseException
from pyGHDL.libghdl import LibGHDLException
-from pyGHDL.dom.Common import DOMException
+from pyGHDL.dom import DOMException
from pyGHDL.dom.NonStandard import Design, Document
from pyGHDL.dom.formatting.prettyprint import PrettyPrint, PrettyPrintException
@@ -41,6 +42,19 @@ class Application:
print("\n".join(buffer))
+ document: Document = self._design.Documents[0]
+ print()
+ print(
+ "libghdl processing time: {: 5.3f} us".format(
+ document.LibGHDLProcessingTime * 10 ** 6
+ )
+ )
+ print(
+ "DOM translation time: {:5.3f} us".format(
+ document.DOMTranslationTime * 10 ** 6
+ )
+ )
+
def handleException(ex):
if isinstance(ex, PrettyPrintException):
@@ -52,6 +66,7 @@ def handleException(ex):
if ex2 is not None:
for message in ex2.InternalErrors:
print("libghdl: {message}".format(message=message))
+ return 0
return 4
elif isinstance(ex, LibGHDLException):
print("LIB:", ex)
@@ -81,8 +96,23 @@ def main(items=argv[1:]):
app = Application()
app.addFile(Path(item), "default_lib")
app.prettyPrint()
- except Exception as ex:
+ except GHDLBaseException as ex:
_exitcode = handleException(ex)
+ except Exception as ex:
+ print(
+ dedent(
+ """\
+ Fatal: An unhandled exception has reached to the top-most exception handler.
+ Exception: {name}
+ """.format(
+ name=ex.__class__.__name__
+ )
+ )
+ )
+ if isinstance(ex, ValueError):
+ print(" Message: {msg}".format(msg=str(ex)))
+ if ex.__cause__ is not None:
+ print("Cause: {msg}".format(msg=str(ex.__cause__)))
return _exitcode
diff --git a/pyGHDL/dom/Aggregates.py b/pyGHDL/dom/Aggregates.py
index ac8ecbca8..32dc1cacf 100644
--- a/pyGHDL/dom/Aggregates.py
+++ b/pyGHDL/dom/Aggregates.py
@@ -41,8 +41,6 @@ This module contains all DOM classes for VHDL's design units (:class:`context <E
"""
from pydecor import export
-from pyGHDL.dom.Range import Range
-from pyGHDL.dom.Symbol import EnumerationLiteralSymbol
from pyVHDLModel.VHDLModel import (
SimpleAggregateElement as VHDLModel_SimpleAggregateElement,
IndexedAggregateElement as VHDLModel_IndexedAggregateElement,
@@ -51,44 +49,60 @@ from pyVHDLModel.VHDLModel import (
OthersAggregateElement as VHDLModel_OthersAggregateElement,
Expression,
)
+from pyGHDL.libghdl._types import Iir
+from pyGHDL.dom import DOMMixin
+from pyGHDL.dom.Range import Range
+from pyGHDL.dom.Symbol import EnumerationLiteralSymbol
__all__ = []
@export
-class SimpleAggregateElement(VHDLModel_SimpleAggregateElement):
- def __init__(self, expression: Expression):
+class SimpleAggregateElement(VHDLModel_SimpleAggregateElement, DOMMixin):
+ def __init__(self, node: Iir, expression: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._expression = expression
@export
-class IndexedAggregateElement(VHDLModel_IndexedAggregateElement):
- def __init__(self, index: Expression, expression: Expression):
+class IndexedAggregateElement(VHDLModel_IndexedAggregateElement, DOMMixin):
+ def __init__(self, node: Iir, index: Expression, expression: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._index = index
self._expression = expression
@export
-class RangedAggregateElement(VHDLModel_RangedAggregateElement):
- def __init__(self, r: Range, expression: Expression):
+class RangedAggregateElement(VHDLModel_RangedAggregateElement, DOMMixin):
+ def __init__(self, node: Iir, r: Range, expression: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._range = r
self._expression = expression
@export
-class NamedAggregateElement(VHDLModel_NamedAggregateElement):
- def __init__(self, name: EnumerationLiteralSymbol, expression: Expression):
+class NamedAggregateElement(VHDLModel_NamedAggregateElement, DOMMixin):
+ def __init__(
+ self, node: Iir, name: EnumerationLiteralSymbol, expression: Expression
+ ):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._name = name
self._expression = expression
@export
-class OthersAggregateElement(VHDLModel_OthersAggregateElement):
- def __init__(self, expression: Expression):
+class OthersAggregateElement(VHDLModel_OthersAggregateElement, DOMMixin):
+ def __init__(self, node: Iir, expression: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._expression = expression
diff --git a/pyGHDL/dom/Attribute.py b/pyGHDL/dom/Attribute.py
new file mode 100644
index 000000000..8c7b08190
--- /dev/null
+++ b/pyGHDL/dom/Attribute.py
@@ -0,0 +1,83 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Package module: DOM: Interface items (e.g. generic or port)
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pydecor import export
+
+from pyVHDLModel.VHDLModel import (
+ Attribute as VHDLModel_Attribute,
+ AttributeSpecification as VHDLModel_AttributeSpecification,
+ Name,
+ SubTypeOrSymbol,
+)
+from pyGHDL.libghdl._types import Iir
+from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL.dom import DOMMixin
+from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode
+from pyGHDL.dom._Translate import GetNameFromNode
+from pyGHDL.dom.Symbol import SimpleSubTypeSymbol
+
+
+@export
+class Attribute(VHDLModel_Attribute, DOMMixin):
+ def __init__(self, node: Iir, name: str, subType: SubTypeOrSymbol):
+ super().__init__(name, subType)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(cls, attributeNode: Iir) -> "Attribute":
+ name = GetNameOfNode(attributeNode)
+ subTypeMark = nodes.Get_Type_Mark(attributeNode)
+ subTypeName = GetNameOfNode(subTypeMark)
+
+ subType = SimpleSubTypeSymbol(subTypeMark, subTypeName)
+ return cls(attributeNode, name, subType)
+
+
+@export
+class AttributeSpecification(VHDLModel_AttributeSpecification, DOMMixin):
+ def __init__(self, node: Iir, attribute: Name):
+ super().__init__(attribute)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(cls, attributeNode: Iir) -> "AttributeSpecification":
+ attributeDesignator = nodes.Get_Attribute_Designator(attributeNode)
+ attributeName = GetNameFromNode(attributeDesignator)
+
+ # FIXME: needs an implementation
+ entityNameList = nodes.Get_Entity_Name_List(attributeNode)
+ enlk = GetIirKindOfNode(entityNameList)
+
+ entityClass = nodes.Get_Entity_Class(attributeNode)
+ eck = GetIirKindOfNode(entityClass)
+
+ return cls(attributeNode, attributeName)
diff --git a/pyGHDL/dom/Common.py b/pyGHDL/dom/Common.py
deleted file mode 100644
index 43e8ce497..000000000
--- a/pyGHDL/dom/Common.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# =============================================================================
-# ____ _ _ ____ _ _
-# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
-# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
-# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
-# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-# |_| |___/
-# =============================================================================
-# Authors:
-# Patrick Lehmann
-#
-# Package module: DOM: Common classes for package pyGHDL.dom.
-#
-# License:
-# ============================================================================
-# Copyright (C) 2019-2021 Tristan Gingold
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <gnu.org/licenses>.
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-# ============================================================================
-
-"""
-.. todo::
- Add a module documentation.
-"""
-from pydecor import export
-
-from pyGHDL import GHDLBaseException
-from pyGHDL.libghdl import LibGHDLException, errorout_memory
-
-__all__ = []
-
-
-@export
-class DOMException(GHDLBaseException):
- pass
-
-
-@export
-class GHDLException(GHDLBaseException):
- pass
diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py
index bf16b5c4b..a8249d38d 100644
--- a/pyGHDL/dom/DesignUnit.py
+++ b/pyGHDL/dom/DesignUnit.py
@@ -39,18 +39,26 @@ This module contains all DOM classes for VHDL's design units (:class:`context <E
"""
+from typing import List
+
+from pyGHDL.dom import DOMMixin
from pyGHDL.libghdl._types import Iir
from pydecor import export
from pyVHDLModel.VHDLModel import (
+ UseClause as VHDLModel_UseClause,
Entity as VHDLModel_Entity,
- EntityOrSymbol,
Architecture as VHDLModel_Architecture,
Package as VHDLModel_Package,
PackageBody as VHDLModel_PackageBody,
+ PackageInstantiation as VHDLModel_PackageInstantiation,
Context as VHDLModel_Context,
Configuration as VHDLModel_Configuration,
Component as VHDLModel_Component,
+ GenericInterfaceItem,
+ PortInterfaceItem,
+ EntityOrSymbol,
+ Name,
)
from pyGHDL.libghdl.vhdl import nodes
@@ -67,7 +75,35 @@ __all__ = []
@export
-class Entity(VHDLModel_Entity):
+class UseClause(VHDLModel_UseClause, DOMMixin):
+ def __init__(self, node: Iir, name: str):
+ super().__init__(name)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(cls, useNode: Iir):
+ from pyGHDL.dom._Translate import GetNameFromNode
+
+ selectedName = nodes.Get_Selected_Name(useNode)
+ name = GetNameFromNode(selectedName)
+
+ return cls(useNode, name)
+
+
+@export
+class Entity(VHDLModel_Entity, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ name: str,
+ genericItems: List[GenericInterfaceItem] = None,
+ portItems: List[PortInterfaceItem] = None,
+ declaredItems: List = None,
+ bodyItems: List["ConcurrentStatement"] = None,
+ ):
+ super().__init__(name, genericItems, portItems, declaredItems, bodyItems)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, entityNode: Iir):
name = GetNameOfNode(entityNode)
@@ -78,55 +114,102 @@ class Entity(VHDLModel_Entity):
)
bodyItems = []
- return cls(name, generics, ports, declaredItems, bodyItems)
+ return cls(entityNode, name, generics, ports, declaredItems, bodyItems)
@export
-class Architecture(VHDLModel_Architecture):
+class Architecture(VHDLModel_Architecture, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ name: str,
+ entity: EntityOrSymbol,
+ declaredItems: List = None,
+ bodyItems: List["ConcurrentStatement"] = None,
+ ):
+ super().__init__(name, entity, declaredItems, bodyItems)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, architectureNode: Iir):
name = GetNameOfNode(architectureNode)
- entityName = GetNameOfNode(nodes.Get_Entity_Name(architectureNode))
- entity = EntitySymbol(entityName)
+ entityNameNode = nodes.Get_Entity_Name(architectureNode)
+ entityName = GetNameOfNode(entityNameNode)
+ entity = EntitySymbol(entityNameNode, entityName)
declaredItems = GetDeclaredItemsFromChainedNodes(
nodes.Get_Declaration_Chain(architectureNode), "architecture", name
)
bodyItems = []
- return cls(name, entity, declaredItems, bodyItems)
+ return cls(architectureNode, name, entity, declaredItems, bodyItems)
def resolve(self):
pass
@export
-class Component(VHDLModel_Component):
+class Component(VHDLModel_Component, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ name: str,
+ genericItems: List[GenericInterfaceItem] = None,
+ portItems: List[PortInterfaceItem] = None,
+ ):
+ super().__init__(name, genericItems, portItems)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, componentNode: Iir):
name = GetNameOfNode(componentNode)
generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(componentNode))
ports = GetPortsFromChainedNodes(nodes.Get_Port_Chain(componentNode))
- return cls(name, generics, ports)
+ return cls(componentNode, name, generics, ports)
@export
-class Package(VHDLModel_Package):
+class Package(VHDLModel_Package, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ name: str,
+ genericItems: List[GenericInterfaceItem] = None,
+ declaredItems: List = None,
+ ):
+ super().__init__(name, genericItems, declaredItems)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, packageNode: Iir):
name = GetNameOfNode(packageNode)
- generics = (
- None # GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(packageNode))
- )
+
+ packageHeader = nodes.Get_Package_Header(packageNode)
+ if packageHeader is not nodes.Null_Iir:
+ generics = GetGenericsFromChainedNodes(
+ nodes.Get_Generic_Chain(packageHeader)
+ )
+ else:
+ generics = []
+
declaredItems = GetDeclaredItemsFromChainedNodes(
nodes.Get_Declaration_Chain(packageNode), "package", name
)
- return cls(name, generics, declaredItems)
+ return cls(packageNode, name, generics, declaredItems)
@export
-class PackageBody(VHDLModel_PackageBody):
+class PackageBody(VHDLModel_PackageBody, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ name: str,
+ declaredItems: List = None,
+ ):
+ super().__init__(name, declaredItems)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, packageBodyNode: Iir):
name = GetNameOfNode(packageBodyNode)
@@ -134,20 +217,65 @@ class PackageBody(VHDLModel_PackageBody):
nodes.Get_Declaration_Chain(packageBodyNode), "package", name
)
- return cls(name, declaredItems)
+ return cls(packageBodyNode, name, declaredItems)
+
+
+@export
+class PackageInstantiation(VHDLModel_PackageInstantiation, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ name: str,
+ uninstantiatedPackageName: Name,
+ # genericItems: List[GenericInterfaceItem] = None,
+ ):
+ super().__init__(name, uninstantiatedPackageName)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(cls, packageNode: Iir):
+ name = GetNameOfNode(packageNode)
+ uninstantiatedPackageName = nodes.Get_Uninstantiated_Package_Name(packageNode)
+
+ # FIXME: read generics
+ # FIXME: read generic map
+
+ return cls(packageNode, name, uninstantiatedPackageName)
@export
-class Context(VHDLModel_Context):
+class Context(VHDLModel_Context, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ name: str,
+ ):
+ super().__init__(name)
+ DOMMixin.__init__(self, node)
+
@classmethod
- def parse(cls, libraryUnit: Iir):
- name = GetNameOfNode(libraryUnit)
- return cls(name)
+ def parse(cls, contextNode: Iir):
+ name = GetNameOfNode(contextNode)
+
+ # FIXME: read use clauses
+
+ return cls(contextNode, name)
@export
-class Configuration(VHDLModel_Configuration):
+class Configuration(VHDLModel_Configuration, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ name: str,
+ ):
+ super().__init__(name)
+ DOMMixin.__init__(self, node)
+
@classmethod
- def parse(cls, configuration: Iir):
- name = GetNameOfNode(configuration)
- return cls(name)
+ def parse(cls, configurationNode: Iir):
+ name = GetNameOfNode(configurationNode)
+
+ # FIXME: needs an implementation
+
+ return cls(configurationNode, name)
diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py
index b129e1ce5..b3256d551 100644
--- a/pyGHDL/dom/Expression.py
+++ b/pyGHDL/dom/Expression.py
@@ -34,6 +34,7 @@ from typing import List
from pydecor import export
+from pyGHDL.dom import DOMMixin, DOMException
from pyVHDLModel.VHDLModel import (
InverseExpression as VHDLModel_InverseExpression,
IdentityExpression as VHDLModel_IdentityExpression,
@@ -43,6 +44,9 @@ from pyVHDLModel.VHDLModel import (
TypeConversion as VHDLModel_TypeConversion,
FunctionCall as VHDLModel_FunctionCall,
QualifiedExpression as VHDLModel_QualifiedExpression,
+ RangeExpression as VHDLModel_RangeExpression,
+ AscendingRangeExpression as VHDLModel_AscendingRangeExpression,
+ DescendingRangeExpression as VHDLModel_DescendingRangeExpression,
AdditionExpression as VHDLModel_AdditionExpression,
SubtractionExpression as VHDLModel_SubtractionExpression,
ConcatenationExpression as VHDLModel_ConcatenationExpression,
@@ -76,9 +80,9 @@ from pyVHDLModel.VHDLModel import (
)
from pyGHDL.libghdl import utils
+from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.dom._Utils import GetIirKindOfNode
-from pyGHDL.dom.Common import DOMException
from pyGHDL.dom.Symbol import EnumerationLiteralSymbol, SimpleSubTypeSymbol
from pyGHDL.dom.Aggregates import (
OthersAggregateElement,
@@ -94,308 +98,435 @@ __all__ = []
class _ParseUnaryExpression:
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir):
from pyGHDL.dom._Translate import GetExpressionFromNode
operand = GetExpressionFromNode(nodes.Get_Operand(node))
- return cls(operand)
+ return cls(node, operand)
class _ParseBinaryExpression:
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir):
from pyGHDL.dom._Translate import GetExpressionFromNode
left = GetExpressionFromNode(nodes.Get_Left(node))
right = GetExpressionFromNode(nodes.Get_Right(node))
- return cls(left, right)
+ return cls(node, left, right)
@export
-class InverseExpression(VHDLModel_InverseExpression, _ParseUnaryExpression):
- def __init__(self, operand: Expression):
+class InverseExpression(VHDLModel_InverseExpression, DOMMixin, _ParseUnaryExpression):
+ def __init__(self, node: Iir, operand: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._operand = operand
@export
-class IdentityExpression(VHDLModel_IdentityExpression, _ParseUnaryExpression):
- def __init__(self, operand: Expression):
+class IdentityExpression(VHDLModel_IdentityExpression, DOMMixin, _ParseUnaryExpression):
+ def __init__(self, node: Iir, operand: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._operand = operand
@export
-class NegationExpression(VHDLModel_NegationExpression, _ParseUnaryExpression):
- def __init__(self, operand: Expression):
+class NegationExpression(VHDLModel_NegationExpression, DOMMixin, _ParseUnaryExpression):
+ def __init__(self, node: Iir, operand: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._operand = operand
@export
-class AbsoluteExpression(VHDLModel_AbsoluteExpression, _ParseUnaryExpression):
- def __init__(self, operand: Expression):
+class AbsoluteExpression(VHDLModel_AbsoluteExpression, DOMMixin, _ParseUnaryExpression):
+ def __init__(self, node: Iir, operand: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._operand = operand
@export
-class ParenthesisExpression(VHDLModel_ParenthesisExpression, _ParseUnaryExpression):
- def __init__(self, operand: Expression):
+class ParenthesisExpression(
+ VHDLModel_ParenthesisExpression, DOMMixin, _ParseUnaryExpression
+):
+ def __init__(self, node: Iir, operand: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._operand = operand
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir):
from pyGHDL.dom._Translate import GetExpressionFromNode
operand = GetExpressionFromNode(nodes.Get_Expression(node))
- return cls(operand)
+ return cls(node, operand)
@export
-class TypeConversion(VHDLModel_TypeConversion):
- def __init__(self, operand: Expression):
+class TypeConversion(VHDLModel_TypeConversion, DOMMixin):
+ def __init__(self, node: Iir, operand: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._operand = operand
@export
-class FunctionCall(VHDLModel_FunctionCall):
- def __init__(self, operand: Expression):
+class FunctionCall(VHDLModel_FunctionCall, DOMMixin):
+ def __init__(self, node: Iir, operand: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._operand = operand
+class RangeExpression(VHDLModel_RangeExpression, DOMMixin):
+ @classmethod
+ def parse(cls, node: Iir) -> "VHDLModel_RangeExpression":
+ from pyGHDL.dom._Translate import GetExpressionFromNode
+
+ direction = nodes.Get_Direction(node)
+ leftBound = GetExpressionFromNode(nodes.Get_Left_Limit_Expr(node))
+ rightBound = GetExpressionFromNode(nodes.Get_Right_Limit_Expr(node))
+
+ if not direction: # ascending
+ return AscendingRangeExpression(node, leftBound, rightBound)
+ else:
+ return DescendingRangeExpression(node, leftBound, rightBound)
+
+
+@export
+class AscendingRangeExpression(VHDLModel_AscendingRangeExpression, DOMMixin):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
+ super().__init__()
+ DOMMixin.__init__(self, node)
+
+ self._leftOperand = left
+ self._rightOperand = right
+
+
@export
-class AdditionExpression(VHDLModel_AdditionExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class DescendingRangeExpression(VHDLModel_DescendingRangeExpression, DOMMixin):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class SubtractionExpression(VHDLModel_SubtractionExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class AdditionExpression(
+ VHDLModel_AdditionExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
+ self._leftOperand = left
+ self._rightOperand = right
+
+
+@export
+class SubtractionExpression(
+ VHDLModel_SubtractionExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
+ super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
class ConcatenationExpression(
- VHDLModel_ConcatenationExpression, _ParseBinaryExpression
+ VHDLModel_ConcatenationExpression, DOMMixin, _ParseBinaryExpression
):
- def __init__(self, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class MultiplyExpression(VHDLModel_MultiplyExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class MultiplyExpression(
+ VHDLModel_MultiplyExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class DivisionExpression(VHDLModel_DivisionExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class DivisionExpression(
+ VHDLModel_DivisionExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class RemainderExpression(VHDLModel_RemainderExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class RemainderExpression(
+ VHDLModel_RemainderExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class ModuloExpression(VHDLModel_ModuloExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class ModuloExpression(VHDLModel_ModuloExpression, DOMMixin, _ParseBinaryExpression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
class ExponentiationExpression(
- VHDLModel_ExponentiationExpression, _ParseBinaryExpression
+ VHDLModel_ExponentiationExpression, DOMMixin, _ParseBinaryExpression
):
- def __init__(self, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class AndExpression(VHDLModel_AndExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class AndExpression(VHDLModel_AndExpression, DOMMixin, _ParseBinaryExpression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class NandExpression(VHDLModel_NandExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class NandExpression(VHDLModel_NandExpression, DOMMixin, _ParseBinaryExpression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class OrExpression(VHDLModel_OrExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class OrExpression(VHDLModel_OrExpression, DOMMixin, _ParseBinaryExpression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class NorExpression(VHDLModel_NorExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class NorExpression(VHDLModel_NorExpression, DOMMixin, _ParseBinaryExpression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class XorExpression(VHDLModel_XorExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class XorExpression(VHDLModel_XorExpression, DOMMixin, _ParseBinaryExpression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class XnorExpression(VHDLModel_XnorExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class XnorExpression(VHDLModel_XnorExpression, DOMMixin, _ParseBinaryExpression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class EqualExpression(VHDLModel_EqualExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class EqualExpression(VHDLModel_EqualExpression, DOMMixin, _ParseBinaryExpression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class UnequalExpression(VHDLModel_UnequalExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class UnequalExpression(VHDLModel_UnequalExpression, DOMMixin, _ParseBinaryExpression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class LessThanExpression(VHDLModel_LessThanExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class LessThanExpression(
+ VHDLModel_LessThanExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class LessEqualExpression(VHDLModel_LessEqualExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class LessEqualExpression(
+ VHDLModel_LessEqualExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class GreaterThanExpression(VHDLModel_GreaterThanExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class GreaterThanExpression(
+ VHDLModel_GreaterThanExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class GreaterEqualExpression(VHDLModel_GreaterEqualExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class GreaterEqualExpression(
+ VHDLModel_GreaterEqualExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
class ShiftRightLogicExpression(
- VHDLModel_ShiftRightLogicExpression, _ParseBinaryExpression
+ VHDLModel_ShiftRightLogicExpression, DOMMixin, _ParseBinaryExpression
):
- def __init__(self, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
class ShiftLeftLogicExpression(
- VHDLModel_ShiftLeftLogicExpression, _ParseBinaryExpression
+ VHDLModel_ShiftLeftLogicExpression, DOMMixin, _ParseBinaryExpression
):
- def __init__(self, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
class ShiftRightArithmeticExpression(
- VHDLModel_ShiftRightArithmeticExpression, _ParseBinaryExpression
+ VHDLModel_ShiftRightArithmeticExpression, DOMMixin, _ParseBinaryExpression
):
- def __init__(self, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
class ShiftLeftArithmeticExpression(
- VHDLModel_ShiftLeftArithmeticExpression, _ParseBinaryExpression
+ VHDLModel_ShiftLeftArithmeticExpression, DOMMixin, _ParseBinaryExpression
):
- def __init__(self, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class RotateRightExpression(VHDLModel_RotateRightExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class RotateRightExpression(
+ VHDLModel_RotateRightExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class RotateLeftExpression(VHDLModel_RotateLeftExpression, _ParseBinaryExpression):
- def __init__(self, left: Expression, right: Expression):
+class RotateLeftExpression(
+ VHDLModel_RotateLeftExpression, DOMMixin, _ParseBinaryExpression
+):
+ def __init__(self, node: Iir, left: Expression, right: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._leftOperand = left
self._rightOperand = right
@export
-class QualifiedExpression(VHDLModel_QualifiedExpression):
- def __init__(self, subType: SubTypeOrSymbol, operand: Expression):
+class QualifiedExpression(VHDLModel_QualifiedExpression, DOMMixin):
+ def __init__(self, node: Iir, subType: SubTypeOrSymbol, operand: Expression):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._subtype = subType
self._operand = operand
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir):
from pyGHDL.dom._Translate import GetExpressionFromNode, GetNameOfNode
typeMarkName = GetNameOfNode(nodes.Get_Type_Mark(node))
@@ -405,13 +536,15 @@ class QualifiedExpression(VHDLModel_QualifiedExpression):
@export
-class Aggregate(VHDLModel_Aggregate):
- def __init__(self, elements: List[AggregateElement]):
+class Aggregate(VHDLModel_Aggregate, DOMMixin):
+ def __init__(self, node: Iir, elements: List[AggregateElement]):
super().__init__()
+ DOMMixin.__init__(self, node)
+
self._elements = elements
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir):
from pyGHDL.dom._Translate import GetExpressionFromNode, GetRangeFromNode
choices = []
@@ -422,18 +555,18 @@ class Aggregate(VHDLModel_Aggregate):
value = GetExpressionFromNode(nodes.Get_Associated_Expr(item))
if kind == nodes.Iir_Kind.Choice_By_None:
- choices.append(SimpleAggregateElement(value))
+ choices.append(SimpleAggregateElement(item, value))
elif kind == nodes.Iir_Kind.Choice_By_Expression:
index = GetExpressionFromNode(nodes.Get_Choice_Expression(item))
- choices.append(IndexedAggregateElement(index, value))
+ choices.append(IndexedAggregateElement(item, index, value))
elif kind == nodes.Iir_Kind.Choice_By_Range:
r = GetRangeFromNode(nodes.Get_Choice_Range(item))
- choices.append(RangedAggregateElement(r, value))
+ choices.append(RangedAggregateElement(item, r, value))
elif kind == nodes.Iir_Kind.Choice_By_Name:
name = EnumerationLiteralSymbol(nodes.Get_Choice_Name(item))
- choices.append(NamedAggregateElement(name, value))
+ choices.append(NamedAggregateElement(item, name, value))
elif kind == nodes.Iir_Kind.Choice_By_Others:
- choices.append(OthersAggregateElement(value))
+ choices.append(OthersAggregateElement(item, value))
else:
raise DOMException(
"Unknown choice kind '{kindName}'({kind}) in aggregate '{aggr}'.".format(
@@ -441,4 +574,4 @@ class Aggregate(VHDLModel_Aggregate):
)
)
- return cls(choices)
+ return cls(node, choices)
diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py
index f720e69b4..df62c8256 100644
--- a/pyGHDL/dom/InterfaceItem.py
+++ b/pyGHDL/dom/InterfaceItem.py
@@ -38,13 +38,15 @@ from pyVHDLModel.VHDLModel import (
ParameterConstantInterfaceItem as VHDLModel_ParameterConstantInterfaceItem,
ParameterVariableInterfaceItem as VHDLModel_ParameterVariableInterfaceItem,
ParameterSignalInterfaceItem as VHDLModel_ParameterSignalInterfaceItem,
+ ParameterFileInterfaceItem as VHDLModel_ParameterFileInterfaceItem,
Mode,
SubTypeOrSymbol,
Expression,
)
+from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
-from pyGHDL.libghdl.vhdl.nodes import Null_Iir
+from pyGHDL.dom import DOMMixin
from pyGHDL.dom._Utils import GetNameOfNode, GetModeOfNode
from pyGHDL.dom._Translate import GetSubTypeIndicationFromNode, GetExpressionFromNode
@@ -53,132 +55,196 @@ __all__ = []
@export
-class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem):
+class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ name: str,
+ mode: Mode,
+ subType: SubTypeOrSymbol,
+ defaultExpression: Expression,
+ ):
+ super().__init__(name=name, mode=mode)
+ DOMMixin.__init__(self, node)
+
+ # TODO: move to model
+ self._subType = subType
+ self._defaultExpression = defaultExpression
+
@classmethod
- def parse(cls, generic):
- name = GetNameOfNode(generic)
- mode = GetModeOfNode(generic)
- subTypeIndication = GetSubTypeIndicationFromNode(generic, "generic", name)
- default = nodes.Get_Default_Value(generic)
+ def parse(cls, genericNode: Iir) -> "GenericConstantInterfaceItem":
+ name = GetNameOfNode(genericNode)
+ mode = GetModeOfNode(genericNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(genericNode, "generic", name)
+ default = nodes.Get_Default_Value(genericNode)
value = GetExpressionFromNode(default) if default else None
- return cls(name, mode, subTypeIndication, value)
+ return cls(genericNode, name, mode, subTypeIndication, value)
+
+@export
+class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, DOMMixin):
def __init__(
self,
+ node: Iir,
name: str,
mode: Mode,
subType: SubTypeOrSymbol,
- defaultExpression: Expression,
+ defaultExpression: Expression = None,
):
super().__init__(name=name, mode=mode)
+ DOMMixin.__init__(self, node)
+
+ # TODO: move to model
self._subType = subType
self._defaultExpression = defaultExpression
-
-@export
-class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem):
@classmethod
- def parse(cls, port):
- name = GetNameOfNode(port)
- mode = GetModeOfNode(port)
- subTypeIndication = GetSubTypeIndicationFromNode(port, "port", name)
+ def parse(cls, portNode: Iir) -> "PortSignalInterfaceItem":
+ name = GetNameOfNode(portNode)
+ mode = GetModeOfNode(portNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(portNode, "port", name)
- defaultValue = nodes.Get_Default_Value(port)
+ defaultValue = nodes.Get_Default_Value(portNode)
value = (
- GetExpressionFromNode(defaultValue) if defaultValue != Null_Iir else None
+ GetExpressionFromNode(defaultValue)
+ if defaultValue != nodes.Null_Iir
+ else None
)
- return cls(name, mode, subTypeIndication, value)
+ return cls(portNode, name, mode, subTypeIndication, value)
+
+@export
+class ParameterConstantInterfaceItem(
+ VHDLModel_ParameterConstantInterfaceItem, DOMMixin
+):
def __init__(
self,
+ node: Iir,
name: str,
mode: Mode,
subType: SubTypeOrSymbol,
defaultExpression: Expression = None,
):
- super().__init__(name=name, mode=mode)
+ super().__init__(name, mode)
+ DOMMixin.__init__(self, node)
+
+ # TODO: move to model
self._subType = subType
self._defaultExpression = defaultExpression
-
-@export
-class ParameterConstantInterfaceItem(VHDLModel_ParameterConstantInterfaceItem):
@classmethod
- def parse(cls, parameter):
- name = GetNameOfNode(parameter)
- mode = GetModeOfNode(parameter)
- subTypeIndication = GetSubTypeIndicationFromNode(parameter, "parameter", name)
+ def parse(cls, parameterNode: Iir) -> "ParameterConstantInterfaceItem":
+ name = GetNameOfNode(parameterNode)
+ mode = GetModeOfNode(parameterNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(
+ parameterNode, "parameter", name
+ )
- defaultValue = nodes.Get_Default_Value(parameter)
+ defaultValue = nodes.Get_Default_Value(parameterNode)
value = (
- GetExpressionFromNode(defaultValue) if defaultValue != Null_Iir else None
+ GetExpressionFromNode(defaultValue)
+ if defaultValue != nodes.Null_Iir
+ else None
)
- return cls(name, mode, subTypeIndication, value)
+ return cls(parameterNode, name, mode, subTypeIndication, value)
+
+@export
+class ParameterVariableInterfaceItem(
+ VHDLModel_ParameterVariableInterfaceItem, DOMMixin
+):
def __init__(
self,
+ node: Iir,
name: str,
mode: Mode,
subType: SubTypeOrSymbol,
defaultExpression: Expression = None,
):
- super().__init__(name=name, mode=mode)
+ super().__init__(name, mode)
+ DOMMixin.__init__(self, node)
+
+ # TODO: move to model
self._subType = subType
self._defaultExpression = defaultExpression
-
-@export
-class ParameterVariableInterfaceItem(VHDLModel_ParameterVariableInterfaceItem):
@classmethod
- def parse(cls, parameter):
- name = GetNameOfNode(parameter)
- mode = GetModeOfNode(parameter)
- subTypeIndication = GetSubTypeIndicationFromNode(parameter, "parameter", name)
+ def parse(cls, parameterNode: Iir) -> "ParameterVariableInterfaceItem":
+ name = GetNameOfNode(parameterNode)
+ mode = GetModeOfNode(parameterNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(
+ parameterNode, "parameter", name
+ )
- defaultValue = nodes.Get_Default_Value(parameter)
+ defaultValue = nodes.Get_Default_Value(parameterNode)
value = (
- GetExpressionFromNode(defaultValue) if defaultValue != Null_Iir else None
+ GetExpressionFromNode(defaultValue)
+ if defaultValue != nodes.Null_Iir
+ else None
)
- return cls(name, mode, subTypeIndication, value)
+ return cls(parameterNode, name, mode, subTypeIndication, value)
+
+@export
+class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem, DOMMixin):
def __init__(
self,
+ node: Iir,
name: str,
mode: Mode,
subType: SubTypeOrSymbol,
defaultExpression: Expression = None,
):
- super().__init__(name=name, mode=mode)
+ super().__init__(name, mode)
+ DOMMixin.__init__(self, node)
+
+ # TODO: move to model
self._subType = subType
self._defaultExpression = defaultExpression
-
-@export
-class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem):
@classmethod
- def parse(cls, parameter):
- name = GetNameOfNode(parameter)
- mode = GetModeOfNode(parameter)
- subTypeIndication = GetSubTypeIndicationFromNode(parameter, "parameter", name)
+ def parse(cls, parameterNode: Iir) -> "ParameterSignalInterfaceItem":
+ name = GetNameOfNode(parameterNode)
+ mode = GetModeOfNode(parameterNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(
+ parameterNode, "parameter", name
+ )
- defaultValue = nodes.Get_Default_Value(parameter)
+ defaultValue = nodes.Get_Default_Value(parameterNode)
value = (
- GetExpressionFromNode(defaultValue) if defaultValue != Null_Iir else None
+ GetExpressionFromNode(defaultValue)
+ if defaultValue != nodes.Null_Iir
+ else None
)
- return cls(name, mode, subTypeIndication, value)
+ return cls(parameterNode, name, mode, subTypeIndication, value)
+
+@export
+class ParameterFileInterfaceItem(VHDLModel_ParameterFileInterfaceItem, DOMMixin):
def __init__(
self,
+ node: Iir,
name: str,
mode: Mode,
subType: SubTypeOrSymbol,
- defaultExpression: Expression = None,
):
- super().__init__(name=name, mode=mode)
+ super().__init__(name, mode)
+ DOMMixin.__init__(self, node)
+
+ # TODO: move to model
self._subType = subType
- self._defaultExpression = defaultExpression
+
+ @classmethod
+ def parse(cls, parameterNode: Iir) -> "ParameterFileInterfaceItem":
+ name = GetNameOfNode(parameterNode)
+ mode = GetModeOfNode(parameterNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(
+ parameterNode, "parameter", name
+ )
+
+ return cls(parameterNode, name, mode, subTypeIndication)
diff --git a/pyGHDL/dom/Literal.py b/pyGHDL/dom/Literal.py
index a2e86b389..784039d45 100644
--- a/pyGHDL/dom/Literal.py
+++ b/pyGHDL/dom/Literal.py
@@ -30,10 +30,10 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from pyGHDL.libghdl._types import Iir
from pydecor import export
from pyVHDLModel.VHDLModel import (
+ NullLiteral as VHDLModel_NullLiteral,
EnumerationLiteral as VHDLModel_EnumerationLiteral,
IntegerLiteral as VHDLModel_IntegerLiteral,
FloatingPointLiteral as VHDLModel_FloatingPointLiteral,
@@ -43,71 +43,112 @@ from pyVHDLModel.VHDLModel import (
StringLiteral as VHDLModel_StringLiteral,
)
from pyGHDL.libghdl import name_table
+from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL.dom import DOMMixin
from pyGHDL.dom._Utils import GetNameOfNode
__all__ = []
@export
-class EnumerationLiteral(VHDLModel_EnumerationLiteral):
+class NullLiteral(VHDLModel_NullLiteral, DOMMixin):
+ def __init__(self, node: Iir):
+ super().__init__()
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(cls, node: Iir) -> "NullLiteral":
+ return cls(node)
+
+
+@export
+class EnumerationLiteral(VHDLModel_EnumerationLiteral, DOMMixin):
+ def __init__(self, node: Iir, value: str):
+ super().__init__(value)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, literalNode: Iir) -> "EnumerationLiteral":
literalName = GetNameOfNode(literalNode)
- return cls(literalName)
+ return cls(literalNode, literalName)
@export
-class IntegerLiteral(VHDLModel_IntegerLiteral):
+class IntegerLiteral(VHDLModel_IntegerLiteral, DOMMixin):
+ def __init__(self, node: Iir, value: int):
+ super().__init__(value)
+ DOMMixin.__init__(self, node)
+
@classmethod
- def parse(cls, node: Iir) -> "IntegerLiteral":
- value = nodes.Get_Value(node)
- return cls(value)
+ def parse(cls, literalNode: Iir) -> "IntegerLiteral":
+ value = nodes.Get_Value(literalNode)
+ return cls(literalNode, value)
@export
-class FloatingPointLiteral(VHDLModel_FloatingPointLiteral):
+class FloatingPointLiteral(VHDLModel_FloatingPointLiteral, DOMMixin):
+ def __init__(self, node: Iir, value: float):
+ super().__init__(value)
+ DOMMixin.__init__(self, node)
+
@classmethod
- def parse(cls, node: Iir) -> "FloatingPointLiteral":
- value = nodes.Get_Fp_Value(node)
- return cls(value)
+ def parse(cls, literalNode: Iir) -> "FloatingPointLiteral":
+ value = nodes.Get_Fp_Value(literalNode)
+ return cls(literalNode, value)
@export
-class PhysicalIntegerLiteral(VHDLModel_PhysicalIntegerLiteral):
+class PhysicalIntegerLiteral(VHDLModel_PhysicalIntegerLiteral, DOMMixin):
+ def __init__(self, node: Iir, value: int, unitName: str):
+ super().__init__(value, unitName)
+ DOMMixin.__init__(self, node)
+
@classmethod
- def parse(cls, node: Iir) -> "PhysicalIntegerLiteral":
- value = nodes.Get_Value(node)
- unit = nodes.Get_Unit_Name(node)
+ def parse(cls, literalNode: Iir) -> "PhysicalIntegerLiteral":
+ value = nodes.Get_Value(literalNode)
+ unit = nodes.Get_Unit_Name(literalNode)
unitName = GetNameOfNode(unit)
- return cls(value, unitName)
+ return cls(literalNode, value, unitName)
@export
-class PhysicalFloatingLiteral(VHDLModel_PhysicalFloatingLiteral):
+class PhysicalFloatingLiteral(VHDLModel_PhysicalFloatingLiteral, DOMMixin):
+ def __init__(self, node: Iir, value: int, unitName: float):
+ super().__init__(value, unitName)
+ DOMMixin.__init__(self, node)
+
@classmethod
- def parse(cls, node: Iir) -> "PhysicalFloatingLiteral":
- value = nodes.Get_Fp_Value(node)
- unit = nodes.Get_Unit_Name(node)
+ def parse(cls, literalNode: Iir) -> "PhysicalFloatingLiteral":
+ value = nodes.Get_Fp_Value(literalNode)
+ unit = nodes.Get_Unit_Name(literalNode)
unitName = GetNameOfNode(unit)
- return cls(value, unitName)
+ return cls(literalNode, value, unitName)
@export
-class CharacterLiteral(VHDLModel_CharacterLiteral):
+class CharacterLiteral(VHDLModel_CharacterLiteral, DOMMixin):
+ def __init__(self, node: Iir, value: str):
+ super().__init__(value)
+ DOMMixin.__init__(self, node)
+
@classmethod
- def parse(cls, node: Iir) -> "CharacterLiteral":
- identifier = nodes.Get_Identifier(node)
+ def parse(cls, literalNode: Iir) -> "CharacterLiteral":
+ identifier = nodes.Get_Identifier(literalNode)
value = name_table.Get_Character(identifier)
- return cls(value)
+ return cls(literalNode, value)
@export
-class StringLiteral(VHDLModel_StringLiteral):
+class StringLiteral(VHDLModel_StringLiteral, DOMMixin):
+ def __init__(self, node: Iir, value: str):
+ super().__init__(value)
+ DOMMixin.__init__(self, node)
+
@classmethod
- def parse(cls, node: Iir) -> "StringLiteral":
- stringID = nodes.Get_String8_Id(node)
+ def parse(cls, literalNode: Iir) -> "StringLiteral":
+ stringID = nodes.Get_String8_Id(literalNode)
value = name_table.Get_Name_Ptr(stringID)
- return cls(value)
+ return cls(literalNode, value)
diff --git a/pyGHDL/dom/Misc.py b/pyGHDL/dom/Misc.py
index 8bea6cf61..b80c64a82 100644
--- a/pyGHDL/dom/Misc.py
+++ b/pyGHDL/dom/Misc.py
@@ -40,36 +40,24 @@ from pydecor import export
from pyVHDLModel.VHDLModel import (
Alias as VHDLModel_Alias,
)
+from pyGHDL.libghdl._types import Iir
+from pyGHDL.dom._Utils import GetNameOfNode
+from pyGHDL.dom import DOMMixin
__all__ = []
@export
-class Position:
- _filename: str
- _line: int
- _column: int
-
- def __init__(self, filename: str, line: int, column: int):
- self._filename = filename
- self._line = line
- self._column = column
-
- @property
- def Filename(self):
- return self._filename
-
- @property
- def Line(self):
- return self._line
+class Alias(VHDLModel_Alias, DOMMixin):
+ def __init__(self, node: Iir, aliasName: str):
+ super().__init__(aliasName)
+ DOMMixin.__init__(self, node)
- @property
- def Column(self):
- return self._column
+ @classmethod
+ def parse(cls, node: Iir):
+ aliasName = GetNameOfNode(node)
+ # FIXME: add an implementation
-@export
-class Alias(VHDLModel_Alias):
- def __init__(self, aliasName: str):
- super().__init__(aliasName)
+ return cls(node, aliasName)
diff --git a/pyGHDL/dom/Names.py b/pyGHDL/dom/Names.py
new file mode 100644
index 000000000..fa53acae6
--- /dev/null
+++ b/pyGHDL/dom/Names.py
@@ -0,0 +1,99 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Package module: DOM: Interface items (e.g. generic or port)
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from typing import List
+
+from pyGHDL.libghdl._types import Iir
+from pydecor import export
+
+from pyVHDLModel.VHDLModel import (
+ SimpleName as VHDLModel_SimpleName,
+ ParenthesisName as VHDLModel_ParenthesisName,
+ IndexedName as VHDLModel_IndexedName,
+ SlicedName as VHDLModel_SlicedName,
+ SelectedName as VHDLModel_SelectedName,
+ AttributeName as VHDLModel_AttributeName,
+ AllName as VHDLModel_AllName,
+ Name,
+)
+from pyGHDL.dom import DOMMixin
+
+__all__ = []
+
+
+@export
+class SimpleName(VHDLModel_SimpleName, DOMMixin):
+ def __init__(self, node: Iir, name: str):
+ super().__init__(name)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class ParenthesisName(VHDLModel_ParenthesisName, DOMMixin):
+ def __init__(self, node: Iir, prefix: Name, associations: List):
+ super().__init__(prefix, associations)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class IndexedName(VHDLModel_IndexedName, DOMMixin):
+ def __init__(self, node: Iir, name: str):
+ super().__init__(name)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class SlicedName(VHDLModel_SlicedName, DOMMixin):
+ def __init__(self, node: Iir, name: str):
+ super().__init__(name)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class SelectedName(VHDLModel_SelectedName, DOMMixin):
+ def __init__(self, node: Iir, name: str, prefix: Name):
+ super().__init__(name, prefix)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class AttributeName(VHDLModel_AttributeName, DOMMixin):
+ def __init__(self, node: Iir, name: str, prefix: Name):
+ super().__init__(name, prefix)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class AllName(VHDLModel_AllName, DOMMixin):
+ def __init__(self, node: Iir, prefix: Name):
+ super().__init__(prefix)
+ DOMMixin.__init__(self, node)
diff --git a/pyGHDL/dom/NonStandard.py b/pyGHDL/dom/NonStandard.py
index 9e2950f03..1524b549f 100644
--- a/pyGHDL/dom/NonStandard.py
+++ b/pyGHDL/dom/NonStandard.py
@@ -35,6 +35,8 @@
.. todo::
Add a module documentation.
"""
+import ctypes
+import time
from pathlib import Path
from typing import Any
@@ -56,10 +58,11 @@ from pyGHDL.libghdl import (
errorout_memory,
LibGHDLException,
utils,
+ files_map_editor,
)
from pyGHDL.libghdl.vhdl import nodes, sem_lib, parse
+from pyGHDL.dom import DOMException
from pyGHDL.dom._Utils import GetIirKindOfNode, CheckForErrors
-from pyGHDL.dom.Common import DOMException
from pyGHDL.dom.DesignUnit import (
Entity,
Architecture,
@@ -67,6 +70,7 @@ from pyGHDL.dom.DesignUnit import (
PackageBody,
Context,
Configuration,
+ PackageInstantiation,
)
__all__ = []
@@ -104,33 +108,62 @@ class Library(VHDLModel_Library):
@export
class Document(VHDLModel_Document):
+ _filename: Path
__ghdlFileID: Any
__ghdlSourceFileEntry: Any
__ghdlFile: Any
- def __init__(self, path: Path = None, dontParse: bool = False):
+ __ghdlProcessingTime: float
+ __domTranslateTime: float
+
+ def __init__(
+ self,
+ path: Path,
+ sourceCode: str = None,
+ dontParse: bool = False,
+ dontTranslate: bool = False,
+ ):
super().__init__(path)
- self.__ghdl_init()
- if dontParse == False:
- self.parse()
+ self._filename = path
- def __ghdl_init(self):
- # Read input file
- self.__ghdlFileID = name_table.Get_Identifier(str(self.Path))
- self.__ghdlSourceFileEntry = files_map.Read_Source_File(
- name_table.Null_Identifier, self.__ghdlFileID
- )
- if self.__ghdlSourceFileEntry == files_map.No_Source_File_Entry:
- raise LibGHDLException("Cannot load file '{!s}'".format(self.Path))
+ if sourceCode is None:
+ self.__loadFromPath()
+ else:
+ self.__loadFromString(sourceCode)
- CheckForErrors()
+ if dontParse == False:
+ # Parse input file
+ t1 = time.perf_counter()
+ self.__ghdlFile = sem_lib.Load_File(self.__ghdlSourceFileEntry)
+ CheckForErrors()
+ self.__ghdlProcessingTime = time.perf_counter() - t1
+
+ if dontTranslate == False:
+ t1 = time.perf_counter()
+ self.translate()
+ self.__domTranslateTime = time.perf_counter() - t1
+
+ def __loadFromPath(self):
+ with self._filename.open("r", encoding="utf-8") as file:
+ self.__loadFromString(file.read())
+
+ def __loadFromString(self, sourceCode: str):
+ sourcesBytes = sourceCode.encode("utf-8")
+ sourceLength = len(sourcesBytes)
+ bufferLength = sourceLength + 128
+ self.__ghdlFileID = name_table.Get_Identifier(str(self._filename))
+ dirId = name_table.Null_Identifier
+ self.__ghdlSourceFileEntry = files_map.Reserve_Source_File(
+ dirId, self.__ghdlFileID, bufferLength
+ )
+ files_map_editor.Fill_Text(
+ self.__ghdlSourceFileEntry, ctypes.c_char_p(sourcesBytes), sourceLength
+ )
- # Parse input file
- self.__ghdlFile = sem_lib.Load_File(self.__ghdlSourceFileEntry)
CheckForErrors()
- def parse(self):
+ def translate(self):
firstUnit = nodes.Get_First_Design_Unit(self.__ghdlFile)
for unit in utils.chain_iter(firstUnit):
@@ -153,6 +186,10 @@ class Document(VHDLModel_Document):
packageBody = PackageBody.parse(libraryUnit)
self.PackageBodies.append(packageBody)
+ elif nodeKind == nodes.Iir_Kind.Package_Instantiation_Declaration:
+ package = PackageInstantiation.parse(libraryUnit)
+ self.Packages.append(package)
+
elif nodeKind == nodes.Iir_Kind.Context_Declaration:
context = Context.parse(libraryUnit)
self.Contexts.append(context)
@@ -167,3 +204,11 @@ class Document(VHDLModel_Document):
kindName=nodeKind.name, kind=nodeKind
)
)
+
+ @property
+ def LibGHDLProcessingTime(self) -> float:
+ return self.__ghdlProcessingTime
+
+ @property
+ def DOMTranslationTime(self) -> float:
+ return self.__domTranslateTime
diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py
index a5ea4b1ff..3085f9f81 100644
--- a/pyGHDL/dom/Object.py
+++ b/pyGHDL/dom/Object.py
@@ -30,114 +30,183 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from pyGHDL.libghdl.vhdl import nodes
+from typing import Union
+
+from pyGHDL.libghdl._types import Iir
from pydecor import export
-from pyGHDL.dom._Translate import GetSubTypeIndicationFromNode, GetExpressionFromNode
-from pyGHDL.dom._Utils import GetNameOfNode
from pyVHDLModel.VHDLModel import (
Constant as VHDLModel_Constant,
DeferredConstant as VHDLModel_DeferredConstant,
Variable as VHDLModel_Variable,
SharedVariable as VHDLModel_SharedVariable,
Signal as VHDLModel_Signal,
+ File as VHDLModel_File,
Expression,
SubTypeOrSymbol,
)
+from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL.dom import DOMMixin
+from pyGHDL.dom._Utils import GetNameOfNode
+
__all__ = []
@export
-class Constant(VHDLModel_Constant):
+class Constant(VHDLModel_Constant, DOMMixin):
def __init__(
- self, name: str, subType: SubTypeOrSymbol, defaultExpression: Expression
+ self,
+ node: Iir,
+ name: str,
+ subType: SubTypeOrSymbol,
+ defaultExpression: Expression,
):
super().__init__(name)
+ DOMMixin.__init__(self, node)
self._name = name
self._subType = subType
self._defaultExpression = defaultExpression
@classmethod
- def parse(cls, node):
- name = GetNameOfNode(node)
- subTypeIndication = GetSubTypeIndicationFromNode(node, "constant", name)
- defaultExpression = GetExpressionFromNode(nodes.Get_Default_Value(node))
+ def parse(cls, constantNode: Iir) -> Union["Constant", "DeferredConstant"]:
+ from pyGHDL.dom._Translate import (
+ GetSubTypeIndicationFromNode,
+ GetExpressionFromNode,
+ )
- return cls(name, subTypeIndication, defaultExpression)
+ name = GetNameOfNode(constantNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(constantNode, "constant", name)
+ defaultValue = nodes.Get_Default_Value(constantNode)
+ if defaultValue != nodes.Null_Iir:
+ defaultExpression = GetExpressionFromNode(defaultValue)
+
+ return cls(constantNode, name, subTypeIndication, defaultExpression)
+ else:
+ return DeferredConstant(constantNode, name, subTypeIndication)
@export
-class DeferredConstant(VHDLModel_DeferredConstant):
- def __init__(self, name: str, subType: SubTypeOrSymbol):
+class DeferredConstant(VHDLModel_DeferredConstant, DOMMixin):
+ def __init__(self, node: Iir, name: str, subType: SubTypeOrSymbol):
super().__init__(name)
+ DOMMixin.__init__(self, node)
self._name = name
self._subType = subType
@classmethod
- def parse(cls, node):
- name = GetNameOfNode(node)
+ def parse(cls, constantNode: Iir) -> "DeferredConstant":
+ from pyGHDL.dom._Translate import GetSubTypeIndicationFromNode
+
+ name = GetNameOfNode(constantNode)
subTypeIndication = GetSubTypeIndicationFromNode(
- node, "deferred constant", name
+ constantNode, "deferred constant", name
)
- return cls(name, subTypeIndication)
+ return cls(constantNode, name, subTypeIndication)
@export
-class Variable(VHDLModel_Variable):
+class Variable(VHDLModel_Variable, DOMMixin):
def __init__(
- self, name: str, subType: SubTypeOrSymbol, defaultExpression: Expression
+ self,
+ node: Iir,
+ name: str,
+ subType: SubTypeOrSymbol,
+ defaultExpression: Expression,
):
super().__init__(name)
+ DOMMixin.__init__(self, node)
self._name = name
self._subType = subType
self._defaultExpression = defaultExpression
@classmethod
- def parse(cls, node):
- name = GetNameOfNode(node)
- subTypeIndication = GetSubTypeIndicationFromNode(node, "variable", name)
- defaultExpression = GetExpressionFromNode(nodes.Get_Default_Value(node))
+ def parse(cls, variableNode: Iir) -> "Variable":
+ from pyGHDL.dom._Translate import (
+ GetSubTypeIndicationFromNode,
+ GetExpressionFromNode,
+ )
- return cls(name, subTypeIndication, defaultExpression)
+ name = GetNameOfNode(variableNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(variableNode, "variable", name)
+ defaultValue = nodes.Get_Default_Value(variableNode)
+ defaultExpression = None
+ if defaultValue != nodes.Null_Iir:
+ defaultExpression = GetExpressionFromNode(defaultValue)
+
+ return cls(variableNode, name, subTypeIndication, defaultExpression)
@export
-class SharedVariable(VHDLModel_SharedVariable):
- def __init__(self, name: str, subType: SubTypeOrSymbol):
+class SharedVariable(VHDLModel_SharedVariable, DOMMixin):
+ def __init__(self, node: Iir, name: str, subType: SubTypeOrSymbol):
super().__init__(name)
+ DOMMixin.__init__(self, node)
self._name = name
self._subType = subType
@classmethod
- def parse(cls, node):
- name = GetNameOfNode(node)
- subTypeIndication = GetSubTypeIndicationFromNode(node, "variable", name)
+ def parse(cls, variableNode: Iir) -> "SharedVariable":
+ from pyGHDL.dom._Translate import GetSubTypeIndicationFromNode
+
+ name = GetNameOfNode(variableNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(variableNode, "variable", name)
- return cls(name, subTypeIndication)
+ return cls(variableNode, name, subTypeIndication)
@export
-class Signal(VHDLModel_Signal):
+class Signal(VHDLModel_Signal, DOMMixin):
def __init__(
- self, name: str, subType: SubTypeOrSymbol, defaultExpression: Expression
+ self,
+ node: Iir,
+ name: str,
+ subType: SubTypeOrSymbol,
+ defaultExpression: Expression,
):
super().__init__(name)
+ DOMMixin.__init__(self, node)
self._name = name
self._subType = subType
self._defaultExpression = defaultExpression
@classmethod
- def parse(cls, node):
- name = GetNameOfNode(node)
- subTypeIndication = GetSubTypeIndicationFromNode(node, "signal", name)
- default = nodes.Get_Default_Value(node)
+ def parse(cls, signalNode: Iir) -> "Signal":
+ from pyGHDL.dom._Translate import (
+ GetSubTypeIndicationFromNode,
+ GetExpressionFromNode,
+ )
+
+ name = GetNameOfNode(signalNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(signalNode, "signal", name)
+ default = nodes.Get_Default_Value(signalNode)
defaultExpression = GetExpressionFromNode(default) if default else None
- return cls(name, subTypeIndication, defaultExpression)
+ return cls(signalNode, name, subTypeIndication, defaultExpression)
+
+
+@export
+class File(VHDLModel_File, DOMMixin):
+ def __init__(self, node: Iir, name: str, subType: SubTypeOrSymbol):
+ super().__init__(name)
+ DOMMixin.__init__(self, node)
+
+ self._name = name
+ self._subType = subType
+
+ @classmethod
+ def parse(cls, fileNode: Iir) -> "File":
+ from pyGHDL.dom._Translate import GetSubTypeIndicationFromNode
+
+ name = GetNameOfNode(fileNode)
+ subTypeIndication = GetSubTypeIndicationFromNode(fileNode, "file", name)
+
+ # FIXME: handle file open stuff
+
+ return cls(fileNode, name, subTypeIndication)
diff --git a/pyGHDL/dom/Range.py b/pyGHDL/dom/Range.py
index 1a5ac518c..d091be1c6 100644
--- a/pyGHDL/dom/Range.py
+++ b/pyGHDL/dom/Range.py
@@ -50,11 +50,3 @@ class Range(VHDLModel_Range):
self._leftBound = left
self._rightBound = right
self._direction = direction
-
-
-@export
-class RangeExpression(VHDLModel_RangeExpression):
- def __init__(self, range: Range):
- super().__init__()
-
- self._range = range
diff --git a/pyGHDL/dom/Subprogram.py b/pyGHDL/dom/Subprogram.py
index 0f10ebf62..42e3c7d79 100644
--- a/pyGHDL/dom/Subprogram.py
+++ b/pyGHDL/dom/Subprogram.py
@@ -32,11 +32,8 @@
# ============================================================================
from typing import List
-from pyGHDL.dom.Symbol import SimpleSubTypeSymbol
-from pyGHDL.libghdl.vhdl import nodes
from pydecor import export
-from pyGHDL.dom._Utils import GetNameOfNode
from pyVHDLModel.VHDLModel import (
Function as VHDLModel_Function,
Procedure as VHDLModel_Procedure,
@@ -45,19 +42,26 @@ from pyVHDLModel.VHDLModel import (
ParameterInterfaceItem,
)
from pyGHDL.libghdl._types import Iir
+from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL.dom import DOMMixin
+from pyGHDL.dom._Utils import GetNameOfNode
+from pyGHDL.dom.Symbol import SimpleSubTypeSymbol
@export
-class Function(VHDLModel_Function):
+class Function(VHDLModel_Function, DOMMixin):
def __init__(
self,
+ node: Iir,
functionName: str,
returnType: SubTypeOrSymbol,
genericItems: List[GenericInterfaceItem] = None,
parameterItems: List[ParameterInterfaceItem] = None,
):
super().__init__(functionName)
+ DOMMixin.__init__(self, node)
+ # TODO: move to model
self._genericItems = [] if genericItems is None else [g for g in genericItems]
self._parameterItems = (
[] if parameterItems is None else [p for p in parameterItems]
@@ -65,53 +69,56 @@ class Function(VHDLModel_Function):
self._returnType = returnType
@classmethod
- def parse(cls, node: Iir):
+ def parse(cls, functionNode: Iir) -> "Function":
from pyGHDL.dom._Translate import (
GetGenericsFromChainedNodes,
GetParameterFromChainedNodes,
)
- functionName = GetNameOfNode(node)
+ functionName = GetNameOfNode(functionNode)
- generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(node))
+ generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(functionNode))
parameters = GetParameterFromChainedNodes(
- nodes.Get_Interface_Declaration_Chain(node)
+ nodes.Get_Interface_Declaration_Chain(functionNode)
)
- returnType = nodes.Get_Return_Type_Mark(node)
+ returnType = nodes.Get_Return_Type_Mark(functionNode)
returnTypeName = GetNameOfNode(returnType)
- returnTypeSymbol = SimpleSubTypeSymbol(returnTypeName)
+ returnTypeSymbol = SimpleSubTypeSymbol(returnType, returnTypeName)
- return cls(functionName, returnTypeSymbol, generics, parameters)
+ return cls(functionNode, functionName, returnTypeSymbol, generics, parameters)
@export
-class Procedure(VHDLModel_Procedure):
+class Procedure(VHDLModel_Procedure, DOMMixin):
def __init__(
self,
+ node: Iir,
procedureName: str,
genericItems: List[GenericInterfaceItem] = None,
parameterItems: List[ParameterInterfaceItem] = None,
):
super().__init__(procedureName)
+ DOMMixin.__init__(self, node)
+ # TODO: move to model
self._genericItems = [] if genericItems is None else [g for g in genericItems]
self._parameterItems = (
[] if parameterItems is None else [p for p in parameterItems]
)
@classmethod
- def parse(cls, node: Iir):
+ def parse(cls, procedureNode: Iir) -> "Procedure":
from pyGHDL.dom._Translate import (
GetGenericsFromChainedNodes,
GetParameterFromChainedNodes,
)
- procedureName = GetNameOfNode(node)
+ procedureName = GetNameOfNode(procedureNode)
- generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(node))
+ generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(procedureNode))
parameters = GetParameterFromChainedNodes(
- nodes.Get_Interface_Declaration_Chain(node)
+ nodes.Get_Interface_Declaration_Chain(procedureNode)
)
- return cls(procedureName, generics, parameters)
+ return cls(procedureNode, procedureName, generics, parameters)
diff --git a/pyGHDL/dom/Symbol.py b/pyGHDL/dom/Symbol.py
index d6d348f14..85d1c637b 100644
--- a/pyGHDL/dom/Symbol.py
+++ b/pyGHDL/dom/Symbol.py
@@ -31,9 +31,9 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
from typing import List, Iterator
+
from pydecor import export
-from pyGHDL.dom.Range import Range
from pyVHDLModel.VHDLModel import (
EntitySymbol as VHDLModel_EntitySymbol,
SimpleSubTypeSymbol as VHDLModel_SimpleSubTypeSymbol,
@@ -43,91 +43,91 @@ from pyVHDLModel.VHDLModel import (
SimpleObjectOrFunctionCallSymbol as VHDLModel_SimpleObjectOrFunctionCallSymbol,
IndexedObjectOrFunctionCallSymbol as VHDLModel_IndexedObjectOrFunctionCallSymbol,
Constraint,
+ Name,
)
+from pyGHDL.libghdl._types import Iir
+from pyGHDL.dom import DOMMixin
+from pyGHDL.dom._Utils import GetNameOfNode
+from pyGHDL.dom.Range import Range
-from pyGHDL.libghdl import utils
-from pyGHDL.libghdl.vhdl import nodes
-from pyGHDL.dom._Utils import GetIirKindOfNode, GetNameOfNode
-from pyGHDL.dom.Common import DOMException
__all__ = []
@export
-class EntitySymbol(VHDLModel_EntitySymbol):
- def __init__(self, entityName: str):
+class EntitySymbol(VHDLModel_EntitySymbol, DOMMixin):
+ def __init__(self, node: Iir, entityName: str):
super().__init__(entityName)
+ DOMMixin.__init__(self, node)
@export
-class EnumerationLiteralSymbol(VHDLModel_EnumerationLiteralSymbol):
- def __init__(self, literalName: str):
+class EnumerationLiteralSymbol(VHDLModel_EnumerationLiteralSymbol, DOMMixin):
+ def __init__(self, node: Iir, literalName: str):
super().__init__(symbolName=literalName)
+ DOMMixin.__init__(self, node)
@export
-class SimpleSubTypeSymbol(VHDLModel_SimpleSubTypeSymbol):
- def __init__(self, subTypeName: str):
+class SimpleSubTypeSymbol(VHDLModel_SimpleSubTypeSymbol, DOMMixin):
+ def __init__(self, node: Iir, subTypeName: Name):
if isinstance(subTypeName, (List, Iterator)):
subTypeName = ".".join(subTypeName)
super().__init__(subTypeName=subTypeName)
+ DOMMixin.__init__(self, node)
@export
-class ConstrainedScalarSubTypeSymbol(VHDLModel_ConstrainedScalarSubTypeSymbol):
- def __init__(self, subTypeName: str, range: Range = None):
+class ConstrainedScalarSubTypeSymbol(
+ VHDLModel_ConstrainedScalarSubTypeSymbol, DOMMixin
+):
+ def __init__(self, node: Iir, subTypeName: str, range: Range = None):
super().__init__(subTypeName=subTypeName, range=range)
+ DOMMixin.__init__(self, node)
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir):
pass
@export
-class ConstrainedCompositeSubTypeSymbol(VHDLModel_ConstrainedCompositeSubTypeSymbol):
- def __init__(self, subTypeName: str, constraints: List[Constraint] = None):
+class ConstrainedCompositeSubTypeSymbol(
+ VHDLModel_ConstrainedCompositeSubTypeSymbol, DOMMixin
+):
+ def __init__(
+ self, node: Iir, subTypeName: str, constraints: List[Constraint] = None
+ ):
super().__init__(subTypeName=subTypeName, constraints=constraints)
+ DOMMixin.__init__(self, node)
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir):
pass
@export
-class SimpleObjectOrFunctionCallSymbol(VHDLModel_SimpleObjectOrFunctionCallSymbol):
+class SimpleObjectOrFunctionCallSymbol(
+ VHDLModel_SimpleObjectOrFunctionCallSymbol, DOMMixin
+):
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir):
name = GetNameOfNode(node)
return cls(name)
@export
-class IndexedObjectOrFunctionCallSymbol(VHDLModel_IndexedObjectOrFunctionCallSymbol):
- def __init__(self, name: str, associations: List):
+class IndexedObjectOrFunctionCallSymbol(
+ VHDLModel_IndexedObjectOrFunctionCallSymbol, DOMMixin
+):
+ def __init__(self, node: Iir, name: str):
super().__init__(objectName=name)
+ DOMMixin.__init__(self, node)
@classmethod
- def parse(cls, node):
- from pyGHDL.dom._Translate import GetExpressionFromNode
-
- prefix = nodes.Get_Prefix(node)
- name = GetNameOfNode(prefix)
-
- associations = []
- for item in utils.chain_iter(nodes.Get_Association_Chain(node)):
- kind = GetIirKindOfNode(item)
-
- if kind == nodes.Iir_Kind.Association_Element_By_Expression:
- actual = nodes.Get_Actual(item)
- expr = GetExpressionFromNode(actual)
+ def parse(cls, node: Iir):
+ from pyGHDL.dom._Translate import GetExpressionFromNode, GetNameFromNode
- associations.append(expr)
- else:
- raise DOMException(
- "Unknown association kind '{kindName}'({kind}) in array index/slice or function call '{node}'.".format(
- kind=kind, kindName=kind.name, node=node
- )
- )
+ name = GetNameFromNode(node)
- return cls(name, associations)
+ return cls(node, name)
diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py
index 2875f1bc2..db51f1c49 100644
--- a/pyGHDL/dom/Type.py
+++ b/pyGHDL/dom/Type.py
@@ -30,38 +30,41 @@
#
# 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 typing import List, Union, Iterator, Tuple
-from pyGHDL.libghdl._types import Iir
from pydecor import export
-from pyGHDL.dom.Range import Range
from pyVHDLModel.VHDLModel import (
+ PhysicalType as VHDLModel_PhysicalType,
IntegerType as VHDLModel_IntegerType,
EnumeratedType as VHDLModel_EnumeratedType,
ArrayType as VHDLModel_ArrayType,
RecordTypeElement as VHDLModel_RecordTypeElement,
RecordType as VHDLModel_RecordType,
AccessType as VHDLModel_AccessType,
+ FileType as VHDLModel_FileType,
+ ProtectedType as VHDLModel_ProtectedType,
+ ProtectedTypeBody as VHDLModel_ProtectedTypeBody,
SubType as VHDLModel_SubType,
+ SubTypeOrSymbol,
)
+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.dom.Symbol import SimpleSubTypeSymbol
+from pyGHDL.dom.Literal import EnumerationLiteral, PhysicalIntegerLiteral
+from pyGHDL.dom.Range import Range
+from pyGHDL.dom.Subprogram import Function, Procedure
@export
-class IntegerType(VHDLModel_IntegerType):
- def __init__(self, typeName: str, range: Range):
- super().__init__(typeName)
- self._leftBound = range.LeftBound
- self._rightBound = range.RightBound
-
+class EnumeratedType(VHDLModel_EnumeratedType, DOMMixin):
+ def __init__(self, node: Iir, name: str, literals: List[EnumerationLiteral]):
+ super().__init__(name, literals)
+ DOMMixin.__init__(self, node)
-@export
-class EnumeratedType(VHDLModel_EnumeratedType):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "EnumeratedType":
literals = []
@@ -70,11 +73,59 @@ class EnumeratedType(VHDLModel_EnumeratedType):
literal = EnumerationLiteral.parse(enumerationLiteral)
literals.append(literal)
- return cls(typeName, literals)
+ return cls(typeDefinitionNode, typeName, literals)
+
+
+@export
+class IntegerType(VHDLModel_IntegerType, DOMMixin):
+ def __init__(self, node: Iir, typeName: str, range: Range):
+ super().__init__(typeName)
+ DOMMixin.__init__(self, node)
+
+ self._leftBound = range.LeftBound
+ self._rightBound = range.RightBound
+
+
+@export
+class PhysicalType(VHDLModel_PhysicalType, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ typeName: str,
+ primaryUnit: str,
+ units: List[Tuple[str, PhysicalIntegerLiteral]],
+ ):
+ super().__init__(typeName, primaryUnit, units)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "PhysicalType":
+ primaryUnit = nodes.Get_Primary_Unit(typeDefinitionNode)
+ primaryUnitName = GetNameOfNode(primaryUnit)
+
+ units = []
+ for secondaryUnit in utils.chain_iter(nodes.Get_Unit_Chain(typeDefinitionNode)):
+ secondaryUnitName = GetNameOfNode(secondaryUnit)
+ if secondaryUnit == primaryUnit:
+ continue
+
+ physicalLiteral = PhysicalIntegerLiteral.parse(
+ nodes.Get_Physical_Literal(secondaryUnit)
+ )
+
+ units.append((secondaryUnitName, physicalLiteral))
+
+ return cls(typeDefinitionNode, typeName, primaryUnitName, units)
@export
-class ArrayType(VHDLModel_ArrayType):
+class ArrayType(VHDLModel_ArrayType, DOMMixin):
+ def __init__(
+ self, node: Iir, name: str, indices: List, elementSubType: SubTypeOrSymbol
+ ):
+ super().__init__(name, indices, elementSubType)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "ArrayType":
from pyGHDL.dom._Translate import (
@@ -103,11 +154,15 @@ class ArrayType(VHDLModel_ArrayType):
elementSubTypeIndication, "array declaration", typeName
)
- return cls(typeName, indices, elementSubType)
+ return cls(typeDefinitionNode, typeName, indices, elementSubType)
@export
-class RecordTypeElement(VHDLModel_RecordTypeElement):
+class RecordTypeElement(VHDLModel_RecordTypeElement, DOMMixin):
+ def __init__(self, node: Iir, name: str, subType: SubTypeOrSymbol):
+ super().__init__(name, subType)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, elementDeclarationNode: Iir) -> "RecordTypeElement":
from pyGHDL.dom._Translate import GetSubTypeIndicationFromNode
@@ -117,11 +172,15 @@ class RecordTypeElement(VHDLModel_RecordTypeElement):
elementDeclarationNode, "record element", elementName
)
- return cls(elementName, elementType)
+ return cls(elementDeclarationNode, elementName, elementType)
@export
-class RecordType(VHDLModel_RecordType):
+class RecordType(VHDLModel_RecordType, DOMMixin):
+ def __init__(self, node: Iir, name: str, elements: List[RecordTypeElement] = None):
+ super().__init__(name, elements)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "RecordType":
elements = []
@@ -130,11 +189,57 @@ class RecordType(VHDLModel_RecordType):
element = RecordTypeElement.parse(elementDeclaration)
elements.append(element)
- return cls(typeName, elements)
+ return cls(typeDefinitionNode, typeName, elements)
@export
-class AccessType(VHDLModel_AccessType):
+class ProtectedType(VHDLModel_ProtectedType, DOMMixin):
+ def __init__(self, node: Iir, name: str, methods: Union[List, Iterator] = None):
+ super().__init__(name, methods)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "ProtectedType":
+ # FIXME: change this to a generator
+ methods = []
+ for item in utils.chain_iter(nodes.Get_Declaration_Chain(typeDefinitionNode)):
+ kind = GetIirKindOfNode(item)
+ if kind == nodes.Iir_Kind.Function_Declaration:
+ methods.append(Function.parse(item))
+ elif kind == nodes.Iir_Kind.Procedure_Declaration:
+ methods.append(Procedure.parse(item))
+
+ return cls(typeDefinitionNode, typeName, methods)
+
+
+@export
+class ProtectedTypeBody(VHDLModel_ProtectedTypeBody, DOMMixin):
+ def __init__(
+ self, node: Iir, name: str, declaredItems: Union[List, Iterator] = None
+ ):
+ super().__init__(name, declaredItems)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(cls, protectedBodyNode: Iir) -> "ProtectedTypeBody":
+ from pyGHDL.dom._Translate import GetDeclaredItemsFromChainedNodes
+
+ typeName = GetNameOfNode(protectedBodyNode)
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ nodes.Get_Declaration_Chain(protectedBodyNode),
+ "protected type body",
+ typeName,
+ )
+
+ return cls(protectedBodyNode, typeName, declaredItems)
+
+
+@export
+class AccessType(VHDLModel_AccessType, DOMMixin):
+ def __init__(self, node: Iir, name: str, designatedSubType: SubTypeOrSymbol):
+ super().__init__(name, designatedSubType)
+ DOMMixin.__init__(self, node)
+
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "AccessType":
from pyGHDL.dom._Translate import GetSubTypeIndicationFromIndicationNode
@@ -146,10 +251,29 @@ class AccessType(VHDLModel_AccessType):
designatedSubtypeIndication, "access type", typeName
)
- return cls(typeName, designatedSubType)
+ return cls(typeDefinitionNode, typeName, designatedSubType)
+
+
+@export
+class FileType(VHDLModel_FileType, DOMMixin):
+ def __init__(self, node: Iir, name: str, designatedSubType: SubTypeOrSymbol):
+ super().__init__(name, designatedSubType)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "FileType":
+
+ designatedSubTypeMark = nodes.Get_File_Type_Mark(typeDefinitionNode)
+ designatedSubTypeName = GetNameOfNode(designatedSubTypeMark)
+ designatedSubType = SimpleSubTypeSymbol(
+ typeDefinitionNode, designatedSubTypeName
+ )
+
+ return cls(typeDefinitionNode, typeName, designatedSubType)
@export
-class SubType(VHDLModel_SubType):
- def __init__(self, subtypeName: str):
+class SubType(VHDLModel_SubType, DOMMixin):
+ def __init__(self, node: Iir, subtypeName: str):
super().__init__(subtypeName)
+ DOMMixin.__init__(self, node)
diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py
index cb9448f09..502a94ad3 100644
--- a/pyGHDL/dom/_Translate.py
+++ b/pyGHDL/dom/_Translate.py
@@ -34,6 +34,8 @@ from typing import List, Generator
from pydecor import export
+from pyGHDL.dom import Position, DOMException
+from pyGHDL.dom.Object import Variable
from pyVHDLModel.VHDLModel import (
Constraint,
Direction,
@@ -44,6 +46,7 @@ from pyVHDLModel.VHDLModel import (
PortInterfaceItem,
ParameterInterfaceItem,
ModelEntity,
+ Name,
)
from pyGHDL.libghdl import utils
@@ -52,10 +55,14 @@ from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.dom._Utils import (
GetNameOfNode,
GetIirKindOfNode,
- GetPositionOfNode,
- GetSelectedName,
)
-from pyGHDL.dom.Common import DOMException
+from pyGHDL.dom.Names import (
+ SimpleName,
+ SelectedName,
+ AttributeName,
+ ParenthesisName,
+ AllName,
+)
from pyGHDL.dom.Symbol import (
SimpleObjectOrFunctionCallSymbol,
SimpleSubTypeSymbol,
@@ -69,10 +76,13 @@ from pyGHDL.dom.Type import (
ArrayType,
RecordType,
EnumeratedType,
- RecordTypeElement,
AccessType,
+ ProtectedType,
+ ProtectedTypeBody,
+ FileType,
+ PhysicalType,
)
-from pyGHDL.dom.Range import Range, RangeExpression
+from pyGHDL.dom.Range import Range
from pyGHDL.dom.Literal import (
IntegerLiteral,
CharacterLiteral,
@@ -80,7 +90,7 @@ from pyGHDL.dom.Literal import (
StringLiteral,
PhysicalIntegerLiteral,
PhysicalFloatingLiteral,
- EnumerationLiteral,
+ NullLiteral,
)
from pyGHDL.dom.Expression import (
SubtractionExpression,
@@ -114,6 +124,7 @@ from pyGHDL.dom.Expression import (
ShiftRightArithmeticExpression,
RotateLeftExpression,
RotateRightExpression,
+ RangeExpression,
)
from pyGHDL.dom.Subprogram import Function, Procedure
from pyGHDL.dom.Misc import Alias
@@ -123,6 +134,52 @@ __all__ = []
@export
+def GetNameFromNode(node: Iir) -> Name:
+ kind = GetIirKindOfNode(node)
+ if kind == nodes.Iir_Kind.Simple_Name:
+ name = GetNameOfNode(node)
+ return SimpleName(node, name)
+ elif kind == nodes.Iir_Kind.Selected_Name:
+ name = GetNameOfNode(node)
+ prefixName = GetNameFromNode(nodes.Get_Prefix(node))
+ return SelectedName(node, name, prefixName)
+ elif kind == nodes.Iir_Kind.Attribute_Name:
+ name = GetNameOfNode(node)
+ prefixName = GetNameFromNode(nodes.Get_Prefix(node))
+ return AttributeName(node, name, prefixName)
+ elif kind == nodes.Iir_Kind.Parenthesis_Name:
+ prefixName = GetNameFromNode(nodes.Get_Prefix(node))
+ associations = GetAssociations(node)
+
+ return ParenthesisName(node, prefixName, associations)
+ elif kind == nodes.Iir_Kind.Selected_By_All_Name:
+ prefixName = GetNameFromNode(nodes.Get_Prefix(node))
+ return AllName(node, prefixName)
+ else:
+ raise DOMException("Unknown name kind '{kind}'".format(kind=kind.name))
+
+
+def GetAssociations(node: Iir) -> List:
+ associations = []
+ for item in utils.chain_iter(nodes.Get_Association_Chain(node)):
+ kind = GetIirKindOfNode(item)
+
+ if kind == nodes.Iir_Kind.Association_Element_By_Expression:
+ actual = nodes.Get_Actual(item)
+ expr = GetExpressionFromNode(actual)
+
+ associations.append(expr)
+ else:
+ raise DOMException(
+ "Unknown association kind '{kindName}'({kind}) in array index/slice or function call '{node}'.".format(
+ kind=kind, kindName=kind.name, node=node
+ )
+ )
+
+ return associations
+
+
+@export
def GetArrayConstraintsFromSubtypeIndication(
subTypeIndication: Iir,
) -> List[Constraint]:
@@ -132,22 +189,19 @@ def GetArrayConstraintsFromSubtypeIndication(
):
constraintKind = GetIirKindOfNode(constraint)
if constraintKind == nodes.Iir_Kind.Range_Expression:
- constraints.append(RangeExpression(GetRangeFromNode(constraint)))
- elif constraintKind == nodes.Iir_Kind.Attribute_Name:
- name = GetNameOfNode(constraint)
- prefix = nodes.Get_Prefix(constraint)
- name2 = GetNameOfNode(prefix)
- kind2 = GetIirKindOfNode(prefix)
- print(name2, kind2, name)
-
- raise DOMException("[NOT IMPLEMENTED] Attribute name as range.")
- elif constraintKind == nodes.Iir_Kind.Simple_Name:
- raise DOMException("[NOT IMPLEMENTED] Subtype as range.")
+ constraints.append(RangeExpression.parse(constraint))
+ elif constraintKind in (
+ nodes.Iir_Kind.Simple_Name,
+ nodes.Iir_Kind.Parenthesis_Name,
+ nodes.Iir_Kind.Selected_Name,
+ nodes.Iir_Kind.Attribute_Name,
+ ):
+ constraints.append(GetNameFromNode(constraint))
else:
- position = GetPositionOfNode(constraint)
+ position = Position.parse(constraint)
raise DOMException(
"Unknown constraint kind '{kind}' for constraint '{constraint}' in subtype indication '{indication}' at {file}:{line}:{column}.".format(
- kind=constraintKind,
+ kind=constraintKind.name,
constraint=constraint,
indication=subTypeIndication,
file=position.Filename,
@@ -168,21 +222,27 @@ def GetTypeFromNode(node: Iir) -> BaseType:
if kind == nodes.Iir_Kind.Range_Expression:
r = GetRangeFromNode(typeDefinition)
- return IntegerType(typeName, r)
+ return IntegerType(node, typeName, r)
+ elif kind == nodes.Iir_Kind.Physical_Type_Definition:
+ return PhysicalType.parse(typeName, typeDefinition)
elif kind == nodes.Iir_Kind.Enumeration_Type_Definition:
return EnumeratedType.parse(typeName, typeDefinition)
elif kind == nodes.Iir_Kind.Array_Type_Definition:
return ArrayType.parse(typeName, typeDefinition)
elif kind == nodes.Iir_Kind.Array_Subtype_Definition:
- print("Array_Subtype_Definition")
+ print("[NOT IMPLEMENTED] Array_Subtype_Definition")
- return ArrayType
+ return ArrayType(typeDefinition, "????", [], None)
elif kind == nodes.Iir_Kind.Record_Type_Definition:
return RecordType.parse(typeName, typeDefinition)
elif kind == nodes.Iir_Kind.Access_Type_Definition:
return AccessType.parse(typeName, typeDefinition)
+ elif kind == nodes.Iir_Kind.File_Type_Definition:
+ return FileType.parse(typeName, typeDefinition)
+ elif kind == nodes.Iir_Kind.Protected_Type_Declaration:
+ return ProtectedType.parse(typeName, typeDefinition)
else:
- position = GetPositionOfNode(typeDefinition)
+ position = Position.parse(typeDefinition)
raise DOMException(
"Unknown type definition kind '{kindName}'({kind}) for type '{name}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -207,10 +267,19 @@ def GetSubTypeIndicationFromNode(node: Iir, entity: str, name: str) -> SubTypeOr
def GetSubTypeIndicationFromIndicationNode(
subTypeIndicationNode: Iir, entity: str, name: str
) -> SubTypeOrSymbol:
+ if subTypeIndicationNode is nodes.Null_Iir:
+ print(
+ "[NOT IMPLEMENTED]: Unhandled multiple declarations for {entity} '{name}'.".format(
+ entity=entity, name=name
+ )
+ )
+ return None
kind = GetIirKindOfNode(subTypeIndicationNode)
- if kind == nodes.Iir_Kind.Simple_Name:
- return GetSimpleTypeFromNode(subTypeIndicationNode)
- elif kind == nodes.Iir_Kind.Selected_Name:
+ if kind in (
+ nodes.Iir_Kind.Simple_Name,
+ nodes.Iir_Kind.Selected_Name,
+ nodes.Iir_Kind.Attribute_Name,
+ ):
return GetSimpleTypeFromNode(subTypeIndicationNode)
elif kind == nodes.Iir_Kind.Subtype_Definition:
return GetScalarConstrainedSubTypeFromNode(subTypeIndicationNode)
@@ -226,8 +295,8 @@ def GetSubTypeIndicationFromIndicationNode(
@export
def GetSimpleTypeFromNode(subTypeIndicationNode: Iir) -> SimpleSubTypeSymbol:
- subTypeName = GetSelectedName(subTypeIndicationNode)
- return SimpleSubTypeSymbol(subTypeName)
+ subTypeName = GetNameFromNode(subTypeIndicationNode)
+ return SimpleSubTypeSymbol(subTypeIndicationNode, subTypeName)
@export
@@ -238,7 +307,7 @@ def GetScalarConstrainedSubTypeFromNode(
typeMarkName = GetNameOfNode(typeMark)
rangeConstraint = nodes.Get_Range_Constraint(subTypeIndicationNode)
r = GetRangeFromNode(rangeConstraint)
- return ConstrainedScalarSubTypeSymbol(typeMarkName, r)
+ return ConstrainedScalarSubTypeSymbol(subTypeIndicationNode, typeMarkName, r)
@export
@@ -249,14 +318,16 @@ def GetCompositeConstrainedSubTypeFromNode(
typeMarkName = GetNameOfNode(typeMark)
constraints = GetArrayConstraintsFromSubtypeIndication(subTypeIndicationNode)
- return ConstrainedCompositeSubTypeSymbol(typeMarkName, constraints)
+ return ConstrainedCompositeSubTypeSymbol(
+ subTypeIndicationNode, typeMarkName, constraints
+ )
@export
-def GetSubTypeFromNode(node: Iir) -> SubTypeOrSymbol:
- subTypeName = GetNameOfNode(node)
+def GetSubTypeFromNode(subTypeNode: Iir) -> SubTypeOrSymbol:
+ subTypeName = GetNameOfNode(subTypeNode)
- return SubType(subTypeName)
+ return SubType(subTypeNode, subTypeName)
@export
@@ -274,7 +345,10 @@ def GetRangeFromNode(node: Iir) -> Range:
__EXPRESSION_TRANSLATION = {
nodes.Iir_Kind.Simple_Name: SimpleObjectOrFunctionCallSymbol,
+ nodes.Iir_Kind.Selected_Name: IndexedObjectOrFunctionCallSymbol,
+ nodes.Iir_Kind.Attribute_Name: IndexedObjectOrFunctionCallSymbol,
nodes.Iir_Kind.Parenthesis_Name: IndexedObjectOrFunctionCallSymbol,
+ nodes.Iir_Kind.Null_Literal: NullLiteral,
nodes.Iir_Kind.Integer_Literal: IntegerLiteral,
nodes.Iir_Kind.Floating_Point_Literal: FloatingPointLiteral,
nodes.Iir_Kind.Physical_Int_Literal: PhysicalIntegerLiteral,
@@ -282,6 +356,7 @@ __EXPRESSION_TRANSLATION = {
nodes.Iir_Kind.Character_Literal: CharacterLiteral,
nodes.Iir_Kind.String_Literal8: StringLiteral,
nodes.Iir_Kind.Negation_Operator: NegationExpression,
+ nodes.Iir_Kind.Range_Expression: RangeExpression,
nodes.Iir_Kind.Addition_Operator: AdditionExpression,
nodes.Iir_Kind.Concatenation_Operator: ConcatenationExpression,
nodes.Iir_Kind.Not_Operator: InverseExpression,
@@ -322,7 +397,7 @@ def GetExpressionFromNode(node: Iir) -> Expression:
try:
cls = __EXPRESSION_TRANSLATION[kind]
except KeyError:
- position = GetPositionOfNode(node)
+ position = Position.parse(node)
raise DOMException(
"Unknown expression kind '{kindName}'({kind}) in expression '{expr}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -346,11 +421,17 @@ def GetGenericsFromChainedNodes(
if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem
- genericConstant = GenericConstantInterfaceItem.parse(generic)
-
- yield genericConstant
+ yield GenericConstantInterfaceItem.parse(generic)
+ elif kind == nodes.Iir_Kind.Interface_Type_Declaration:
+ print("[NOT IMPLEMENTED] generic type")
+ elif kind == nodes.Iir_Kind.Interface_Package_Declaration:
+ print("[NOT IMPLEMENTED] generic package")
+ elif kind == nodes.Iir_Kind.Interface_Procedure_Declaration:
+ print("[NOT IMPLEMENTED] generic procedure")
+ elif kind == nodes.Iir_Kind.Interface_Function_Declaration:
+ print("[NOT IMPLEMENTED] generic function")
else:
- position = GetPositionOfNode(generic)
+ position = Position.parse(generic)
raise DOMException(
"Unknown generic kind '{kindName}'({kind}) in generic '{generic}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -376,7 +457,7 @@ def GetPortsFromChainedNodes(
yield portSignal
else:
- position = GetPositionOfNode(port)
+ position = Position.parse(port)
raise DOMException(
"Unknown port kind '{kindName}'({kind}) in port '{port}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -407,8 +488,12 @@ def GetParameterFromChainedNodes(
from pyGHDL.dom.InterfaceItem import ParameterSignalInterfaceItem
yield ParameterSignalInterfaceItem.parse(parameter)
+ elif kind == nodes.Iir_Kind.Interface_File_Declaration:
+ from pyGHDL.dom.InterfaceItem import ParameterFileInterfaceItem
+
+ yield ParameterFileInterfaceItem.parse(parameter)
else:
- position = GetPositionOfNode(parameter)
+ position = Position.parse(parameter)
raise DOMException(
"Unknown parameter kind '{kindName}'({kind}) in parameter '{param}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -437,11 +522,16 @@ def GetDeclaredItemsFromChainedNodes(
if nodes.Get_Shared_Flag(item):
yield SharedVariable.parse(item)
else:
- raise DOMException("Found non-shared variable.")
+ yield Variable.parse(item)
+ # raise DOMException("Found non-shared variable.")
elif kind == nodes.Iir_Kind.Signal_Declaration:
from pyGHDL.dom.Object import Signal
yield Signal.parse(item)
+ elif kind == nodes.Iir_Kind.File_Declaration:
+ from pyGHDL.dom.Object import File
+
+ yield File.parse(item)
elif kind == nodes.Iir_Kind.Type_Declaration:
yield GetTypeFromNode(item)
elif kind == nodes.Iir_Kind.Anonymous_Type_Declaration:
@@ -458,18 +548,41 @@ def GetDeclaredItemsFromChainedNodes(
elif kind == nodes.Iir_Kind.Procedure_Body:
# procedureName = NodeToName(item)
print("found procedure body '{name}'".format(name="????"))
+ 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_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
+ )
+ )
else:
- position = GetPositionOfNode(item)
+ position = Position.parse(item)
raise DOMException(
- "Unknown declared item kind '{kindName}'({kind}) in {entity} '{name}' at {file}:{line}:{column}.".format(
- kind=kind,
- kindName=kind.name,
+ "Unknown declared item kind '{kind}' in {entity} '{name}' at {file}:{line}:{column}.".format(
+ kind=kind.name,
entity=entity,
name=name,
file=position.Filename,
@@ -479,7 +592,7 @@ def GetDeclaredItemsFromChainedNodes(
)
-def GetAliasFromNode(node: Iir):
- aliasName = GetNameOfNode(node)
+def GetAliasFromNode(aliasNode: Iir):
+ aliasName = GetNameOfNode(aliasNode)
- return Alias(aliasName)
+ return Alias(aliasNode, aliasName)
diff --git a/pyGHDL/dom/_Utils.py b/pyGHDL/dom/_Utils.py
index 1c109c9dc..2b17d98ab 100644
--- a/pyGHDL/dom/_Utils.py
+++ b/pyGHDL/dom/_Utils.py
@@ -32,15 +32,13 @@
# ============================================================================
from pydecor import export
-from pyGHDL.dom.Common import DOMException
from pyVHDLModel.VHDLModel import Mode
from pyGHDL.libghdl import LibGHDLException, name_table, files_map, errorout_memory
from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.libghdl.vhdl.nodes import Null_Iir
from pyGHDL.libghdl._types import Iir
-from pyGHDL.dom.Misc import Position
-
+from pyGHDL.dom import DOMException
__all__ = []
@@ -60,7 +58,8 @@ def CheckForErrors() -> None:
if errorCount != 0:
for i in range(errorCount):
rec = errorout_memory.Get_Error_Record(i + 1)
- fileName = name_table.Get_Name_Ptr(files_map.Get_File_Name(rec.file))
+ # FIXME: needs help from @tgingold
+ fileName = "" # name_table.Get_Name_Ptr(files_map.Get_File_Name(rec.file))
message = errorout_memory.Get_Error_Message(i + 1)
errors.append(
@@ -77,9 +76,8 @@ def CheckForErrors() -> None:
@export
def GetIirKindOfNode(node: Iir) -> nodes.Iir_Kind:
"""Return the kind of a node in the IIR tree."""
-
if node == Null_Iir:
- raise ValueError("Parameter 'node' must not be 'Null_iir'.")
+ raise ValueError("GetIirKindOfNode: Parameter 'node' must not be 'Null_iir'.")
kind: int = nodes.Get_Kind(node)
return nodes.Iir_Kind(kind)
@@ -88,56 +86,20 @@ def GetIirKindOfNode(node: Iir) -> nodes.Iir_Kind:
@export
def GetNameOfNode(node: Iir) -> str:
"""Return the python string from node :obj:`node` identifier."""
-
if node == Null_Iir:
- raise ValueError("Parameter 'node' must not be 'Null_iir'.")
+ raise ValueError("GetNameOfNode: Parameter 'node' must not be 'Null_iir'.")
identifier = nodes.Get_Identifier(node)
return name_table.Get_Name_Ptr(identifier)
@export
-def GetSelectedName(node: Iir):
- names = []
- kind = GetIirKindOfNode(node)
- if kind == nodes.Iir_Kind.Simple_Name:
- return GetNameOfNode(node)
-
- while kind != nodes.Iir_Kind.Simple_Name:
- names.append(GetNameOfNode(node))
- node = nodes.Get_Prefix(node)
- kind = GetIirKindOfNode(node)
-
- names.append(GetNameOfNode(node))
-
- return reversed(names)
-
-
-@export
def GetModeOfNode(node: Iir) -> Mode:
"""Return the mode of a :obj:`node`."""
-
if node == Null_Iir:
- raise ValueError("Parameter 'node' must not be 'Null_iir'.")
+ raise ValueError("GetModeOfNode: Parameter 'node' must not be 'Null_iir'.")
try:
return __MODE_TRANSLATION[nodes.Get_Mode(node)]
except KeyError:
raise LibGHDLException("Unknown mode.")
-
-
-@export
-def GetPositionOfNode(node: Iir) -> Position:
- """Return the source code position of a IIR node."""
-
- if node == Null_Iir:
- raise ValueError("Parameter 'node' must not be 'Null_iir'.")
-
- location = nodes.Get_Location(node)
- file = files_map.Location_To_File(location)
- fileName = name_table.Get_Name_Ptr(files_map.Get_File_Name(file))
- # position = files_map.Location_File_To_Pos(location, file)
- line = files_map.Location_File_To_Line(location, file)
- column = files_map.Location_File_Line_To_Offset(location, file, line)
-
- return Position(fileName, line, column)
diff --git a/pyGHDL/dom/__init__.py b/pyGHDL/dom/__init__.py
index b4ffaf4c6..19f23a94b 100644
--- a/pyGHDL/dom/__init__.py
+++ b/pyGHDL/dom/__init__.py
@@ -30,5 +30,78 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
+from pathlib import Path
+
+from pyGHDL import GHDLBaseException
+from pyGHDL.libghdl import files_map, name_table
+
+from pyGHDL.libghdl.vhdl import nodes
+from pydecor import export
+
+from pyGHDL.libghdl._types import Iir
__all__ = []
+
+
+@export
+class Position:
+ """Represents the source code position of a IIR node in a source file."""
+
+ _filename: Path
+ _line: int
+ _column: int
+
+ def __init__(self, filename: Path, line: int, column: int):
+ self._filename = filename
+ self._line = line
+ self._column = column
+
+ @classmethod
+ def parse(cls, node: Iir) -> "Position":
+ """Return the source code position of a IIR node."""
+ if node == nodes.Null_Iir:
+ raise ValueError(
+ "Position.parse(): Parameter 'node' must not be 'Null_iir'."
+ )
+
+ location = nodes.Get_Location(node)
+ file = files_map.Location_To_File(location)
+ fileNameId = files_map.Get_File_Name(file)
+ fileName = name_table.Get_Name_Ptr(fileNameId)
+ line = files_map.Location_File_To_Line(location, file)
+ column = files_map.Location_File_Line_To_Offset(location, file, line)
+
+ return cls(Path(fileName), line, column)
+
+ @property
+ def Filename(self) -> Path:
+ return self._filename
+
+ @property
+ def Line(self) -> int:
+ return self._line
+
+ @property
+ def Column(self) -> int:
+ return self._column
+
+
+@export
+class DOMMixin:
+ _iirNode: Iir
+ _position: Position = None
+
+ def __init__(self, node: Iir):
+ self._iirNode = node
+
+ @property
+ def Position(self) -> Position:
+ if self._position is None:
+ self._position = Position.parse(self._iirNode)
+
+ return self._position
+
+
+@export
+class DOMException(GHDLBaseException):
+ pass
diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py
index 10def8503..f055f3f51 100644
--- a/pyGHDL/dom/formatting/prettyprint.py
+++ b/pyGHDL/dom/formatting/prettyprint.py
@@ -2,6 +2,7 @@ from typing import List, Union
from pydecor import export
+from pyGHDL.dom.Attribute import Attribute, AttributeSpecification
from pyGHDL.dom.Misc import Alias
from pyGHDL.dom.Subprogram import Procedure
from pyGHDL.dom.Type import (
@@ -11,6 +12,10 @@ from pyGHDL.dom.Type import (
RecordType,
AccessType,
EnumeratedType,
+ FileType,
+ ProtectedType,
+ ProtectedTypeBody,
+ PhysicalType,
)
from pyVHDLModel.VHDLModel import (
GenericInterfaceItem,
@@ -32,8 +37,10 @@ from pyGHDL.dom.DesignUnit import (
Configuration,
Context,
Component,
+ UseClause,
+ PackageInstantiation,
)
-from pyGHDL.dom.Object import Constant, Signal, SharedVariable
+from pyGHDL.dom.Object import Constant, Signal, SharedVariable, File
from pyGHDL.dom.InterfaceItem import (
GenericConstantInterfaceItem,
PortSignalInterfaceItem,
@@ -139,7 +146,15 @@ class PrettyPrint:
def formatEntity(self, entity: Entity, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
- buffer.append("{prefix}- Name: {name}".format(name=entity.Name, prefix=prefix))
+ buffer.append(
+ "{prefix}- Name: {name} at {file}:{line}:{column}".format(
+ name=entity.Name,
+ prefix=prefix,
+ file=entity.Position.Filename.name,
+ line=entity.Position.Line,
+ column=entity.Position.Column,
+ )
+ )
buffer.append("{prefix} Generics:".format(prefix=prefix))
for generic in entity.GenericItems:
for line in self.formatGeneric(generic, level + 1):
@@ -161,7 +176,13 @@ class PrettyPrint:
buffer = []
prefix = " " * level
buffer.append(
- "{prefix}- Name: {name}".format(name=architecture.Name, prefix=prefix)
+ "{prefix}- Name: {name} at {file}:{line}:{column}".format(
+ name=architecture.Name,
+ prefix=prefix,
+ file=architecture.Position.Filename.name,
+ line=architecture.Position.Line,
+ column=architecture.Position.Column,
+ )
)
buffer.append(
"{prefix} Entity: {entity}".format(
@@ -334,6 +355,16 @@ class PrettyPrint:
else "",
)
)
+ elif isinstance(item, File):
+ buffer.append(
+ "{prefix}- File {name} : {subtype}".format(
+ prefix=prefix,
+ name=item.Name,
+ subtype=self.formatSubtypeIndication(
+ item.SubType, "file", item.Name
+ ),
+ )
+ )
elif isinstance(item, Type):
buffer.append(
"{prefix}- {type}".format(prefix=prefix, type=self.formatType(item))
@@ -368,6 +399,32 @@ class PrettyPrint:
elif isinstance(item, Component):
for line in self.formatComponent(item, level):
buffer.append(line)
+ elif isinstance(item, Attribute):
+ buffer.append(
+ "{prefix}- attribute {name} : {type!s}".format(
+ prefix=prefix, name=item.Name, type=item.SubType
+ )
+ )
+ elif isinstance(item, AttributeSpecification):
+ buffer.append(
+ "{prefix}- attribute {name!s} of {entity} : {entityClass} is {value}".format(
+ prefix=prefix,
+ name=item.Attribute,
+ entity="????",
+ entityClass="????",
+ value="????",
+ )
+ )
+ elif isinstance(item, UseClause):
+ buffer.append(
+ "{prefix}- use {name!s}".format(prefix=prefix, name=item.Item)
+ )
+ elif isinstance(item, PackageInstantiation):
+ buffer.append(
+ "{prefix}- package {name} is new {name2!s} generic map (.....)".format(
+ prefix=prefix, name=item.Name, name2=item.PackageReference
+ )
+ )
else:
raise PrettyPrintException(
"Unhandled declared item kind '{name}'.".format(
@@ -385,12 +442,20 @@ class PrettyPrint:
)
elif isinstance(item, EnumeratedType):
result += "(........)"
+ elif isinstance(item, PhysicalType):
+ result += " is range ....... units ..... end units"
elif isinstance(item, ArrayType):
result += "array(........) of ....."
elif isinstance(item, RecordType):
result += "record ..... end record"
elif isinstance(item, AccessType):
result += "access ....."
+ elif isinstance(item, FileType):
+ result += "file ....."
+ elif isinstance(item, ProtectedType):
+ result += "protected ..... end protected"
+ elif isinstance(item, ProtectedTypeBody):
+ result += "protected body ..... end protected body"
else:
raise PrettyPrintException(
"Unknown type '{name}'".format(name=item.__class__.__name__)
@@ -402,11 +467,12 @@ class PrettyPrint:
if isinstance(subTypeIndication, SimpleSubTypeSymbol):
return "{type}".format(type=subTypeIndication.SymbolName)
elif isinstance(subTypeIndication, ConstrainedCompositeSubTypeSymbol):
- ranges = [str(c.Range) for c in subTypeIndication.Constraints]
- constraints = ", ".join(ranges)
+ constraints = []
+ for constraint in subTypeIndication.Constraints:
+ constraints.append(str(constraint))
return "{type}({constraints})".format(
- type=subTypeIndication.SymbolName, constraints=constraints
+ type=subTypeIndication.SymbolName, constraints=", ".join(constraints)
)
else:
raise PrettyPrintException(
diff --git a/pyGHDL/libghdl/__init__.py b/pyGHDL/libghdl/__init__.py
index 525710590..d23ffc0e7 100644
--- a/pyGHDL/libghdl/__init__.py
+++ b/pyGHDL/libghdl/__init__.py
@@ -87,7 +87,7 @@ def _check_libghdl_bindir(bindir: Path, basename: Path) -> Path:
def _get_libghdl_path():
- """
+ """\
Locate the directory where the shared library is installed.
Search order:
@@ -182,7 +182,7 @@ def initialize() -> None:
@export
# @BindToLibGHDL("libghdl__set_option")
def set_option(Opt: str) -> bool:
- """
+ """\
Set option :obj:`opt`.
:param Opt: Option to set.
@@ -195,7 +195,7 @@ def set_option(Opt: str) -> bool:
@export
# @BindToLibGHDL("libghdl__analyze_init")
def analyze_init() -> None:
- """
+ """\
Initialize the analyzer.
.. deprecated:: 1.0.0
@@ -207,7 +207,7 @@ def analyze_init() -> None:
@export
# @BindToLibGHDL("libghdl__analyze_init_status")
def analyze_init_status() -> int:
- """
+ """\
Initialize the analyzer.
:return: Returns 0 in case of success.
@@ -218,7 +218,7 @@ def analyze_init_status() -> int:
@export
# @BindToLibGHDL("libghdl__analyze_file")
def analyze_file(fname: str) -> Iir:
- """
+ """\
Analyze a given filename :obj:`fname`.
:param fname: File name
diff --git a/pyGHDL/libghdl/_decorator.py b/pyGHDL/libghdl/_decorator.py
index a680cc9d1..9c5aefa19 100644
--- a/pyGHDL/libghdl/_decorator.py
+++ b/pyGHDL/libghdl/_decorator.py
@@ -48,7 +48,7 @@ from typing import Callable, List, Dict, Any, TypeVar
from pydecor import export
-from pyGHDL.libghdl import libghdl
+from pyGHDL.libghdl import libghdl, LibGHDLException
@export
@@ -181,14 +181,34 @@ def BindToLibGHDL(subprogramName):
@wraps(func)
def inner(*args):
- return returnType(functionPointer(*args))
+ try:
+ returnValue = functionPointer(*args)
+ except OSError as ex:
+ errors = [str(ex)]
+ raise LibGHDLException(
+ "Caught exception when calling '{func}' in libghdl.".format(
+ func=subprogramName
+ ),
+ errors,
+ ) from ex
+
+ return returnType(returnValue)
return inner
else:
@wraps(func)
def inner(*args):
- return functionPointer(*args)
+ try:
+ return functionPointer(*args)
+ except OSError as ex:
+ errors = [str(ex)]
+ raise LibGHDLException(
+ "Caught exception when calling '{func}' in libghdl.".format(
+ func=subprogramName
+ ),
+ errors,
+ ) from ex
return inner
diff --git a/pyGHDL/libghdl/files_map_editor.py b/pyGHDL/libghdl/files_map_editor.py
index eceb3efe2..2009af882 100644
--- a/pyGHDL/libghdl/files_map_editor.py
+++ b/pyGHDL/libghdl/files_map_editor.py
@@ -32,7 +32,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from ctypes import c_int32, c_char_p, c_bool
+from ctypes import c_int32, c_char_p, c_bool, c_uint32
from pydecor import export
@@ -113,7 +113,7 @@ def Fill_Text(File: SourceFileEntry, Text_Pointer, Text_Length: int) -> None:
@export
# @BindToLibGHDL("files_map__editor__check_buffer_content")
def Check_Buffer_Content(
- File: SourceFileEntry, String_Pointer, String_Length: int
+ File: SourceFileEntry, String_Pointer: c_char_p, String_Length: c_uint32
) -> None:
"""
Check that content of :obj:`File` is STR[1 .. STR_LEN].
diff --git a/pyGHDL/requirements.txt b/pyGHDL/requirements.txt
index 6198d8044..974fef2ed 100644
--- a/pyGHDL/requirements.txt
+++ b/pyGHDL/requirements.txt
@@ -1,3 +1,3 @@
pydecor>=2.0.1
-pyVHDLModel==0.10.3
+pyVHDLModel==0.10.4
#https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel
diff --git a/setup.py b/setup.py
index 330247011..6b816f24b 100644
--- a/setup.py
+++ b/setup.py
@@ -50,6 +50,7 @@ packagePath = Path(packageName)
readmeFile = packagePath / "README.md"
requirementsFile = packagePath / "requirements.txt"
+
# Read (local) README for upload to PyPI
def get_description(file: Path) -> str:
with file.open("r") as fh:
@@ -80,7 +81,7 @@ def get_version():
match = pattern.match(line)
if match:
return match.group(1)
- except:
+ except Exception:
pass
raise Exception("Cannot find version")
diff --git a/testsuite/pyunit/Current.vhdl b/testsuite/pyunit/Current.vhdl
index ff03e1d04..a017b9f46 100644
--- a/testsuite/pyunit/Current.vhdl
+++ b/testsuite/pyunit/Current.vhdl
@@ -21,7 +21,8 @@ end entity entity_1;
architecture behav of entity_1 is
constant MAX : positive := -25;
signal rst : std_logic := foo('U');
--- signal vec : bit_vector(pack.input'bar'range);
+ signal vec : bit_vector(pack(3 to 2).signaal'range'value);
+ signal copy : input'subtype;
type newInt is range -4 to 3;
type newFp is range 4.3 downto -3.9;
@@ -34,9 +35,10 @@ architecture behav of entity_1 is
end record;
type enum is (e1, e2, e3);
type acc is access bar;
+ type fil is file of string;
subtype uint8 is integer range 0 to 255;
--- file f : text;
+ file f : text;
function func (a : integer; b : boolean) return bit is
begin
@@ -50,6 +52,27 @@ architecture behav of entity_1 is
end procedure;
+ type prot is protected
+ function meth(a : int) return bit;
+ end protected;
+
+ type prot is protected body
+ variable var : positive;
+ constant const : boolean;
+
+ function meth(a : int) return bit is
+ begin
+
+ end function;
+ end protected body;
+
+ package pack_inst is new generic_pack
+ generic map (
+ BITS => 32
+ );
+
+ attribute att : boolean;
+
alias bar is boolean;
begin
process(Clock)
@@ -65,7 +88,14 @@ begin
end architecture behav;
package package_1 is
+ generic (
+ BITS : positive
+ );
+
+ use lib.pack.all;
+
constant ghdl : float := (3, 5, 0 to 2 => 5, 3 => 4, name => 10); -- 2.3;
+ attribute fixed of ghdl : constant is true;
component comp is
port (
@@ -76,4 +106,12 @@ end package;
package body package_1 is
constant ghdl : float := (1); -- => 2, 4 => 5, others => 10); -- .5;
+
+ type CAPACITY is range 0 to 1E5 units
+ pF;
+ nF = 1000 pF;
+ uF = 1000 nF;
+ mF = 1000 uF;
+ F = 1000 mF;
+ end units;
end package body;
diff --git a/testsuite/pyunit/dom/Expressions.py b/testsuite/pyunit/dom/Expressions.py
index f9c066f52..4de36a2b2 100644
--- a/testsuite/pyunit/dom/Expressions.py
+++ b/testsuite/pyunit/dom/Expressions.py
@@ -30,17 +30,20 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
+import ctypes
+from inspect import currentframe
from pathlib import Path
from textwrap import dedent
from unittest import TestCase
-from pyGHDL.dom.DesignUnit import Package
from pyGHDL.dom import Expression
from pyGHDL.dom.NonStandard import Design, Document
+from pyGHDL.dom.DesignUnit import Package
from pyGHDL.dom.Symbol import SimpleObjectOrFunctionCallSymbol
from pyGHDL.dom.Object import Constant
-from pyGHDL.dom.Expression import InverseExpression
+from pyGHDL.dom.Expression import InverseExpression, AbsoluteExpression
+
if __name__ == "__main__":
print("ERROR: you called a testcase declaration file as an executable module.")
@@ -50,34 +53,60 @@ if __name__ == "__main__":
class Expressions(TestCase):
_root = Path(__file__).resolve().parent.parent
-
- def test_NotExpression(self):
- self._filename: Path = self._root / "{className}.vhdl".format(
- className=self.__class__.__name__
- )
-
- sourceCode = dedent(
+ _design = Design()
+ _packageTemplate = dedent(
"""\
package package_1 is
- constant c0 : boolean := not true;
+ {code}
end package;
"""
)
- with self._filename.open(mode="w", encoding="utf-8") as file:
- file.write(sourceCode)
+ def parse(self, filename: Path, code: str) -> Expression:
+ sourceCode = self._packageTemplate.format(code=code)
- design = Design()
- document = Document(self._filename)
- design.Documents.append(document)
+ document = Document(filename, sourceCode)
+ self._design.Documents.append(document)
- package: Package = design.Documents[0].Packages[0]
+ # Traverse already to default value expression
+ package: Package = document.Packages[0]
item: Constant = package.DeclaredItems[0]
default: Expression = item.DefaultExpression
+
+ return default
+
+ def test_NotExpression(self):
+ filename: Path = self._root / "{className}_{funcName}.vhdl".format(
+ className=self.__class__.__name__, funcName= currentframe().f_code.co_name[5:]
+ )
+
+ # Define test data
+ constantDeclartion = "constant c0 : boolean := not true;"
+
+ # Parse in-memory
+ default: Expression = self.parse(filename, constantDeclartion)
+
+ # Start checks
self.assertTrue(isinstance(default, InverseExpression))
self.assertTrue(isinstance(default.Operand, SimpleObjectOrFunctionCallSymbol))
self.assertTrue(default.Operand.SymbolName == "true")
+ # def test_AbsExpression(self):
+ # filename: Path = self._root / "{className}_{funcName}.vhdl".format(
+ # className=self.__class__.__name__, funcName= currentframe().f_code.co_name[5:]
+ # )
+ #
+ # # Define test data
+ # constantDeclartion = "constant c0 : integer := abs 3;"
+ #
+ # # Parse in-memory
+ # default: Expression = self.parse(filename, constantDeclartion)
+ #
+ # # Start checks
+ # self.assertTrue(isinstance(default, AbsoluteExpression))
+ # self.assertTrue(isinstance(default.Operand, SimpleObjectOrFunctionCallSymbol))
+ # self.assertTrue(default.Operand.SymbolName == "-3")
+
# def test_Aggregare(self):
# self._filename: Path = self._root / "{className}.vhdl".format(className=self.__class__.__name__)
#
diff --git a/testsuite/pyunit/dom/Literals.py b/testsuite/pyunit/dom/Literals.py
index ebd702f5e..a69481ef4 100644
--- a/testsuite/pyunit/dom/Literals.py
+++ b/testsuite/pyunit/dom/Literals.py
@@ -80,6 +80,6 @@ class Literals(TestCase):
item: Constant = package.DeclaredItems[i]
self.assertTrue(isinstance(item, Constant))
self.assertTrue(item.Name == "c{}".format(i))
- self.assertTrue(item.SubType.SymbolName == "integer")
+ self.assertTrue(str(item.SubType.SymbolName) == "integer")
self.assertTrue(isinstance(item.DefaultExpression, IntegerLiteral))
self.assertTrue(item.DefaultExpression.Value == expected[i])
diff --git a/testsuite/pyunit/dom/Sanity.py b/testsuite/pyunit/dom/Sanity.py
index 10258c38c..dc415446b 100644
--- a/testsuite/pyunit/dom/Sanity.py
+++ b/testsuite/pyunit/dom/Sanity.py
@@ -30,11 +30,13 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from sys import executable
-from subprocess import check_call, STDOUT
from pathlib import Path
+from subprocess import check_call, STDOUT
+
from pytest import mark
+from pyGHDL.dom.NonStandard import Design, Document
+
if __name__ == "__main__":
print("ERROR: you called a testcase declaration file as an executable module.")
print("Use: 'python -m unitest <testcase module>'")
@@ -44,7 +46,12 @@ _TESTSUITE_ROOT = Path(__file__).parent.parent.parent.resolve()
_GHDL_ROOT = _TESTSUITE_ROOT.parent
+design = Design()
+
@mark.xfail
-@mark.parametrize("file", [str(f) for f in _TESTSUITE_ROOT.glob("sanity/**/*.vhdl")])
+@mark.parametrize("file", [str(f.relative_to(_TESTSUITE_ROOT)) for f in _TESTSUITE_ROOT.glob("sanity/**/*.vhdl")])
def test_AllVHDLSources(file):
- check_call([executable, _GHDL_ROOT / "pyGHDL/cli/DOM.py", file], stderr=STDOUT)
+ check_call(["python", _GHDL_ROOT / "pyGHDL/cli/DOM.py", file], stderr=STDOUT)
+
+# document = Document(Path(file))
+# design.Documents.append(document)
diff --git a/testsuite/pyunit/lsp/LanguageServer.py b/testsuite/pyunit/lsp/LanguageServer.py
index a406dce91..51e26ca7d 100644
--- a/testsuite/pyunit/lsp/LanguageServer.py
+++ b/testsuite/pyunit/lsp/LanguageServer.py
@@ -8,6 +8,7 @@ from subprocess import run as subprocess_run, PIPE
from typing import Optional
from unittest import TestCase
+
from pyGHDL.lsp.lsp import LanguageProtocolServer, LSPConn
is_windows = os.name == "nt"