aboutsummaryrefslogtreecommitdiffstats
path: root/pyGHDL/dom
diff options
context:
space:
mode:
authorPatrick Lehmann <Patrick.Lehmann@plc2.de>2021-06-17 13:11:32 +0200
committertgingold <tgingold@users.noreply.github.com>2021-06-17 21:34:16 +0200
commit4ec5cdcd77aa1b6fc384197e1208061d62f16ba2 (patch)
tree3c386d35b39b001db4e128abda379ddeb5ba7b2c /pyGHDL/dom
parent1eea725dedae1fe3eee47c2b4bfc18c7ac35e806 (diff)
downloadghdl-4ec5cdcd77aa1b6fc384197e1208061d62f16ba2.tar.gz
ghdl-4ec5cdcd77aa1b6fc384197e1208061d62f16ba2.tar.bz2
ghdl-4ec5cdcd77aa1b6fc384197e1208061d62f16ba2.zip
Updates to the dom namespace in pyGHDL.
Diffstat (limited to 'pyGHDL/dom')
-rw-r--r--pyGHDL/dom/Common.py57
-rw-r--r--pyGHDL/dom/DesignUnit.py114
-rw-r--r--pyGHDL/dom/Expression.py287
-rw-r--r--pyGHDL/dom/InterfaceItem.py56
-rw-r--r--pyGHDL/dom/Literal.py55
-rw-r--r--pyGHDL/dom/Misc.py86
-rw-r--r--pyGHDL/dom/Object.py72
-rw-r--r--pyGHDL/dom/Range.py58
-rw-r--r--pyGHDL/dom/Symbol.py60
-rw-r--r--pyGHDL/dom/_Translate.py208
-rw-r--r--pyGHDL/dom/_Utils.py38
-rw-r--r--pyGHDL/dom/__init__.py20
-rw-r--r--pyGHDL/dom/formatting/__init__.py0
-rw-r--r--pyGHDL/dom/formatting/prettyprint.py296
14 files changed, 1239 insertions, 168 deletions
diff --git a/pyGHDL/dom/Common.py b/pyGHDL/dom/Common.py
index 646e074e5..88d0cdc8c 100644
--- a/pyGHDL/dom/Common.py
+++ b/pyGHDL/dom/Common.py
@@ -1,19 +1,19 @@
# =============================================================================
-# ____ _ _ ____ _ _
-# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
-# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
-# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
-# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-# |_| |___/
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
# =============================================================================
-# Authors:
-# Patrick Lehmann
+# Authors:
+# Patrick Lehmann
#
# Package module: DOM: Common classes for package pyGHDL.dom.
#
# License:
# ============================================================================
-# Copyright (C) 2019-2020 Tristan Gingold
+# 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
@@ -37,21 +37,14 @@
"""
from pydecor import export
-from pyVHDLModel.VHDLModel import Mode
-
-from pyGHDL.libghdl import name_table
-from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL import GHDLBaseException
+from pyGHDL.libghdl import LibGHDLException, errorout_memory
__all__ = []
@export
-class GHDLBaseException(Exception):
- pass
-
-
-@export
-class LibGHDLException(GHDLBaseException):
+class DOMException(GHDLBaseException):
pass
@@ -62,23 +55,11 @@ class GHDLException(GHDLBaseException):
@export
class GHDLMixin:
- _MODE_TRANSLATION = {
- nodes.Iir_Mode.In_Mode: Mode.In,
- nodes.Iir_Mode.Out_Mode: Mode.Out,
- nodes.Iir_Mode.Inout_Mode: Mode.InOut,
- nodes.Iir_Mode.Buffer_Mode: Mode.Buffer,
- nodes.Iir_Mode.Linkage_Mode: Mode.Linkage,
- }
-
- @classmethod
- def _ghdlNodeToName(cls, node) -> str:
- """Return the python string from node :obj:`node` identifier"""
- return name_table.Get_Name_Ptr(nodes.Get_Identifier(node))
+ def CheckForErrors(self) -> None:
+ errorCount = errorout_memory.Get_Nbr_Messages()
+ if errorCount != 0:
+ for i in range(errorCount):
+ print(errorout_memory.Get_Error_Message(i + 1))
- @classmethod
- def _ghdlPortToMode(cls, port):
- """Return the mode of a :obj:`port`."""
- try:
- return cls._MODE_TRANSLATION[nodes.Get_Mode(port)]
- except KeyError:
- raise LibGHDLException("Unknown mode.")
+ raise DOMException("Error in libghdl.") \
+ from LibGHDLException("libghdl: Internal error 2.")
diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py
index 4cf1ac2ad..9827cec24 100644
--- a/pyGHDL/dom/DesignUnit.py
+++ b/pyGHDL/dom/DesignUnit.py
@@ -1,19 +1,19 @@
# =============================================================================
-# ____ _ _ ____ _ _
-# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
-# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
-# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
-# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-# |_| |___/
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
# =============================================================================
-# Authors:
-# Patrick Lehmann
+# Authors:
+# Patrick Lehmann
#
-# Package module: DOM: VHDL design units (e.g. entity or package).
+# Package module: DOM: VHDL design units (e.g. context or package).
#
# License:
# ============================================================================
-# Copyright (C) 2019-2020 Tristan Gingold
+# 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
@@ -32,7 +32,7 @@
# ============================================================================
"""
-This module contains all DOM classes for VHDL's design units (:class:`entity <Entity>`,
+This module contains all DOM classes for VHDL's design units (:class:`context <Entity>`,
:class:`architecture <Architecture>`, :class:`package <Package>`,
:class:`package body <PackageBody>`, :class:`context <Context>` and
:class:`configuration <Configuration>`.
@@ -41,56 +41,43 @@ This module contains all DOM classes for VHDL's design units (:class:`entity <En
"""
from pydecor import export
-from pyVHDLModel.VHDLModel import Entity as VHDLModel_Entity
-from pyVHDLModel.VHDLModel import Architecture as VHDLModel_Architecture
-from pyVHDLModel.VHDLModel import Package as VHDLModel_Package
-from pyVHDLModel.VHDLModel import PackageBody as VHDLModel_PackageBody
-from pyVHDLModel.VHDLModel import Context as VHDLModel_Context
+from pyVHDLModel.VHDLModel import Entity as VHDLModel_Entity
+from pyVHDLModel.VHDLModel import Architecture as VHDLModel_Architecture
+from pyVHDLModel.VHDLModel import Package as VHDLModel_Package
+from pyVHDLModel.VHDLModel import PackageBody as VHDLModel_PackageBody
+from pyVHDLModel.VHDLModel import Context as VHDLModel_Context
from pyVHDLModel.VHDLModel import Configuration as VHDLModel_Configuration
+from pyGHDL.libghdl import utils
from pyGHDL.libghdl.vhdl import nodes
-import pyGHDL.libghdl.utils as pyutils
-from pyGHDL.dom.Common import GHDLMixin
-from pyGHDL.dom.InterfaceItem import (
- GenericConstantInterfaceItem,
- PortSignalInterfaceItem,
-)
+from pyGHDL.dom._Utils import NodeToName, GetIirKindOfNode
+from pyGHDL.dom._Translate import GetExpressionFromNode, GetSubtypeIndicationFromNode, GetGenericsFromChainedNodes, GetPortsFromChainedNodes, \
+ GetDeclaredItemsFromChainedNodes
+from pyGHDL.dom.Common import GHDLMixin, DOMException
+from pyGHDL.dom.Object import Constant, Signal
__all__ = []
@export
class Entity(VHDLModel_Entity, GHDLMixin):
+
@classmethod
def parse(cls, libraryUnit):
- name = cls._ghdlNodeToName(libraryUnit)
+ name = NodeToName(libraryUnit)
entity = cls(name)
- cls.__parseGenerics(libraryUnit, entity)
- cls.__parsePorts(libraryUnit, entity)
-
- return entity
-
- @classmethod
- def __ghdlGetGenerics(cls, entity):
- return pyutils.chain_iter(nodes.Get_Generic_Chain(entity))
+ for generic in GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(libraryUnit)):
+ entity.GenericItems.append(generic)
- @classmethod
- def __ghdlGetPorts(cls, entity):
- return pyutils.chain_iter(nodes.Get_Port_Chain(entity))
+ for port in GetPortsFromChainedNodes(nodes.Get_Port_Chain(libraryUnit)):
+ entity.PortItems.append(port)
- @classmethod
- def __parseGenerics(cls, libraryUnit, entity):
- for generic in cls.__ghdlGetGenerics(libraryUnit):
- genericConstant = GenericConstantInterfaceItem.parse(generic)
- entity.GenericItems.append(genericConstant)
+ for item in GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(libraryUnit), "entity", name):
+ entity.DeclaredItems.append(item)
- @classmethod
- def __parsePorts(cls, libraryUnit, entity):
- for port in cls.__ghdlGetPorts(libraryUnit):
- signalPort = PortSignalInterfaceItem.parse(port)
- entity.PortItems.append(signalPort)
+ return entity
@export
@@ -102,10 +89,15 @@ class Architecture(VHDLModel_Architecture, GHDLMixin):
@classmethod
def parse(cls, libraryUnit):
- name = cls._ghdlNodeToName(libraryUnit)
- entityName = cls._ghdlNodeToName(nodes.Get_Entity_Name(libraryUnit))
+ name = NodeToName(libraryUnit)
+ entityName = NodeToName(nodes.Get_Entity_Name(libraryUnit))
- return cls(name, entityName)
+ architecture = cls(name, entityName)
+
+ for item in GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(libraryUnit), "architecture", name):
+ architecture.DeclaredItems.append(item)
+
+ return architecture
def resolve(self):
pass
@@ -113,31 +105,47 @@ class Architecture(VHDLModel_Architecture, GHDLMixin):
@export
class Package(VHDLModel_Package, GHDLMixin):
+
@classmethod
def parse(cls, libraryUnit):
- name = cls._ghdlNodeToName(libraryUnit)
- return cls(name)
+ name = NodeToName(libraryUnit)
+
+ package = cls(name)
+
+ for item in GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(libraryUnit), "package", name):
+ package.DeclaredItems.append(item)
+
+ return package
@export
class PackageBody(VHDLModel_PackageBody, GHDLMixin):
+
@classmethod
def parse(cls, libraryUnit):
- name = cls._ghdlNodeToName(libraryUnit)
- return cls(name)
+ name = NodeToName(libraryUnit)
+
+ packageBody = cls(name)
+
+ for item in GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(libraryUnit), "package body", name):
+ packageBody.DeclaredItems.append(item)
+
+ return packageBody
@export
class Context(VHDLModel_Context, GHDLMixin):
+
@classmethod
def parse(cls, libraryUnit):
- name = cls._ghdlNodeToName(libraryUnit)
+ name = NodeToName(libraryUnit)
return cls(name)
@export
class Configuration(VHDLModel_Configuration, GHDLMixin):
+
@classmethod
def parse(cls, libraryUnit):
- name = cls._ghdlNodeToName(libraryUnit)
+ name = NodeToName(libraryUnit)
return cls(name)
diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py
new file mode 100644
index 000000000..7f32e7d54
--- /dev/null
+++ b/pyGHDL/dom/Expression.py
@@ -0,0 +1,287 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# 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 \
+ InverseExpression as VHDLModel_InverseExpression, \
+ IdentityExpression as VHDLModel_IdentityExpression, \
+ NegationExpression as VHDLModel_NegationExpression, \
+ AbsoluteExpression as VHDLModel_AbsoluteExpression, \
+ TypeConversion as VHDLModel_TypeConversion, \
+ FunctionCall as VHDLModel_FunctionCall, \
+ QualifiedExpression as VHDLModel_QualifiedExpression, \
+ AdditionExpression as VHDLModel_AdditionExpression, \
+ SubtractionExpression as VHDLModel_SubtractionExpression, \
+ ConcatenationExpression as VHDLModel_ConcatenationExpression, \
+ MultiplyExpression as VHDLModel_MultiplyExpression, \
+ DivisionExpression as VHDLModel_DivisionExpression, \
+ RemainderExpression as VHDLModel_RemainderExpression, \
+ ModuloExpression as VHDLModel_ModuloExpression, \
+ ExponentiationExpression as VHDLModel_ExponentiationExpression, \
+ AndExpression as VHDLModel_AndExpression, \
+ NandExpression as VHDLModel_NandExpression, \
+ OrExpression as VHDLModel_OrExpression, \
+ NorExpression as VHDLModel_NorExpression, \
+ XorExpression as VHDLModel_XorExpression, \
+ XnorExpression as VHDLModel_XnorExpression, \
+ EqualExpression as VHDLModel_EqualExpression, \
+ UnequalExpression as VHDLModel_UnequalExpression, \
+ GreaterThanExpression as VHDLModel_GreaterThanExpression, \
+ GreaterEqualExpression as VHDLModel_GreaterEqualExpression, \
+ LessThanExpression as VHDLModel_LessThanExpression, \
+ ShiftRightLogicExpression as VHDLModel_ShiftRightLogicExpression, \
+ ShiftLeftLogicExpression as VHDLModel_ShiftLeftLogicExpression, \
+ ShiftRightArithmeticExpression as VHDLModel_ShiftRightArithmeticExpression, \
+ ShiftLeftArithmeticExpression as VHDLModel_ShiftLeftArithmeticExpression, \
+ RotateRightExpression as VHDLModel_RotateRightExpression, \
+ RotateLeftExpression as VHDLModel_RotateLeftExpression, \
+ Expression
+
+__all__ = []
+
+@export
+class InverseExpression(VHDLModel_InverseExpression):
+ def __init__(self, operand: Expression):
+ super().__init__()
+ self._operand = operand
+
+@export
+class IdentityExpression(VHDLModel_IdentityExpression):
+ def __init__(self, operand: Expression):
+ super().__init__()
+ self._operand = operand
+
+@export
+class NegationExpression(VHDLModel_NegationExpression):
+ def __init__(self, operand: Expression):
+ super().__init__()
+ self._operand = operand
+
+@export
+class AbsoluteExpression(VHDLModel_AbsoluteExpression):
+ def __init__(self, operand: Expression):
+ super().__init__()
+ self._operand = operand
+
+@export
+class TypeConversion(VHDLModel_TypeConversion):
+ def __init__(self, operand: Expression):
+ super().__init__()
+ self._operand = operand
+
+@export
+class FunctionCall(VHDLModel_FunctionCall):
+ def __init__(self, operand: Expression):
+ super().__init__()
+ self._operand = operand
+
+@export
+class QualifiedExpression(VHDLModel_QualifiedExpression):
+ def __init__(self, operand: Expression):
+ super().__init__()
+ self._operand = operand
+
+@export
+class AdditionExpression(VHDLModel_AdditionExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class SubtractionExpression(VHDLModel_SubtractionExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class ConcatenationExpression(VHDLModel_ConcatenationExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class MultiplyExpression(VHDLModel_MultiplyExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class DivisionExpression(VHDLModel_DivisionExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class RemainderExpression(VHDLModel_RemainderExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class ModuloExpression(VHDLModel_ModuloExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class ExponentiationExpression(VHDLModel_ExponentiationExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class AndExpression(VHDLModel_AndExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class NandExpression(VHDLModel_NandExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class OrExpression(VHDLModel_OrExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class NorExpression(VHDLModel_NorExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class XorExpression(VHDLModel_XorExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class XnorExpression(VHDLModel_XnorExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class EqualExpression(VHDLModel_EqualExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class UnequalExpression(VHDLModel_UnequalExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class GreaterThanExpression(VHDLModel_GreaterThanExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class GreaterEqualExpression(VHDLModel_GreaterEqualExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class LessThanExpression(VHDLModel_LessThanExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class ShiftRightLogicExpression(VHDLModel_ShiftRightLogicExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class ShiftLeftLogicExpression(VHDLModel_ShiftLeftLogicExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class ShiftRightArithmeticExpression(VHDLModel_ShiftRightArithmeticExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class ShiftLeftArithmeticExpression(VHDLModel_ShiftLeftArithmeticExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class RotateRightExpression(VHDLModel_RotateRightExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
+
+@export
+class RotateLeftExpression(VHDLModel_RotateLeftExpression):
+ def __init__(self, left: Expression, right: Expression):
+ super().__init__()
+ self._leftOperand = left
+ self._rightOperand = right
diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py
index 0134655d5..89427e3b4 100644
--- a/pyGHDL/dom/InterfaceItem.py
+++ b/pyGHDL/dom/InterfaceItem.py
@@ -1,19 +1,19 @@
# =============================================================================
-# ____ _ _ ____ _ _
-# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
-# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
-# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
-# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-# |_| |___/
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
# =============================================================================
-# Authors:
-# Patrick Lehmann
+# Authors:
+# Patrick Lehmann
#
# Package module: DOM: Interface items (e.g. generic or port)
#
# License:
# ============================================================================
-# Copyright (C) 2019-2020 Tristan Gingold
+# 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
@@ -30,17 +30,16 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-
from pydecor import export
-from pyVHDLModel.VHDLModel import (
- PortSignalInterfaceItem as VHDLModel_PortSignalInterfaceItem,
-)
-from pyVHDLModel.VHDLModel import (
- GenericConstantInterfaceItem as VHDLModel_GenericConstantInterfaceItem,
-)
+from pyVHDLModel.VHDLModel import \
+ GenericConstantInterfaceItem as VHDLModel_GenericConstantInterfaceItem, \
+ PortSignalInterfaceItem as VHDLModel_PortSignalInterfaceItem, \
+ Mode, SubTypeOrSymbol, Expression
-from pyGHDL.dom.Common import GHDLMixin
+from pyGHDL.dom._Utils import NodeToName, GetModeOfNode
+from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode
+from pyGHDL.dom.Common import GHDLMixin
__all__ = []
@@ -49,21 +48,32 @@ __all__ = []
class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem, GHDLMixin):
@classmethod
def parse(cls, generic):
- name = cls._ghdlNodeToName(generic)
- mode = cls._ghdlPortToMode(generic)
+ name = NodeToName(generic)
+ mode = GetModeOfNode(generic)
+ subTypeIndication = GetSubtypeIndicationFromNode(generic, "generic", name)
- generic = cls(name, mode)
+ generic = cls(name, mode, subTypeIndication)
return generic
+ def __init__(self, name:str, mode: Mode, subType: SubTypeOrSymbol):
+ super().__init__(name=name, mode=mode)
+ self._subType = subType
@export
class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, GHDLMixin):
@classmethod
def parse(cls, port):
- name = cls._ghdlNodeToName(port)
- mode = cls._ghdlPortToMode(port)
+ name = NodeToName(port)
+ mode = GetModeOfNode(port)
+ subTypeIndication = GetSubtypeIndicationFromNode(port, "port", name)
- port = cls(name, mode)
+ port = cls(name, mode, subTypeIndication)
return port
+
+ def __init__(self, name:str, mode: Mode, subType: SubTypeOrSymbol, defaultExpression: Expression = None):
+ super().__init__(name=name, mode=mode)
+ self._subType = subType
+ self._defaultExpression = defaultExpression
+
diff --git a/pyGHDL/dom/Literal.py b/pyGHDL/dom/Literal.py
new file mode 100644
index 000000000..2ed1b5f65
--- /dev/null
+++ b/pyGHDL/dom/Literal.py
@@ -0,0 +1,55 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# 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 \
+ IntegerLiteral as VHDLModel_IntegerLiteral, \
+ FloatingPointLiteral as VHDLModel_FloatingPointLiteral, \
+ CharacterLiteral as VHDLModel_CharacterLiteral
+
+__all__ = []
+
+
+@export
+class IntegerLiteral(VHDLModel_IntegerLiteral):
+ pass
+
+
+@export
+class FloatingPointLiteral(VHDLModel_FloatingPointLiteral):
+ pass
+
+
+@export
+class CharacterLiteral(VHDLModel_CharacterLiteral):
+ pass
diff --git a/pyGHDL/dom/Misc.py b/pyGHDL/dom/Misc.py
index 43c201c46..0f26119a2 100644
--- a/pyGHDL/dom/Misc.py
+++ b/pyGHDL/dom/Misc.py
@@ -1,19 +1,19 @@
# =============================================================================
-# ____ _ _ ____ _ _
-# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
-# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
-# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
-# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-# |_| |___/
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
# =============================================================================
-# Authors:
-# Patrick Lehmann
+# Authors:
+# Patrick Lehmann
#
# Package module: DOM: Elements not covered by the VHDL standard.
#
# License:
# ============================================================================
-# Copyright (C) 2019-2020 Tristan Gingold
+# 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
@@ -36,27 +36,22 @@
Add a module documentation.
"""
from pathlib import Path
-from typing import Any
+from typing import Any
+import pyGHDL.libghdl.utils
from pydecor import export
-from pyVHDLModel.VHDLModel import Design as VHDLModel_Design
-from pyVHDLModel.VHDLModel import Library as VHDLModel_Library
-from pyVHDLModel.VHDLModel import Document as VHDLModel_Document
+from pyGHDL.dom._Utils import GetIirKindOfNode
+from pyVHDLModel.VHDLModel import Design as VHDLModel_Design
+from pyVHDLModel.VHDLModel import Library as VHDLModel_Library
+from pyVHDLModel.VHDLModel import Document as VHDLModel_Document
-import pyGHDL.libghdl as libghdl
-from pyGHDL.libghdl import name_table, files_map, errorout_memory
-from pyGHDL.libghdl.vhdl import nodes, sem_lib
+import pyGHDL.libghdl as libghdl
+from pyGHDL.libghdl import name_table, files_map, errorout_memory, LibGHDLException, utils
+from pyGHDL.libghdl.vhdl import nodes, sem_lib
-from pyGHDL.dom.Common import LibGHDLException, GHDLException
-from pyGHDL.dom.DesignUnit import (
- Entity,
- Architecture,
- Package,
- PackageBody,
- Context,
- Configuration,
-)
+from pyGHDL.dom.Common import DOMException, GHDLMixin
+from pyGHDL.dom.DesignUnit import Entity, Architecture, Package, PackageBody, Context, Configuration
__all__ = []
@@ -90,61 +85,66 @@ class Library(VHDLModel_Library):
@export
-class Document(VHDLModel_Document):
+class Document(VHDLModel_Document, GHDLMixin):
__ghdlFileID: Any
__ghdlSourceFileEntry: Any
__ghdlFile: Any
def __init__(self, path: Path = None, dontParse: bool = False):
super().__init__(path)
+ GHDLMixin.__init__(self)
self.__ghdl_init()
- if dontParse == False:
+ if (dontParse == False):
self.parse()
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
- )
+ 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))
- # parse
+ self.CheckForErrors()
+
+ # Parse input file
self.__ghdlFile = sem_lib.Load_File(self.__ghdlSourceFileEntry)
+ self.CheckForErrors()
+
def parse(self):
- unit = nodes.Get_First_Design_Unit(self.__ghdlFile)
- while unit != nodes.Null_Iir:
+ firstUnit = nodes.Get_First_Design_Unit(self.__ghdlFile)
+
+ for unit in utils.chain_iter(firstUnit):
libraryUnit = nodes.Get_Library_Unit(unit)
- nodeKind = nodes.Get_Kind(libraryUnit)
+ nodeKind = GetIirKindOfNode(libraryUnit)
- if nodeKind == nodes.Iir_Kind.Entity_Declaration:
+ if (nodeKind == nodes.Iir_Kind.Entity_Declaration):
entity = Entity.parse(libraryUnit)
self.Entities.append(entity)
- elif nodeKind == nodes.Iir_Kind.Architecture_Body:
+ elif (nodeKind == nodes.Iir_Kind.Architecture_Body):
architecture = Architecture.parse(libraryUnit)
self.Architectures.append(architecture)
- elif nodeKind == nodes.Iir_Kind.Package_Declaration:
+ elif (nodeKind == nodes.Iir_Kind.Package_Declaration):
package = Package.parse(libraryUnit)
self.Packages.append(package)
- elif nodeKind == nodes.Iir_Kind.Package_Body:
+ elif (nodeKind == nodes.Iir_Kind.Package_Body):
packageBody = PackageBody.parse(libraryUnit)
self.PackageBodies.append(packageBody)
- elif nodeKind == nodes.Iir_Kind.Context_Declaration:
+ elif (nodeKind == nodes.Iir_Kind.Context_Declaration):
context = Context.parse(libraryUnit)
self.Contexts.append(context)
- elif nodeKind == nodes.Iir_Kind.Configuration_Declaration:
+ elif (nodeKind == nodes.Iir_Kind.Configuration_Declaration):
configuration = Configuration.parse(libraryUnit)
self.Configurations.append(configuration)
else:
- raise GHDLException("Unknown design unit kind.")
-
- unit = nodes.Get_Chain(unit)
+ raise DOMException(
+ "Unknown design unit kind '{kindName}'({kind}).".format(
+ kindName=nodeKind.name, kind=nodeKind)
+ )
diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py
new file mode 100644
index 000000000..924c28662
--- /dev/null
+++ b/pyGHDL/dom/Object.py
@@ -0,0 +1,72 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# 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 \
+ Constant as VHDLModel_Constant, \
+ Variable as VHDLModel_Variable, \
+ Signal as VHDLModel_Signal, \
+ Expression, SubTypeOrSymbol
+
+__all__ = []
+
+
+@export
+class Constant(VHDLModel_Constant):
+ def __init__(self, name: str, subType: SubTypeOrSymbol, defaultExpression: Expression):
+ super().__init__(name)
+
+ self._name = name
+ self._subType = subType
+ self._defaultExpression = defaultExpression
+
+
+@export
+class Variable(VHDLModel_Variable):
+ def __init__(self, name: str, subType: SubTypeOrSymbol, defaultExpression: Expression):
+ super().__init__(name)
+
+ self._name = name
+ self._subType = subType
+ self._defaultExpression = defaultExpression
+
+
+@export
+class Signal(VHDLModel_Signal):
+ def __init__(self, name: str, subType: SubTypeOrSymbol, defaultExpression: Expression):
+ super().__init__(name)
+
+ self._name = name
+ self._subType = subType
+ self._defaultExpression = defaultExpression
+
diff --git a/pyGHDL/dom/Range.py b/pyGHDL/dom/Range.py
new file mode 100644
index 000000000..45675cd19
--- /dev/null
+++ b/pyGHDL/dom/Range.py
@@ -0,0 +1,58 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# 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 \
+ Range as VHDLModel_Range, \
+ RangeExpression as VHDLModel_RangeExpression, \
+ Direction, Expression
+
+__all__ = []
+
+
+@export
+class Range(VHDLModel_Range):
+ def __init__(self, left: Expression, right: Expression, direction: Direction):
+ super().__init__()
+
+ 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/Symbol.py b/pyGHDL/dom/Symbol.py
new file mode 100644
index 000000000..9b765872d
--- /dev/null
+++ b/pyGHDL/dom/Symbol.py
@@ -0,0 +1,60 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# 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 typing import List
+
+from pyVHDLModel.VHDLModel import \
+ SimpleSubTypeSymbol as VHDLModel_SimpleSubTypeSymbol, \
+ ConstrainedSubTypeSymbol as VHDLModel_ConstrainedSubTypeSymbol, \
+ SimpleObjectSymbol as VHDLModel_SimpleObjectSymbol, \
+ Constraint
+
+__all__ = []
+
+
+@export
+class SimpleSubTypeSymbol(VHDLModel_SimpleSubTypeSymbol):
+ def __init__(self, subTypeName: str):
+ super().__init__(subTypeName=subTypeName)
+
+
+@export
+class ConstrainedSubTypeSymbol(VHDLModel_ConstrainedSubTypeSymbol):
+ def __init__(self, subTypeName: str, constraints: List[Constraint] = None):
+ super().__init__(subTypeName=subTypeName, constraints=constraints)
+
+@export
+class SimpleObjectSymbol(VHDLModel_SimpleObjectSymbol):
+ def __init__(self, symbolName: str):
+ super().__init__(symbolName)
diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py
new file mode 100644
index 000000000..e93b20b07
--- /dev/null
+++ b/pyGHDL/dom/_Translate.py
@@ -0,0 +1,208 @@
+from typing import List
+
+
+from pydecor import export
+from pyVHDLModel.VHDLModel import Constraint, Direction, Expression, SubTypeOrSymbol
+
+from pyGHDL.libghdl import utils, name_table
+from pyGHDL.libghdl.utils import flist_iter
+from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL.dom._Utils import NodeToName, GetIirKindOfNode
+from pyGHDL.dom.Common import DOMException
+from pyGHDL.dom.Range import Range, RangeExpression
+from pyGHDL.dom.Symbol import SimpleObjectSymbol, SimpleSubTypeSymbol, ConstrainedSubTypeSymbol
+from pyGHDL.dom.Literal import IntegerLiteral, CharacterLiteral, FloatingPointLiteral
+from pyGHDL.dom.Expression import SubtractionExpression, AdditionExpression, MultiplyExpression, DivisionExpression, InverseExpression, ExponentiationExpression
+
+__all__ = []
+
+
+@export
+def GetSubtypeIndicationFromNode(node, entity: str, name: str) -> SubTypeOrSymbol:
+ subTypeIndication = nodes.Get_Subtype_Indication(node)
+ subTypeKind = GetIirKindOfNode(subTypeIndication)
+
+ if (subTypeKind == nodes.Iir_Kind.Simple_Name):
+ subTypeName = NodeToName(subTypeIndication)
+
+ subType = SimpleSubTypeSymbol(subTypeName)
+ elif (subTypeKind == nodes.Iir_Kind.Array_Subtype_Definition):
+ typeMark = nodes.Get_Subtype_Type_Mark(subTypeIndication)
+ typeMarkName = NodeToName(typeMark)
+
+ constraints = GetArrayConstraintsFromSubtypeIndication(subTypeIndication)
+ subType = ConstrainedSubTypeSymbol(typeMarkName, constraints)
+ elif (subTypeKind == nodes.Iir_Kind.Subtype_Definition):
+ raise DOMException(
+ "Unknown handling of subtype kind '{kind}' of subtype indication '{indication}' while parsing {entity} '{name}'.".format(
+ kind=subTypeKind, indication=subTypeIndication, entity=entity, name=name)
+ )
+ else:
+ raise DOMException(
+ "Unknown subtype kind '{kind}' of subtype indication '{indication}' while parsing {entity} '{name}'.".format(
+ kind=subTypeKind, indication=subTypeIndication, entity=entity, name=name)
+ )
+
+ return subType
+
+@export
+def GetArrayConstraintsFromSubtypeIndication(subTypeIndication) -> List[Constraint]:
+ constraints = []
+ for constraint in flist_iter(nodes.Get_Index_Constraint_List(subTypeIndication)):
+ constraintKind = GetIirKindOfNode(constraint)
+ if constraintKind == nodes.Iir_Kind.Range_Expression:
+ direction = nodes.Get_Direction(constraint)
+ leftBound = nodes.Get_Left_Limit_Expr(constraint)
+ rightBound = nodes.Get_Right_Limit_Expr(constraint)
+
+ r = Range(
+ GetExpressionFromNode(leftBound),
+ GetExpressionFromNode(rightBound),
+ Direction.DownTo if direction else Direction.To
+ )
+ constraints.append(RangeExpression(r))
+ elif constraintKind == nodes.Iir_Kind.Attribute_Name:
+ raise DOMException("[NOT IMPLEMENTED] Attribute name as range.")
+ elif constraintKind == nodes.Iir_Kind.Simple_Name:
+ raise DOMException("[NOT IMPLEMENTED] Subtype as range.")
+ else:
+ raise DOMException(
+ "Unknown constraint kind '{kind}' for constraint '{constraint}' in subtype indication '{indication}'.".format(
+ kind=constraintKind, constraint=constraint, indication=subTypeIndication)
+ )
+
+ return constraints
+
+
+@export
+def GetExpressionFromNode(node) -> Expression:
+ kind = GetIirKindOfNode(node)
+
+ if kind == nodes.Iir_Kind.Simple_Name:
+ name = NodeToName(node)
+ return SimpleObjectSymbol(name)
+ elif kind == nodes.Iir_Kind.Integer_Literal:
+ integerLiteralValue = nodes.Get_Value(node)
+ return IntegerLiteral(integerLiteralValue)
+ elif kind == nodes.Iir_Kind.Floating_Point_Literal:
+ fpLiteralValue = nodes.Get_Fp_Value(node)
+ return FloatingPointLiteral(fpLiteralValue)
+ elif kind == nodes.Iir_Kind.Character_Literal:
+ identifier = nodes.Get_Identifier(node)
+ characterLiteralValue = name_table.Get_Character(identifier)
+ return CharacterLiteral(characterLiteralValue)
+ elif kind == nodes.Iir_Kind.Negation_Operator:
+ operand = GetExpressionFromNode(nodes.Get_Operand(node))
+ return InverseExpression(operand)
+ elif kind == nodes.Iir_Kind.Addition_Operator:
+ left = GetExpressionFromNode(nodes.Get_Left(node))
+ right = GetExpressionFromNode(nodes.Get_Right(node))
+ return AdditionExpression(left, right)
+ elif kind == nodes.Iir_Kind.Substraction_Operator:
+ left = GetExpressionFromNode(nodes.Get_Left(node))
+ right = GetExpressionFromNode(nodes.Get_Right(node))
+ return SubtractionExpression(left, right)
+ elif kind == nodes.Iir_Kind.Multiplication_Operator:
+ left = GetExpressionFromNode(nodes.Get_Left(node))
+ right = GetExpressionFromNode(nodes.Get_Right(node))
+ return MultiplyExpression(left, right)
+ elif kind == nodes.Iir_Kind.Division_Operator:
+ left = GetExpressionFromNode(nodes.Get_Left(node))
+ right = GetExpressionFromNode(nodes.Get_Right(node))
+ return DivisionExpression(left, right)
+ elif kind == nodes.Iir_Kind.Exponentiation_Operator:
+ left = GetExpressionFromNode(nodes.Get_Left(node))
+ right = GetExpressionFromNode(nodes.Get_Right(node))
+ return ExponentiationExpression(left, right)
+ else:
+ raise DOMException(
+ "Unknown expression kind '{kindName}'({kind}) in expression '{expr}'.".format(
+ kind=kind, kindName=kind.name, expr=node)
+ )
+
+# FIXME: rewrite to generator
+@export
+def GetGenericsFromChainedNodes(nodeChain):
+ result = []
+ for generic in utils.chain_iter(nodeChain):
+ kind = GetIirKindOfNode(generic)
+ if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
+ from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem
+
+ genericConstant = GenericConstantInterfaceItem.parse(generic)
+
+ result.append(genericConstant)
+ else:
+ raise DOMException(
+ "Unknown generic kind '{kindName}'({kind}) in generic '{generic}'.".format(
+ kind=kind, kindName=kind.name, generic=generic)
+ )
+
+ return result
+
+# FIXME: rewrite to generator
+@export
+def GetPortsFromChainedNodes(nodeChain):
+ result = []
+ for port in utils.chain_iter(nodeChain):
+ kind = GetIirKindOfNode(port)
+ if kind == nodes.Iir_Kind.Interface_Signal_Declaration:
+ from pyGHDL.dom.InterfaceItem import PortSignalInterfaceItem
+
+ portSignal = PortSignalInterfaceItem.parse(port)
+
+ result.append(portSignal)
+ else:
+ raise DOMException(
+ "Unknown port kind '{kindName}'({kind}) in port '{port}'.".format(
+ kind=kind, kindName=kind.name, port=port)
+ )
+
+ return result
+
+def GetDeclaredItemsFromChainedNodes(nodeChain, entity: str, name: str):
+ result = []
+ for item in utils.chain_iter(nodeChain):
+ kind = GetIirKindOfNode(item)
+ if kind == nodes.Iir_Kind.Constant_Declaration:
+ from pyGHDL.dom.Object import Constant
+
+ constantName = NodeToName(item)
+ subTypeIndication = GetSubtypeIndicationFromNode(item, "constant", constantName)
+ defaultExpression = GetExpressionFromNode(nodes.Get_Default_Value(item))
+
+ constant = Constant(constantName, subTypeIndication, defaultExpression)
+
+ result.append(constant)
+ elif kind == nodes.Iir_Kind.Signal_Declaration:
+ from pyGHDL.dom.Object import Signal
+
+ signalName = NodeToName(item)
+ subTypeIndication = GetSubtypeIndicationFromNode(item, "signal", signalName)
+ defaultExpression = GetExpressionFromNode(nodes.Get_Default_Value(item))
+
+ constant = Signal(signalName, subTypeIndication, defaultExpression)
+
+ result.append(constant)
+ elif kind == nodes.Iir_Kind.Anonymous_Type_Declaration:
+ typeName = NodeToName(item)
+ print("found type '{name}'".format(name=typeName))
+ elif kind == nodes.Iir_Kind.Subtype_Declaration:
+ subTypeName = NodeToName(item)
+ print("found subtype '{name}'".format(name=subTypeName))
+ elif kind == nodes.Iir_Kind.Function_Declaration:
+ functionName = NodeToName(item)
+ print("found function '{name}'".format(name=functionName))
+ elif kind == nodes.Iir_Kind.Function_Body:
+ # functionName = NodeToName(item)
+ print("found function body '{name}'".format(name="????"))
+ elif kind == nodes.Iir_Kind.Object_Alias_Declaration:
+ aliasName = NodeToName(item)
+ print("found alias '{name}'".format(name=aliasName))
+ else:
+ raise DOMException(
+ "Unknown declared item kind '{kindName}'({kind}) in {entity} '{name}'.".format(
+ kind=kind, kindName=kind.name, entity=entity, name=name)
+ )
+
+ return result
diff --git a/pyGHDL/dom/_Utils.py b/pyGHDL/dom/_Utils.py
new file mode 100644
index 000000000..f0c838517
--- /dev/null
+++ b/pyGHDL/dom/_Utils.py
@@ -0,0 +1,38 @@
+from pydecor import export
+
+from pyVHDLModel.VHDLModel import Mode
+
+from pyGHDL.libghdl import LibGHDLException, name_table
+from pyGHDL.libghdl.vhdl import nodes
+
+
+__all__ = []
+
+__MODE_TRANSLATION = {
+ nodes.Iir_Mode.In_Mode: Mode.In,
+ nodes.Iir_Mode.Out_Mode: Mode.Out,
+ nodes.Iir_Mode.Inout_Mode: Mode.InOut,
+ nodes.Iir_Mode.Buffer_Mode: Mode.Buffer,
+ nodes.Iir_Mode.Linkage_Mode: Mode.Linkage
+}
+
+@export
+def GetIirKindOfNode(node) -> nodes.Iir_Kind:
+ kind: int = nodes.Get_Kind(node)
+ return nodes.Iir_Kind(kind)
+
+
+@export
+def NodeToName(node) -> str:
+ """Return the python string from node :obj:`node` identifier"""
+ identifier = nodes.Get_Identifier(node)
+ return name_table.Get_Name_Ptr(identifier)
+
+
+@export
+def GetModeOfNode(node) -> Mode:
+ """Return the mode of a :obj:`port`."""
+ try:
+ return __MODE_TRANSLATION[nodes.Get_Mode(node)]
+ except KeyError:
+ raise LibGHDLException("Unknown mode.")
diff --git a/pyGHDL/dom/__init__.py b/pyGHDL/dom/__init__.py
index b57c20c28..b4ffaf4c6 100644
--- a/pyGHDL/dom/__init__.py
+++ b/pyGHDL/dom/__init__.py
@@ -1,19 +1,19 @@
# =============================================================================
-# ____ _ _ ____ _ _
-# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
-# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
-# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
-# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
-# |_| |___/
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
# =============================================================================
-# Authors:
-# Patrick Lehmann
+# Authors:
+# Patrick Lehmann
#
# Package package: Document object model (DOM) for pyGHDL.libghdl.
#
# License:
# ============================================================================
-# Copyright (C) 2019-2020 Tristan Gingold
+# 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
@@ -31,6 +31,4 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from pydecor import export
-
__all__ = []
diff --git a/pyGHDL/dom/formatting/__init__.py b/pyGHDL/dom/formatting/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/pyGHDL/dom/formatting/__init__.py
diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py
new file mode 100644
index 000000000..a64f2a4f5
--- /dev/null
+++ b/pyGHDL/dom/formatting/prettyprint.py
@@ -0,0 +1,296 @@
+from typing import List, Union
+
+from pydecor import export
+
+from pyGHDL.dom.Object import Constant, Signal
+from pyVHDLModel.VHDLModel import GenericInterfaceItem, Expression, Direction, Mode, NamedEntity, PortInterfaceItem, BinaryExpression, IdentityExpression, \
+ UnaryExpression
+
+from pyGHDL import GHDLBaseException
+from pyGHDL.dom.Misc import Document
+from pyGHDL.dom.DesignUnit import Entity, Architecture, Package, PackageBody, Configuration, Context
+from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem, PortSignalInterfaceItem
+from pyGHDL.dom.Symbol import SimpleSubTypeSymbol, ConstrainedSubTypeSymbol, SimpleObjectSymbol
+from pyGHDL.dom.Literal import IntegerLiteral, CharacterLiteral, FloatingPointLiteral
+
+from pyGHDL.dom.Expression import SubtractionExpression, AdditionExpression, MultiplyExpression, DivisionExpression, InverseExpression, AbsoluteExpression, \
+ NegationExpression, ExponentiationExpression
+
+StringBuffer = List[str]
+
+DirectionTranslation = {
+ Direction.To: "to",
+ Direction.DownTo: "downto"
+}
+
+ModeTranslation = {
+ Mode.In: "in",
+ Mode.Out: "out",
+ Mode.InOut: "inout",
+ Mode.Buffer: "buffer",
+ Mode.Linkage: "linkage"
+}
+
+UnaryExpressionTranslation = {
+ IdentityExpression: " +",
+ NegationExpression: " -",
+ InverseExpression: "not ",
+ AbsoluteExpression: "abs ",
+}
+
+BinaryExpressionTranslation = {
+ AdditionExpression: " + ",
+ SubtractionExpression: " - ",
+ MultiplyExpression: " * ",
+ DivisionExpression: " / ",
+ ExponentiationExpression: "**"
+}
+
+@export
+class PrettyPrintException(GHDLBaseException):
+ pass
+
+@export
+class PrettyPrint:
+ # _buffer: StringBuffer
+ #
+ # def __init__(self):
+ # self._buffer = []
+
+ def formatDocument(self, document: Document, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}Document '{doc!s}':".format(doc=document.Path, prefix=prefix))
+ buffer.append("{prefix} Entities:".format(prefix=prefix))
+ for entity in document.Entities:
+ for line in self.formatEntity(entity, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} Architectures:".format(prefix=prefix))
+ for architecture in document.Architectures:
+ for line in self.formatArchitecture(architecture, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} Packages:".format(prefix=prefix))
+ for package in document.Packages:
+ for line in self.formatPackage(package, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} PackageBodies:".format(prefix=prefix))
+ for packageBodies in document.PackageBodies:
+ for line in self.formatPackageBody(packageBodies, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} Configurations:".format(prefix=prefix))
+ for configuration in document.Configurations:
+ for line in self.formatConfiguration(configuration, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} Contexts:".format(prefix=prefix))
+ for context in document.Contexts:
+ for line in self.formatContext(context, level+1):
+ buffer.append(line)
+
+ return buffer
+
+ def formatEntity(self, entity: Entity, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=entity.Name, prefix=prefix))
+ buffer.append("{prefix} Generics:".format(prefix=prefix))
+ for generic in entity.GenericItems:
+ for line in self.formatGeneric(generic, level + 1):
+ buffer.append(line)
+ buffer.append("{prefix} Ports:".format(prefix=prefix))
+ for port in entity.PortItems:
+ for line in self.formatPort(port, level + 1):
+ buffer.append(line)
+ buffer.append("{prefix} Declared:".format(prefix=prefix))
+ for item in entity.DeclaredItems:
+ for line in self.formatDeclaredItems(item, level + 1):
+ buffer.append(line)
+
+ return buffer
+
+ def formatArchitecture(self, architecture: Architecture, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=architecture.Name, prefix=prefix))
+ buffer.append("{prefix} Declared:".format(prefix=prefix))
+ for item in architecture.DeclaredItems:
+ for line in self.formatDeclaredItems(item, level + 2):
+ buffer.append(line)
+
+ return buffer
+
+ def formatPackage(self, package: Package, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=package.Name, prefix=prefix))
+ buffer.append("{prefix} Declared:".format(prefix=prefix))
+ for item in package.DeclaredItems:
+ for line in self.formatDeclaredItems(item, level + 1):
+ buffer.append(line)
+
+ return buffer
+
+ def formatPackageBody(self, packageBody: PackageBody, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=packageBody.Name, prefix=prefix))
+ buffer.append("{prefix} Declared:".format(prefix=prefix))
+ for item in packageBody.DeclaredItems:
+ for line in self.formatDeclaredItems(item, level + 1):
+ buffer.append(line)
+
+ return buffer
+
+ def formatConfiguration(self, configuration: Configuration, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=configuration.Name, prefix=prefix))
+
+ return buffer
+
+ def formatContext(self, context: Context, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=context.Name, prefix=prefix))
+
+ return buffer
+
+ def formatGeneric(self, generic: Union[NamedEntity, GenericInterfaceItem], level: int = 0) -> StringBuffer:
+ if isinstance(generic, GenericConstantInterfaceItem):
+ return self.formatGenericConstant(generic, level)
+ else:
+ raise PrettyPrintException("Unhandled generic kind for generic '{name}'.".format(name=generic.Name))
+
+ def formatPort(self, port: Union[NamedEntity, PortInterfaceItem], level: int = 0) -> StringBuffer:
+ if isinstance(port, PortSignalInterfaceItem):
+ return self.formatPortSignal(port, level)
+ else:
+ raise PrettyPrintException("Unhandled port kind for port '{name}'.".format(name=port.Name))
+
+ def formatGenericConstant(self, generic: GenericConstantInterfaceItem, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ subType = generic.SubType
+ if isinstance(subType, SimpleSubTypeSymbol):
+ buffer.append(
+ "{prefix} - {name} : {mode} {type}".format(
+ prefix=prefix,
+ name=generic.Name,
+ mode=ModeTranslation[generic.Mode],
+ type=subType.SymbolName
+ )
+ )
+ elif isinstance(subType, ConstrainedSubTypeSymbol):
+ buffer.append(
+ "{prefix} - {name} : {mode} {type}({constraints})".format(
+ prefix=prefix,
+ name=generic.Name,
+ mode=ModeTranslation[generic.Mode],
+ type=subType.SymbolName,
+ constraints=", ".join(
+ ["{left} {dir} {right}".format(
+ left=self.formatExpression(constraint.Range.LeftBound),
+ right=self.formatExpression(constraint.Range.RightBound),
+ dir=DirectionTranslation[constraint.Range.Direction])
+ for constraint in subType.Constraints])
+ )
+ )
+ else:
+ raise PrettyPrintException("Unhandled constraint kind for generic '{name}'.".format(name=generic.Name))
+
+ return buffer
+
+ def formatPortSignal(self, port: PortSignalInterfaceItem, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+
+ buffer.append(
+ "{prefix} - {name} : {mode} {subtypeindication}".format(
+ prefix=prefix,
+ name=port.Name,
+ mode=ModeTranslation[port.Mode],
+ subtypeindication=self.formatSubtypeIndication(port.SubType, "port", port.Name)
+ )
+ )
+
+ return buffer
+
+ def formatDeclaredItems(self, item, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+
+ if isinstance(item, Constant):
+ buffer.append(
+ "{prefix}- constant {name} : {subtype} := {expr}".format(
+ prefix=prefix,
+ name=item.Name,
+ subtype=self.formatSubtypeIndication(item.SubType, "constant", item.Name),
+ expr=self.formatExpression(item.DefaultExpression)
+ )
+ )
+ elif isinstance(item, Signal):
+ buffer.append(
+ "{prefix}- signal {name} : {subtype}{initValue}".format(
+ prefix=prefix,
+ name=item.Name,
+ subtype=self.formatSubtypeIndication(item.SubType, "signal", item.Name),
+ initValue=" := {expr}".format(
+ expr=self.formatExpression(item.DefaultExpression)
+ ) if item.DefaultExpression is not None else ""
+ )
+ )
+ else:
+ raise PrettyPrintException("Unhandled declared item kind.")
+
+ return buffer
+
+ def formatSubtypeIndication(self, subTypeIndication, entity: str, name: str) -> str:
+ if isinstance(subTypeIndication, SimpleSubTypeSymbol):
+ return "{type}".format(type=subTypeIndication.SymbolName)
+ elif isinstance(subTypeIndication, ConstrainedSubTypeSymbol):
+ constraints = ", ".join(
+ ["{left} {dir} {right}".format(
+ left=self.formatExpression(constraint.Range.LeftBound),
+ right=self.formatExpression(constraint.Range.RightBound),
+ dir=DirectionTranslation[constraint.Range.Direction]
+ ) for constraint in subTypeIndication.Constraints]
+ )
+
+ return "{type}({constraints})".format(
+ type=subTypeIndication.SymbolName,
+ constraints=constraints
+ )
+ else:
+ raise PrettyPrintException("Unhandled constraint kind for {entity} '{name}'.".format(entity=entity, name=name))
+
+ def formatExpression(self, expression: Expression) -> str:
+ if isinstance(expression, SimpleObjectSymbol):
+ return "{name}".format(name=expression.SymbolName)
+ elif isinstance(expression, IntegerLiteral):
+ return "{value}".format(value=expression.Value)
+ elif isinstance(expression, FloatingPointLiteral):
+ return "{value}".format(value=expression.Value)
+ elif isinstance(expression, CharacterLiteral):
+ return "'{value}'".format(value=expression.Value)
+ elif isinstance(expression, UnaryExpression):
+ try:
+ operator = UnaryExpressionTranslation[type(expression)]
+ except KeyError:
+ raise PrettyPrintException("Unhandled operator for unary expression.")
+
+ return "{operator}{operand}".format(
+ operand=self.formatExpression(expression.Operand),
+ operator=operator
+ )
+ elif isinstance(expression, BinaryExpression):
+ try:
+ operator = BinaryExpressionTranslation[type(expression)]
+ except KeyError:
+ raise PrettyPrintException("Unhandled operator for binary expression.")
+
+ return "{left}{operator}{right}".format(
+ left=self.formatExpression(expression.LeftOperand),
+ right=self.formatExpression(expression.RightOperand),
+ operator=operator
+ )
+ else:
+ raise PrettyPrintException("Unhandled expression kind.")