aboutsummaryrefslogtreecommitdiffstats
path: root/pyGHDL
diff options
context:
space:
mode:
authorUnai Martinez-Corral <38422348+umarcor@users.noreply.github.com>2021-06-23 16:07:10 +0100
committerGitHub <noreply@github.com>2021-06-23 16:07:10 +0100
commitc6283d9a9b40c3e9afeba912fcb13aa9d56b9c52 (patch)
treee1706cb19a2439e3d94657e54c688a36c703f048 /pyGHDL
parent983236ac3dfd0c455a0ac910a9a468ea2c81e5d9 (diff)
parent240b4fdd90a9f3ca04e8e168bffdc92bea2ca3f3 (diff)
downloadghdl-c6283d9a9b40c3e9afeba912fcb13aa9d56b9c52.tar.gz
ghdl-c6283d9a9b40c3e9afeba912fcb13aa9d56b9c52.tar.bz2
ghdl-c6283d9a9b40c3e9afeba912fcb13aa9d56b9c52.zip
DOM: Functions and types (#1804)
Diffstat (limited to 'pyGHDL')
-rwxr-xr-xpyGHDL/cli/DOM.py20
-rw-r--r--pyGHDL/dom/Common.py13
-rw-r--r--pyGHDL/dom/DesignUnit.py100
-rw-r--r--pyGHDL/dom/InterfaceItem.py32
-rw-r--r--pyGHDL/dom/Literal.py22
-rw-r--r--pyGHDL/dom/NonStandard.py12
-rw-r--r--pyGHDL/dom/Object.py52
-rw-r--r--pyGHDL/dom/Subprogram.py58
-rw-r--r--pyGHDL/dom/Symbol.py17
-rw-r--r--pyGHDL/dom/Type.py110
-rw-r--r--pyGHDL/dom/_Translate.py232
-rw-r--r--pyGHDL/dom/_Utils.py66
-rw-r--r--pyGHDL/dom/formatting/prettyprint.py80
-rw-r--r--pyGHDL/libghdl/__init__.py11
-rw-r--r--pyGHDL/libghdl/_decorator.py2
-rw-r--r--pyGHDL/requirements.txt3
16 files changed, 563 insertions, 267 deletions
diff --git a/pyGHDL/cli/DOM.py b/pyGHDL/cli/DOM.py
index 2feb6aecd..dceafc629 100755
--- a/pyGHDL/cli/DOM.py
+++ b/pyGHDL/cli/DOM.py
@@ -9,8 +9,8 @@ from pydecor import export
from pyGHDL import GHDLBaseException
from pyGHDL.libghdl import LibGHDLException
-from pyGHDL.dom import NonStandard
from pyGHDL.dom.Common import DOMException
+from pyGHDL.dom.NonStandard import Design, Document
from pyGHDL.dom.formatting.prettyprint import PrettyPrint, PrettyPrintException
__all__ = []
@@ -19,14 +19,16 @@ __api__ = __all__
@export
class Application:
- _design: NonStandard.Design
+ _design: Design
def __init__(self):
- self._design = NonStandard.Design()
+ self._design = Design()
def addFile(self, filename: Path, library: str):
- document = NonStandard.Document(filename)
- self._design.Documents.append(document)
+ lib = self._design.GetLibrary(library)
+
+ document = Document(filename)
+ self._design.AddDocument(document, lib)
def prettyPrint(self):
PP = PrettyPrint()
@@ -43,12 +45,18 @@ class Application:
def handleException(ex):
if isinstance(ex, PrettyPrintException):
print("PP:", ex)
- return 5
+ return 0
elif isinstance(ex, DOMException):
print("DOM:", ex)
+ ex2 = ex.__cause__
+ if ex2 is not None:
+ for message in ex2.InternalErrors:
+ print("libghdl: {message}".format(message=message))
return 4
elif isinstance(ex, LibGHDLException):
print("LIB:", ex)
+ for message in ex.InternalErrors:
+ print(" {message}".format(message=message))
return 3
elif isinstance(ex, GHDLBaseException):
print("GHDL:", ex)
diff --git a/pyGHDL/dom/Common.py b/pyGHDL/dom/Common.py
index 984f06e86..43e8ce497 100644
--- a/pyGHDL/dom/Common.py
+++ b/pyGHDL/dom/Common.py
@@ -51,16 +51,3 @@ class DOMException(GHDLBaseException):
@export
class GHDLException(GHDLBaseException):
pass
-
-
-@export
-class GHDLMixin:
- 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))
-
- raise DOMException("Error in libghdl.") from LibGHDLException(
- "libghdl: Internal error 2."
- )
diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py
index ce93bda3e..bf16b5c4b 100644
--- a/pyGHDL/dom/DesignUnit.py
+++ b/pyGHDL/dom/DesignUnit.py
@@ -61,54 +61,39 @@ from pyGHDL.dom._Translate import (
GetDeclaredItemsFromChainedNodes,
)
from pyGHDL.dom.Symbol import EntitySymbol
-from pyGHDL.dom.Common import GHDLMixin
__all__ = []
@export
-class Entity(VHDLModel_Entity, GHDLMixin):
+class Entity(VHDLModel_Entity):
@classmethod
def parse(cls, entityNode: Iir):
name = GetNameOfNode(entityNode)
- entity = cls(name)
-
- for generic in GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(entityNode)):
- entity.GenericItems.append(generic)
-
- for port in GetPortsFromChainedNodes(nodes.Get_Port_Chain(entityNode)):
- entity.PortItems.append(port)
-
- for item in GetDeclaredItemsFromChainedNodes(
+ generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(entityNode))
+ ports = GetPortsFromChainedNodes(nodes.Get_Port_Chain(entityNode))
+ declaredItems = GetDeclaredItemsFromChainedNodes(
nodes.Get_Declaration_Chain(entityNode), "entity", name
- ):
- entity.DeclaredItems.append(item)
+ )
+ bodyItems = []
- return entity
+ return cls(name, generics, ports, declaredItems, bodyItems)
@export
-class Architecture(VHDLModel_Architecture, GHDLMixin):
- def __init__(self, name: str, entity: EntityOrSymbol):
- super().__init__(name)
-
- self._entity = entity
-
+class Architecture(VHDLModel_Architecture):
@classmethod
def parse(cls, architectureNode: Iir):
name = GetNameOfNode(architectureNode)
entityName = GetNameOfNode(nodes.Get_Entity_Name(architectureNode))
entity = EntitySymbol(entityName)
-
- architecture = cls(name, entity)
-
- for item in GetDeclaredItemsFromChainedNodes(
+ declaredItems = GetDeclaredItemsFromChainedNodes(
nodes.Get_Declaration_Chain(architectureNode), "architecture", name
- ):
- architecture.DeclaredItems.append(item)
+ )
+ bodyItems = []
- return architecture
+ return cls(name, entity, declaredItems, bodyItems)
def resolve(self):
pass
@@ -119,54 +104,41 @@ class Component(VHDLModel_Component):
@classmethod
def parse(cls, componentNode: Iir):
name = GetNameOfNode(componentNode)
+ generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(componentNode))
+ ports = GetPortsFromChainedNodes(nodes.Get_Port_Chain(componentNode))
- component = cls(name)
-
- for generic in GetGenericsFromChainedNodes(
- nodes.Get_Generic_Chain(componentNode)
- ):
- component.GenericItems.append(generic)
-
- for port in GetPortsFromChainedNodes(nodes.Get_Port_Chain(componentNode)):
- component.PortItems.append(port)
-
- return component
+ return cls(name, generics, ports)
@export
-class Package(VHDLModel_Package, GHDLMixin):
+class Package(VHDLModel_Package):
@classmethod
- def parse(cls, libraryUnit: Iir):
- name = GetNameOfNode(libraryUnit)
-
- package = cls(name)
+ def parse(cls, packageNode: Iir):
+ name = GetNameOfNode(packageNode)
+ generics = (
+ None # GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(packageNode))
+ )
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ nodes.Get_Declaration_Chain(packageNode), "package", name
+ )
- for item in GetDeclaredItemsFromChainedNodes(
- nodes.Get_Declaration_Chain(libraryUnit), "package", name
- ):
- package.DeclaredItems.append(item)
-
- return package
+ return cls(name, generics, declaredItems)
@export
-class PackageBody(VHDLModel_PackageBody, GHDLMixin):
+class PackageBody(VHDLModel_PackageBody):
@classmethod
- def parse(cls, libraryUnit: Iir):
- name = GetNameOfNode(libraryUnit)
-
- packageBody = cls(name)
-
- for item in GetDeclaredItemsFromChainedNodes(
- nodes.Get_Declaration_Chain(libraryUnit), "package body", name
- ):
- packageBody.DeclaredItems.append(item)
+ def parse(cls, packageBodyNode: Iir):
+ name = GetNameOfNode(packageBodyNode)
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ nodes.Get_Declaration_Chain(packageBodyNode), "package", name
+ )
- return packageBody
+ return cls(name, declaredItems)
@export
-class Context(VHDLModel_Context, GHDLMixin):
+class Context(VHDLModel_Context):
@classmethod
def parse(cls, libraryUnit: Iir):
name = GetNameOfNode(libraryUnit)
@@ -174,8 +146,8 @@ class Context(VHDLModel_Context, GHDLMixin):
@export
-class Configuration(VHDLModel_Configuration, GHDLMixin):
+class Configuration(VHDLModel_Configuration):
@classmethod
- def parse(cls, libraryUnit: Iir):
- name = GetNameOfNode(libraryUnit)
+ def parse(cls, configuration: Iir):
+ name = GetNameOfNode(configuration)
return cls(name)
diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py
index eac92c8a6..f720e69b4 100644
--- a/pyGHDL/dom/InterfaceItem.py
+++ b/pyGHDL/dom/InterfaceItem.py
@@ -46,7 +46,7 @@ from pyVHDLModel.VHDLModel import (
from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.libghdl.vhdl.nodes import Null_Iir
from pyGHDL.dom._Utils import GetNameOfNode, GetModeOfNode
-from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode, GetExpressionFromNode
+from pyGHDL.dom._Translate import GetSubTypeIndicationFromNode, GetExpressionFromNode
__all__ = []
@@ -58,13 +58,11 @@ class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem):
def parse(cls, generic):
name = GetNameOfNode(generic)
mode = GetModeOfNode(generic)
- subTypeIndication = GetSubtypeIndicationFromNode(generic, "generic", name)
+ subTypeIndication = GetSubTypeIndicationFromNode(generic, "generic", name)
default = nodes.Get_Default_Value(generic)
value = GetExpressionFromNode(default) if default else None
- g = cls(name, mode, subTypeIndication, value)
-
- return g
+ return cls(name, mode, subTypeIndication, value)
def __init__(
self,
@@ -84,16 +82,14 @@ class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem):
def parse(cls, port):
name = GetNameOfNode(port)
mode = GetModeOfNode(port)
- subTypeIndication = GetSubtypeIndicationFromNode(port, "port", name)
+ subTypeIndication = GetSubTypeIndicationFromNode(port, "port", name)
defaultValue = nodes.Get_Default_Value(port)
value = (
GetExpressionFromNode(defaultValue) if defaultValue != Null_Iir else None
)
- p = cls(name, mode, subTypeIndication, value)
-
- return p
+ return cls(name, mode, subTypeIndication, value)
def __init__(
self,
@@ -113,16 +109,14 @@ class ParameterConstantInterfaceItem(VHDLModel_ParameterConstantInterfaceItem):
def parse(cls, parameter):
name = GetNameOfNode(parameter)
mode = GetModeOfNode(parameter)
- subTypeIndication = GetSubtypeIndicationFromNode(parameter, "parameter", name)
+ subTypeIndication = GetSubTypeIndicationFromNode(parameter, "parameter", name)
defaultValue = nodes.Get_Default_Value(parameter)
value = (
GetExpressionFromNode(defaultValue) if defaultValue != Null_Iir else None
)
- param = cls(name, mode, subTypeIndication, value)
-
- return param
+ return cls(name, mode, subTypeIndication, value)
def __init__(
self,
@@ -142,16 +136,14 @@ class ParameterVariableInterfaceItem(VHDLModel_ParameterVariableInterfaceItem):
def parse(cls, parameter):
name = GetNameOfNode(parameter)
mode = GetModeOfNode(parameter)
- subTypeIndication = GetSubtypeIndicationFromNode(parameter, "parameter", name)
+ subTypeIndication = GetSubTypeIndicationFromNode(parameter, "parameter", name)
defaultValue = nodes.Get_Default_Value(parameter)
value = (
GetExpressionFromNode(defaultValue) if defaultValue != Null_Iir else None
)
- param = cls(name, mode, subTypeIndication, value)
-
- return param
+ return cls(name, mode, subTypeIndication, value)
def __init__(
self,
@@ -171,16 +163,14 @@ class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem):
def parse(cls, parameter):
name = GetNameOfNode(parameter)
mode = GetModeOfNode(parameter)
- subTypeIndication = GetSubtypeIndicationFromNode(parameter, "parameter", name)
+ subTypeIndication = GetSubTypeIndicationFromNode(parameter, "parameter", name)
defaultValue = nodes.Get_Default_Value(parameter)
value = (
GetExpressionFromNode(defaultValue) if defaultValue != Null_Iir else None
)
- param = cls(name, mode, subTypeIndication, value)
-
- return param
+ return cls(name, mode, subTypeIndication, value)
def __init__(
self,
diff --git a/pyGHDL/dom/Literal.py b/pyGHDL/dom/Literal.py
index 209712ba3..a2e86b389 100644
--- a/pyGHDL/dom/Literal.py
+++ b/pyGHDL/dom/Literal.py
@@ -30,9 +30,11 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
+from pyGHDL.libghdl._types import Iir
from pydecor import export
from pyVHDLModel.VHDLModel import (
+ EnumerationLiteral as VHDLModel_EnumerationLiteral,
IntegerLiteral as VHDLModel_IntegerLiteral,
FloatingPointLiteral as VHDLModel_FloatingPointLiteral,
PhysicalIntegerLiteral as VHDLModel_PhysicalIntegerLiteral,
@@ -48,9 +50,17 @@ __all__ = []
@export
+class EnumerationLiteral(VHDLModel_EnumerationLiteral):
+ @classmethod
+ def parse(cls, literalNode: Iir) -> "EnumerationLiteral":
+ literalName = GetNameOfNode(literalNode)
+ return cls(literalName)
+
+
+@export
class IntegerLiteral(VHDLModel_IntegerLiteral):
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir) -> "IntegerLiteral":
value = nodes.Get_Value(node)
return cls(value)
@@ -58,7 +68,7 @@ class IntegerLiteral(VHDLModel_IntegerLiteral):
@export
class FloatingPointLiteral(VHDLModel_FloatingPointLiteral):
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir) -> "FloatingPointLiteral":
value = nodes.Get_Fp_Value(node)
return cls(value)
@@ -66,7 +76,7 @@ class FloatingPointLiteral(VHDLModel_FloatingPointLiteral):
@export
class PhysicalIntegerLiteral(VHDLModel_PhysicalIntegerLiteral):
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir) -> "PhysicalIntegerLiteral":
value = nodes.Get_Value(node)
unit = nodes.Get_Unit_Name(node)
unitName = GetNameOfNode(unit)
@@ -77,7 +87,7 @@ class PhysicalIntegerLiteral(VHDLModel_PhysicalIntegerLiteral):
@export
class PhysicalFloatingLiteral(VHDLModel_PhysicalFloatingLiteral):
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir) -> "PhysicalFloatingLiteral":
value = nodes.Get_Fp_Value(node)
unit = nodes.Get_Unit_Name(node)
unitName = GetNameOfNode(unit)
@@ -88,7 +98,7 @@ class PhysicalFloatingLiteral(VHDLModel_PhysicalFloatingLiteral):
@export
class CharacterLiteral(VHDLModel_CharacterLiteral):
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir) -> "CharacterLiteral":
identifier = nodes.Get_Identifier(node)
value = name_table.Get_Character(identifier)
return cls(value)
@@ -97,7 +107,7 @@ class CharacterLiteral(VHDLModel_CharacterLiteral):
@export
class StringLiteral(VHDLModel_StringLiteral):
@classmethod
- def parse(cls, node):
+ def parse(cls, node: Iir) -> "StringLiteral":
stringID = nodes.Get_String8_Id(node)
value = name_table.Get_Name_Ptr(stringID)
return cls(value)
diff --git a/pyGHDL/dom/NonStandard.py b/pyGHDL/dom/NonStandard.py
index 63a35dc7f..9e2950f03 100644
--- a/pyGHDL/dom/NonStandard.py
+++ b/pyGHDL/dom/NonStandard.py
@@ -58,8 +58,8 @@ from pyGHDL.libghdl import (
utils,
)
from pyGHDL.libghdl.vhdl import nodes, sem_lib, parse
-from pyGHDL.dom._Utils import GetIirKindOfNode
-from pyGHDL.dom.Common import DOMException, GHDLMixin
+from pyGHDL.dom._Utils import GetIirKindOfNode, CheckForErrors
+from pyGHDL.dom.Common import DOMException
from pyGHDL.dom.DesignUnit import (
Entity,
Architecture,
@@ -103,14 +103,13 @@ class Library(VHDLModel_Library):
@export
-class Document(VHDLModel_Document, GHDLMixin):
+class Document(VHDLModel_Document):
__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:
@@ -125,12 +124,11 @@ class Document(VHDLModel_Document, GHDLMixin):
if self.__ghdlSourceFileEntry == files_map.No_Source_File_Entry:
raise LibGHDLException("Cannot load file '{!s}'".format(self.Path))
- self.CheckForErrors()
+ CheckForErrors()
# Parse input file
self.__ghdlFile = sem_lib.Load_File(self.__ghdlSourceFileEntry)
-
- self.CheckForErrors()
+ CheckForErrors()
def parse(self):
firstUnit = nodes.Get_First_Design_Unit(self.__ghdlFile)
diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py
index 1f1f8f6d9..a5ea4b1ff 100644
--- a/pyGHDL/dom/Object.py
+++ b/pyGHDL/dom/Object.py
@@ -33,11 +33,13 @@
from pyGHDL.libghdl.vhdl import nodes
from pydecor import export
-from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode, GetExpressionFromNode
+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,
Expression,
SubTypeOrSymbol,
@@ -60,12 +62,28 @@ class Constant(VHDLModel_Constant):
@classmethod
def parse(cls, node):
name = GetNameOfNode(node)
- subTypeIndication = GetSubtypeIndicationFromNode(node, "constant", name)
+ subTypeIndication = GetSubTypeIndicationFromNode(node, "constant", name)
defaultExpression = GetExpressionFromNode(nodes.Get_Default_Value(node))
- constant = cls(name, subTypeIndication, defaultExpression)
+ return cls(name, subTypeIndication, defaultExpression)
- return constant
+
+@export
+class DeferredConstant(VHDLModel_DeferredConstant):
+ def __init__(self, name: str, subType: SubTypeOrSymbol):
+ super().__init__(name)
+
+ self._name = name
+ self._subType = subType
+
+ @classmethod
+ def parse(cls, node):
+ name = GetNameOfNode(node)
+ subTypeIndication = GetSubTypeIndicationFromNode(
+ node, "deferred constant", name
+ )
+
+ return cls(name, subTypeIndication)
@export
@@ -82,12 +100,26 @@ class Variable(VHDLModel_Variable):
@classmethod
def parse(cls, node):
name = GetNameOfNode(node)
- subTypeIndication = GetSubtypeIndicationFromNode(node, "variable", name)
+ subTypeIndication = GetSubTypeIndicationFromNode(node, "variable", name)
defaultExpression = GetExpressionFromNode(nodes.Get_Default_Value(node))
- variable = cls(name, subTypeIndication, defaultExpression)
+ return cls(name, subTypeIndication, defaultExpression)
- return variable
+
+@export
+class SharedVariable(VHDLModel_SharedVariable):
+ def __init__(self, name: str, subType: SubTypeOrSymbol):
+ super().__init__(name)
+
+ self._name = name
+ self._subType = subType
+
+ @classmethod
+ def parse(cls, node):
+ name = GetNameOfNode(node)
+ subTypeIndication = GetSubTypeIndicationFromNode(node, "variable", name)
+
+ return cls(name, subTypeIndication)
@export
@@ -104,10 +136,8 @@ class Signal(VHDLModel_Signal):
@classmethod
def parse(cls, node):
name = GetNameOfNode(node)
- subTypeIndication = GetSubtypeIndicationFromNode(node, "signal", name)
+ subTypeIndication = GetSubTypeIndicationFromNode(node, "signal", name)
default = nodes.Get_Default_Value(node)
defaultExpression = GetExpressionFromNode(default) if default else None
- signal = cls(name, subTypeIndication, defaultExpression)
-
- return signal
+ return cls(name, subTypeIndication, defaultExpression)
diff --git a/pyGHDL/dom/Subprogram.py b/pyGHDL/dom/Subprogram.py
index b3c47bfe5..0f10ebf62 100644
--- a/pyGHDL/dom/Subprogram.py
+++ b/pyGHDL/dom/Subprogram.py
@@ -30,6 +30,8 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
+from typing import List
+
from pyGHDL.dom.Symbol import SimpleSubTypeSymbol
from pyGHDL.libghdl.vhdl import nodes
from pydecor import export
@@ -39,14 +41,27 @@ from pyVHDLModel.VHDLModel import (
Function as VHDLModel_Function,
Procedure as VHDLModel_Procedure,
SubTypeOrSymbol,
+ GenericInterfaceItem,
+ ParameterInterfaceItem,
)
from pyGHDL.libghdl._types import Iir
@export
class Function(VHDLModel_Function):
- def __init__(self, functionName: str, returnType: SubTypeOrSymbol):
+ def __init__(
+ self,
+ functionName: str,
+ returnType: SubTypeOrSymbol,
+ genericItems: List[GenericInterfaceItem] = None,
+ parameterItems: List[ParameterInterfaceItem] = None,
+ ):
super().__init__(functionName)
+
+ self._genericItems = [] if genericItems is None else [g for g in genericItems]
+ self._parameterItems = (
+ [] if parameterItems is None else [p for p in parameterItems]
+ )
self._returnType = returnType
@classmethod
@@ -57,27 +72,34 @@ class Function(VHDLModel_Function):
)
functionName = GetNameOfNode(node)
+
+ generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(node))
+ parameters = GetParameterFromChainedNodes(
+ nodes.Get_Interface_Declaration_Chain(node)
+ )
+
returnType = nodes.Get_Return_Type_Mark(node)
returnTypeName = GetNameOfNode(returnType)
-
returnTypeSymbol = SimpleSubTypeSymbol(returnTypeName)
- function = cls(functionName, returnTypeSymbol)
-
- for generic in GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(node)):
- function.GenericItems.append(generic)
- for port in GetParameterFromChainedNodes(
- nodes.Get_Interface_Declaration_Chain(node)
- ):
- function.ParameterItems.append(port)
- return function
+ return cls(functionName, returnTypeSymbol, generics, parameters)
@export
class Procedure(VHDLModel_Procedure):
- def __init__(self, procedureName: str):
+ def __init__(
+ self,
+ procedureName: str,
+ genericItems: List[GenericInterfaceItem] = None,
+ parameterItems: List[ParameterInterfaceItem] = None,
+ ):
super().__init__(procedureName)
+ 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):
from pyGHDL.dom._Translate import (
@@ -87,13 +109,9 @@ class Procedure(VHDLModel_Procedure):
procedureName = GetNameOfNode(node)
- procedure = cls(procedureName)
-
- for generic in GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(node)):
- procedure.GenericItems.append(generic)
- for port in GetParameterFromChainedNodes(
+ generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(node))
+ parameters = GetParameterFromChainedNodes(
nodes.Get_Interface_Declaration_Chain(node)
- ):
- procedure.ParameterItems.append(port)
+ )
- return procedure
+ return cls(procedureName, generics, parameters)
diff --git a/pyGHDL/dom/Symbol.py b/pyGHDL/dom/Symbol.py
index 1865e4481..d6d348f14 100644
--- a/pyGHDL/dom/Symbol.py
+++ b/pyGHDL/dom/Symbol.py
@@ -30,13 +30,15 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from typing import List
+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,
- ConstrainedSubTypeSymbol as VHDLModel_ConstrainedSubTypeSymbol,
+ ConstrainedScalarSubTypeSymbol as VHDLModel_ConstrainedScalarSubTypeSymbol,
+ ConstrainedCompositeSubTypeSymbol as VHDLModel_ConstrainedCompositeSubTypeSymbol,
EnumerationLiteralSymbol as VHDLModel_EnumerationLiteralSymbol,
SimpleObjectOrFunctionCallSymbol as VHDLModel_SimpleObjectOrFunctionCallSymbol,
IndexedObjectOrFunctionCallSymbol as VHDLModel_IndexedObjectOrFunctionCallSymbol,
@@ -66,15 +68,24 @@ class EnumerationLiteralSymbol(VHDLModel_EnumerationLiteralSymbol):
@export
class SimpleSubTypeSymbol(VHDLModel_SimpleSubTypeSymbol):
def __init__(self, subTypeName: str):
+ if isinstance(subTypeName, (List, Iterator)):
+ subTypeName = ".".join(subTypeName)
+
super().__init__(subTypeName=subTypeName)
+
+@export
+class ConstrainedScalarSubTypeSymbol(VHDLModel_ConstrainedScalarSubTypeSymbol):
+ def __init__(self, subTypeName: str, range: Range = None):
+ super().__init__(subTypeName=subTypeName, range=range)
+
@classmethod
def parse(cls, node):
pass
@export
-class ConstrainedSubTypeSymbol(VHDLModel_ConstrainedSubTypeSymbol):
+class ConstrainedCompositeSubTypeSymbol(VHDLModel_ConstrainedCompositeSubTypeSymbol):
def __init__(self, subTypeName: str, constraints: List[Constraint] = None):
super().__init__(subTypeName=subTypeName, constraints=constraints)
diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py
index c276387c7..2875f1bc2 100644
--- a/pyGHDL/dom/Type.py
+++ b/pyGHDL/dom/Type.py
@@ -30,21 +30,123 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
+from pyGHDL.dom.Common import DOMException
+from pyGHDL.dom.Literal import EnumerationLiteral
+from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode
+from pyGHDL.libghdl import utils
+
+from pyGHDL.libghdl.vhdl import nodes
+
+from pyGHDL.libghdl._types import Iir
from pydecor import export
+from pyGHDL.dom.Range import Range
from pyVHDLModel.VHDLModel import (
IntegerType as VHDLModel_IntegerType,
+ EnumeratedType as VHDLModel_EnumeratedType,
+ ArrayType as VHDLModel_ArrayType,
+ RecordTypeElement as VHDLModel_RecordTypeElement,
+ RecordType as VHDLModel_RecordType,
+ AccessType as VHDLModel_AccessType,
SubType as VHDLModel_SubType,
- Expression,
)
@export
class IntegerType(VHDLModel_IntegerType):
- def __init__(self, typeName: str, leftBound: Expression, rightBound: Expression):
+ def __init__(self, typeName: str, range: Range):
super().__init__(typeName)
- self._leftBound = leftBound
- self._rightBound = rightBound
+ self._leftBound = range.LeftBound
+ self._rightBound = range.RightBound
+
+
+@export
+class EnumeratedType(VHDLModel_EnumeratedType):
+ @classmethod
+ def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "EnumeratedType":
+ literals = []
+ enumerationLiterals = nodes.Get_Enumeration_Literal_List(typeDefinitionNode)
+ for enumerationLiteral in utils.flist_iter(enumerationLiterals):
+ literal = EnumerationLiteral.parse(enumerationLiteral)
+ literals.append(literal)
+
+ return cls(typeName, literals)
+
+
+@export
+class ArrayType(VHDLModel_ArrayType):
+ @classmethod
+ def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "ArrayType":
+ from pyGHDL.dom._Translate import (
+ GetSimpleTypeFromNode,
+ GetSubTypeIndicationFromIndicationNode,
+ )
+
+ indices = []
+ indexDefinitions = nodes.Get_Index_Subtype_Definition_List(typeDefinitionNode)
+ for index in utils.flist_iter(indexDefinitions):
+ indexKind = GetIirKindOfNode(index)
+ if indexKind == nodes.Iir_Kind.Simple_Name:
+ indexSubType = GetSimpleTypeFromNode(index)
+ indices.append(indexSubType)
+ else:
+ raise DOMException(
+ "Unknown kind '{kind}' for an index in the array definition of `{typeName}`.".format(
+ kind=indexKind.name, typeName=typeName
+ )
+ )
+
+ elementSubTypeIndication = nodes.Get_Element_Subtype_Indication(
+ typeDefinitionNode
+ )
+ elementSubType = GetSubTypeIndicationFromIndicationNode(
+ elementSubTypeIndication, "array declaration", typeName
+ )
+
+ return cls(typeName, indices, elementSubType)
+
+
+@export
+class RecordTypeElement(VHDLModel_RecordTypeElement):
+ @classmethod
+ def parse(cls, elementDeclarationNode: Iir) -> "RecordTypeElement":
+ from pyGHDL.dom._Translate import GetSubTypeIndicationFromNode
+
+ elementName = GetNameOfNode(elementDeclarationNode)
+ elementType = GetSubTypeIndicationFromNode(
+ elementDeclarationNode, "record element", elementName
+ )
+
+ return cls(elementName, elementType)
+
+
+@export
+class RecordType(VHDLModel_RecordType):
+ @classmethod
+ def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "RecordType":
+ elements = []
+ elementDeclarations = nodes.Get_Elements_Declaration_List(typeDefinitionNode)
+ for elementDeclaration in utils.flist_iter(elementDeclarations):
+ element = RecordTypeElement.parse(elementDeclaration)
+ elements.append(element)
+
+ return cls(typeName, elements)
+
+
+@export
+class AccessType(VHDLModel_AccessType):
+ @classmethod
+ def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "AccessType":
+ from pyGHDL.dom._Translate import GetSubTypeIndicationFromIndicationNode
+
+ designatedSubtypeIndication = nodes.Get_Designated_Subtype_Indication(
+ typeDefinitionNode
+ )
+ designatedSubType = GetSubTypeIndicationFromIndicationNode(
+ designatedSubtypeIndication, "access type", typeName
+ )
+
+ return cls(typeName, designatedSubType)
@export
diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py
index 2b2a44e60..cb9448f09 100644
--- a/pyGHDL/dom/_Translate.py
+++ b/pyGHDL/dom/_Translate.py
@@ -30,7 +30,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from typing import List
+from typing import List, Generator
from pydecor import export
@@ -40,20 +40,38 @@ from pyVHDLModel.VHDLModel import (
Expression,
SubTypeOrSymbol,
BaseType,
+ GenericInterfaceItem,
+ PortInterfaceItem,
+ ParameterInterfaceItem,
+ ModelEntity,
)
from pyGHDL.libghdl import utils
from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
-from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode, GetPositionOfNode
+from pyGHDL.dom._Utils import (
+ GetNameOfNode,
+ GetIirKindOfNode,
+ GetPositionOfNode,
+ GetSelectedName,
+)
from pyGHDL.dom.Common import DOMException
from pyGHDL.dom.Symbol import (
SimpleObjectOrFunctionCallSymbol,
SimpleSubTypeSymbol,
- ConstrainedSubTypeSymbol,
+ ConstrainedCompositeSubTypeSymbol,
IndexedObjectOrFunctionCallSymbol,
+ ConstrainedScalarSubTypeSymbol,
+)
+from pyGHDL.dom.Type import (
+ IntegerType,
+ SubType,
+ ArrayType,
+ RecordType,
+ EnumeratedType,
+ RecordTypeElement,
+ AccessType,
)
-from pyGHDL.dom.Type import IntegerType, SubType
from pyGHDL.dom.Range import Range, RangeExpression
from pyGHDL.dom.Literal import (
IntegerLiteral,
@@ -62,6 +80,7 @@ from pyGHDL.dom.Literal import (
StringLiteral,
PhysicalIntegerLiteral,
PhysicalFloatingLiteral,
+ EnumerationLiteral,
)
from pyGHDL.dom.Expression import (
SubtractionExpression,
@@ -104,46 +123,6 @@ __all__ = []
@export
-def GetSubtypeIndicationFromNode(node: Iir, entity: str, name: str) -> SubTypeOrSymbol:
- subTypeIndication = nodes.Get_Subtype_Indication(node)
- if subTypeIndication is nodes.Null_Iir:
- return None
- subTypeKind = GetIirKindOfNode(subTypeIndication)
-
- if subTypeKind == nodes.Iir_Kind.Simple_Name:
- subTypeName = GetNameOfNode(subTypeIndication)
-
- subType = SimpleSubTypeSymbol(subTypeName)
- elif subTypeKind == nodes.Iir_Kind.Array_Subtype_Definition:
- typeMark = nodes.Get_Subtype_Type_Mark(subTypeIndication)
- typeMarkName = GetNameOfNode(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:
- position = GetPositionOfNode(node)
- raise DOMException(
- "Unknown subtype kind '{kind}' of subtype indication '{indication}' while parsing {entity} '{name}' at {file}:{line}:{column}.".format(
- kind=subTypeKind,
- indication=subTypeIndication,
- entity=entity,
- name=name,
- file=position.Filename,
- line=position.Line,
- column=position.Column,
- )
- )
-
- return subType
-
-
-@export
def GetArrayConstraintsFromSubtypeIndication(
subTypeIndication: Iir,
) -> List[Constraint]:
@@ -155,6 +134,12 @@ def GetArrayConstraintsFromSubtypeIndication(
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.")
@@ -177,14 +162,98 @@ def GetArrayConstraintsFromSubtypeIndication(
@export
def GetTypeFromNode(node: Iir) -> BaseType:
typeName = GetNameOfNode(node)
- leftBound = IntegerLiteral(0)
- rightBound = IntegerLiteral(15)
+ typeDefinition = nodes.Get_Type_Definition(node)
+
+ kind = GetIirKindOfNode(typeDefinition)
+ if kind == nodes.Iir_Kind.Range_Expression:
+ r = GetRangeFromNode(typeDefinition)
+
+ return IntegerType(typeName, r)
+ 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")
+
+ return ArrayType
+ 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)
+ else:
+ position = GetPositionOfNode(typeDefinition)
+ raise DOMException(
+ "Unknown type definition kind '{kindName}'({kind}) for type '{name}' at {file}:{line}:{column}.".format(
+ kind=kind,
+ kindName=kind.name,
+ name=typeName,
+ file=position.Filename,
+ line=position.Line,
+ column=position.Column,
+ )
+ )
+
+
+@export
+def GetSubTypeIndicationFromNode(node: Iir, entity: str, name: str) -> SubTypeOrSymbol:
+ subTypeIndicationNode = nodes.Get_Subtype_Indication(node)
+ # if subTypeIndicationNode is nodes.Null_Iir:
+ # return None
+ return GetSubTypeIndicationFromIndicationNode(subTypeIndicationNode, entity, name)
+
+
+@export
+def GetSubTypeIndicationFromIndicationNode(
+ subTypeIndicationNode: Iir, entity: str, name: str
+) -> SubTypeOrSymbol:
+ kind = GetIirKindOfNode(subTypeIndicationNode)
+ if kind == nodes.Iir_Kind.Simple_Name:
+ return GetSimpleTypeFromNode(subTypeIndicationNode)
+ elif kind == nodes.Iir_Kind.Selected_Name:
+ return GetSimpleTypeFromNode(subTypeIndicationNode)
+ elif kind == nodes.Iir_Kind.Subtype_Definition:
+ return GetScalarConstrainedSubTypeFromNode(subTypeIndicationNode)
+ elif kind == nodes.Iir_Kind.Array_Subtype_Definition:
+ return GetCompositeConstrainedSubTypeFromNode(subTypeIndicationNode)
+ else:
+ raise DOMException(
+ "Unknown kind '{kind}' for an subtype indication in a {entity} of `{name}`.".format(
+ kind=kind.name, entity=entity, name=name
+ )
+ )
+
+
+@export
+def GetSimpleTypeFromNode(subTypeIndicationNode: Iir) -> SimpleSubTypeSymbol:
+ subTypeName = GetSelectedName(subTypeIndicationNode)
+ return SimpleSubTypeSymbol(subTypeName)
+
+
+@export
+def GetScalarConstrainedSubTypeFromNode(
+ subTypeIndicationNode: Iir,
+) -> ConstrainedScalarSubTypeSymbol:
+ typeMark = nodes.Get_Subtype_Type_Mark(subTypeIndicationNode)
+ typeMarkName = GetNameOfNode(typeMark)
+ rangeConstraint = nodes.Get_Range_Constraint(subTypeIndicationNode)
+ r = GetRangeFromNode(rangeConstraint)
+ return ConstrainedScalarSubTypeSymbol(typeMarkName, r)
+
+
+@export
+def GetCompositeConstrainedSubTypeFromNode(
+ subTypeIndicationNode: Iir,
+) -> ConstrainedCompositeSubTypeSymbol:
+ typeMark = nodes.Get_Subtype_Type_Mark(subTypeIndicationNode)
+ typeMarkName = GetNameOfNode(typeMark)
- return IntegerType(typeName, leftBound, rightBound)
+ constraints = GetArrayConstraintsFromSubtypeIndication(subTypeIndicationNode)
+ return ConstrainedCompositeSubTypeSymbol(typeMarkName, constraints)
@export
-def GetSubTypeFromNode(node: Iir) -> BaseType:
+def GetSubTypeFromNode(node: Iir) -> SubTypeOrSymbol:
subTypeName = GetNameOfNode(node)
return SubType(subTypeName)
@@ -268,10 +337,10 @@ def GetExpressionFromNode(node: Iir) -> Expression:
return cls.parse(node)
-# FIXME: rewrite to generator
@export
-def GetGenericsFromChainedNodes(nodeChain: Iir):
- result = []
+def GetGenericsFromChainedNodes(
+ nodeChain: Iir,
+) -> Generator[GenericInterfaceItem, None, None]:
for generic in utils.chain_iter(nodeChain):
kind = GetIirKindOfNode(generic)
if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
@@ -279,7 +348,7 @@ def GetGenericsFromChainedNodes(nodeChain: Iir):
genericConstant = GenericConstantInterfaceItem.parse(generic)
- result.append(genericConstant)
+ yield genericConstant
else:
position = GetPositionOfNode(generic)
raise DOMException(
@@ -293,13 +362,11 @@ def GetGenericsFromChainedNodes(nodeChain: Iir):
)
)
- return result
-
-# FIXME: rewrite to generator
@export
-def GetPortsFromChainedNodes(nodeChain: Iir):
- result = []
+def GetPortsFromChainedNodes(
+ nodeChain: Iir,
+) -> Generator[PortInterfaceItem, None, None]:
for port in utils.chain_iter(nodeChain):
kind = GetIirKindOfNode(port)
if kind == nodes.Iir_Kind.Interface_Signal_Declaration:
@@ -307,7 +374,7 @@ def GetPortsFromChainedNodes(nodeChain: Iir):
portSignal = PortSignalInterfaceItem.parse(port)
- result.append(portSignal)
+ yield portSignal
else:
position = GetPositionOfNode(port)
raise DOMException(
@@ -321,27 +388,25 @@ def GetPortsFromChainedNodes(nodeChain: Iir):
)
)
- return result
-
-# FIXME: rewrite to generator
@export
-def GetParameterFromChainedNodes(nodeChain: Iir):
- result = []
+def GetParameterFromChainedNodes(
+ nodeChain: Iir,
+) -> Generator[ParameterInterfaceItem, None, None]:
for parameter in utils.chain_iter(nodeChain):
kind = GetIirKindOfNode(parameter)
if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
from pyGHDL.dom.InterfaceItem import ParameterConstantInterfaceItem
- result.append(ParameterConstantInterfaceItem.parse(parameter))
+ yield ParameterConstantInterfaceItem.parse(parameter)
elif kind == nodes.Iir_Kind.Interface_Variable_Declaration:
from pyGHDL.dom.InterfaceItem import ParameterVariableInterfaceItem
- result.append(ParameterVariableInterfaceItem.parse(parameter))
+ yield ParameterVariableInterfaceItem.parse(parameter)
elif kind == nodes.Iir_Kind.Interface_Signal_Declaration:
from pyGHDL.dom.InterfaceItem import ParameterSignalInterfaceItem
- result.append(ParameterSignalInterfaceItem.parse(parameter))
+ yield ParameterSignalInterfaceItem.parse(parameter)
else:
position = GetPositionOfNode(parameter)
raise DOMException(
@@ -355,43 +420,50 @@ def GetParameterFromChainedNodes(nodeChain: Iir):
)
)
- return result
-
-def GetDeclaredItemsFromChainedNodes(nodeChain: Iir, entity: str, name: str):
- result = []
+def GetDeclaredItemsFromChainedNodes(
+ nodeChain: Iir, entity: str, name: str
+) -> Generator[ModelEntity, None, None]:
for item in utils.chain_iter(nodeChain):
kind = GetIirKindOfNode(item)
if kind == nodes.Iir_Kind.Constant_Declaration:
from pyGHDL.dom.Object import Constant
- result.append(Constant.parse(item))
+ yield Constant.parse(item)
+
+ elif kind == nodes.Iir_Kind.Variable_Declaration:
+ from pyGHDL.dom.Object import SharedVariable
+
+ if nodes.Get_Shared_Flag(item):
+ yield SharedVariable.parse(item)
+ else:
+ raise DOMException("Found non-shared variable.")
elif kind == nodes.Iir_Kind.Signal_Declaration:
from pyGHDL.dom.Object import Signal
- result.append(Signal.parse(item))
+ yield Signal.parse(item)
elif kind == nodes.Iir_Kind.Type_Declaration:
- result.append(GetTypeFromNode(item))
+ yield GetTypeFromNode(item)
elif kind == nodes.Iir_Kind.Anonymous_Type_Declaration:
- result.append(GetTypeFromNode(item))
+ yield GetTypeFromNode(item)
elif kind == nodes.Iir_Kind.Subtype_Declaration:
- result.append(GetSubTypeFromNode(item))
+ yield GetSubTypeFromNode(item)
elif kind == nodes.Iir_Kind.Function_Declaration:
- result.append(Function.parse(item))
+ yield Function.parse(item)
elif kind == nodes.Iir_Kind.Function_Body:
# procedureName = NodeToName(item)
print("found function body '{name}'".format(name="????"))
elif kind == nodes.Iir_Kind.Procedure_Declaration:
- result.append(Procedure.parse(item))
+ yield Procedure.parse(item)
elif kind == nodes.Iir_Kind.Procedure_Body:
# procedureName = NodeToName(item)
print("found procedure body '{name}'".format(name="????"))
elif kind == nodes.Iir_Kind.Object_Alias_Declaration:
- result.append(GetAliasFromNode(item))
+ yield GetAliasFromNode(item)
elif kind == nodes.Iir_Kind.Component_Declaration:
from pyGHDL.dom.DesignUnit import Component
- result.append(Component.parse(item))
+ yield Component.parse(item)
else:
position = GetPositionOfNode(item)
raise DOMException(
@@ -406,8 +478,6 @@ def GetDeclaredItemsFromChainedNodes(nodeChain: Iir, entity: str, name: str):
)
)
- return result
-
def GetAliasFromNode(node: Iir):
aliasName = GetNameOfNode(node)
diff --git a/pyGHDL/dom/_Utils.py b/pyGHDL/dom/_Utils.py
index e75c5f36a..1c109c9dc 100644
--- a/pyGHDL/dom/_Utils.py
+++ b/pyGHDL/dom/_Utils.py
@@ -30,13 +30,15 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from pyGHDL.libghdl._types import Iir
from pydecor import export
+from pyGHDL.dom.Common import DOMException
from pyVHDLModel.VHDLModel import Mode
-from pyGHDL.libghdl import LibGHDLException, name_table, files_map
+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
@@ -52,9 +54,33 @@ __MODE_TRANSLATION = {
@export
+def CheckForErrors() -> None:
+ errorCount = errorout_memory.Get_Nbr_Messages()
+ errors = []
+ 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))
+ message = errorout_memory.Get_Error_Message(i + 1)
+
+ errors.append(
+ "{file}:{line}:{column}: {msg}".format(
+ file=fileName, line=rec.line, column=rec.offset, msg=message
+ )
+ )
+
+ raise DOMException("Error raised in libghdl.") from LibGHDLException(
+ "libghdl: Internal error.", errors
+ )
+
+
+@export
def GetIirKindOfNode(node: Iir) -> nodes.Iir_Kind:
- # This function is the most likely to be called on a Null_Iir node
- assert node != 0
+ """Return the kind of a node in the IIR tree."""
+
+ if node == Null_Iir:
+ raise ValueError("Parameter 'node' must not be 'Null_iir'.")
+
kind: int = nodes.Get_Kind(node)
return nodes.Iir_Kind(kind)
@@ -62,13 +88,38 @@ 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'.")
+
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:`port`."""
+ """Return the mode of a :obj:`node`."""
+
+ if node == Null_Iir:
+ raise ValueError("Parameter 'node' must not be 'Null_iir'.")
+
try:
return __MODE_TRANSLATION[nodes.Get_Mode(node)]
except KeyError:
@@ -77,6 +128,11 @@ def GetModeOfNode(node: Iir) -> 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))
diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py
index f19125811..10def8503 100644
--- a/pyGHDL/dom/formatting/prettyprint.py
+++ b/pyGHDL/dom/formatting/prettyprint.py
@@ -4,13 +4,22 @@ from pydecor import export
from pyGHDL.dom.Misc import Alias
from pyGHDL.dom.Subprogram import Procedure
-from pyGHDL.dom.Type import IntegerType, SubType
+from pyGHDL.dom.Type import (
+ IntegerType,
+ SubType,
+ ArrayType,
+ RecordType,
+ AccessType,
+ EnumeratedType,
+)
from pyVHDLModel.VHDLModel import (
GenericInterfaceItem,
NamedEntity,
PortInterfaceItem,
WithDefaultExpression,
Function,
+ BaseType,
+ Type,
)
from pyGHDL import GHDLBaseException
@@ -24,14 +33,14 @@ from pyGHDL.dom.DesignUnit import (
Context,
Component,
)
-from pyGHDL.dom.Object import Constant, Signal
+from pyGHDL.dom.Object import Constant, Signal, SharedVariable
from pyGHDL.dom.InterfaceItem import (
GenericConstantInterfaceItem,
PortSignalInterfaceItem,
)
from pyGHDL.dom.Symbol import (
SimpleSubTypeSymbol,
- ConstrainedSubTypeSymbol,
+ ConstrainedCompositeSubTypeSymbol,
)
@@ -54,7 +63,7 @@ class PrettyPrint:
buffer = []
prefix = " " * level
buffer.append("{prefix}Libraries:".format(prefix=prefix))
- for library in design.Libraries:
+ for library in design.Libraries.values():
for line in self.formatLibrary(library, level + 1):
buffer.append(line)
buffer.append("{prefix}Documents:".format(prefix=prefix))
@@ -74,18 +83,18 @@ class PrettyPrint:
for entity in library.Entities:
for line in self.formatEntity(entity, level + 1):
buffer.append(line)
- buffer.append("{prefix}Architectures:".format(prefix=prefix))
- for architecture in library.Architectures:
- for line in self.formatArchitecture(architecture, level + 1):
- buffer.append(line)
+ # buffer.append("{prefix}Architectures:".format(prefix=prefix))
+ # for architecture in library.Architectures:
+ # for line in self.formatArchitecture(architecture, level + 1):
+ # buffer.append(line)
buffer.append("{prefix}Packages:".format(prefix=prefix))
for package in library.Packages:
for line in self.formatPackage(package, level + 1):
buffer.append(line)
- buffer.append("{prefix}PackageBodies:".format(prefix=prefix))
- for packageBodies in library.PackageBodies:
- for line in self.formatPackageBody(packageBodies, level + 1):
- buffer.append(line)
+ # buffer.append("{prefix}PackageBodies:".format(prefix=prefix))
+ # for packageBodies in library.PackageBodies:
+ # for line in self.formatPackageBody(packageBodies, level + 1):
+ # buffer.append(line)
buffer.append("{prefix}Configurations:".format(prefix=prefix))
for configuration in library.Configurations:
for line in self.formatConfiguration(configuration, level + 1):
@@ -302,6 +311,16 @@ class PrettyPrint:
expr=str(item.DefaultExpression),
)
)
+ elif isinstance(item, SharedVariable):
+ buffer.append(
+ "{prefix}- shared variable {name} : {subtype}".format(
+ prefix=prefix,
+ name=item.Name,
+ subtype=self.formatSubtypeIndication(
+ item.SubType, "shared variable", item.Name
+ ),
+ )
+ )
elif isinstance(item, Signal):
buffer.append(
"{prefix}- signal {name} : {subtype}{initValue}".format(
@@ -315,15 +334,9 @@ class PrettyPrint:
else "",
)
)
- elif isinstance(item, IntegerType):
+ elif isinstance(item, Type):
buffer.append(
- "{prefix}- type {name} is range {range}".format(
- prefix=prefix,
- name=item.Name,
- range="{left!s} to {right!s}".format(
- left=item.LeftBound, right=item.RightBound
- ),
- )
+ "{prefix}- {type}".format(prefix=prefix, type=self.formatType(item))
)
elif isinstance(item, SubType):
buffer.append(
@@ -364,10 +377,31 @@ class PrettyPrint:
return buffer
+ def formatType(self, item: BaseType) -> str:
+ result = "type {name} is ".format(name=item.Name)
+ if isinstance(item, IntegerType):
+ result += "range {left!s} to {right!s}".format(
+ left=item.LeftBound, right=item.RightBound
+ )
+ elif isinstance(item, EnumeratedType):
+ result += "(........)"
+ elif isinstance(item, ArrayType):
+ result += "array(........) of ....."
+ elif isinstance(item, RecordType):
+ result += "record ..... end record"
+ elif isinstance(item, AccessType):
+ result += "access ....."
+ else:
+ raise PrettyPrintException(
+ "Unknown type '{name}'".format(name=item.__class__.__name__)
+ )
+
+ return result
+
def formatSubtypeIndication(self, subTypeIndication, entity: str, name: str) -> str:
if isinstance(subTypeIndication, SimpleSubTypeSymbol):
return "{type}".format(type=subTypeIndication.SymbolName)
- elif isinstance(subTypeIndication, ConstrainedSubTypeSymbol):
+ elif isinstance(subTypeIndication, ConstrainedCompositeSubTypeSymbol):
ranges = [str(c.Range) for c in subTypeIndication.Constraints]
constraints = ", ".join(ranges)
@@ -376,8 +410,8 @@ class PrettyPrint:
)
else:
raise PrettyPrintException(
- "Unhandled constraint kind for {entity} '{name}'.".format(
- entity=entity, name=name
+ "Unhandled subtype kind '{type}' for {entity} '{name}'.".format(
+ type=subTypeIndication.__class__.__name__, entity=entity, name=name
)
)
diff --git a/pyGHDL/libghdl/__init__.py b/pyGHDL/libghdl/__init__.py
index 0d3c75fa1..525710590 100644
--- a/pyGHDL/libghdl/__init__.py
+++ b/pyGHDL/libghdl/__init__.py
@@ -37,6 +37,7 @@ import os
import sys
from pathlib import Path
from shutil import which
+from typing import List
from pydecor import export
@@ -48,7 +49,15 @@ from pyGHDL.libghdl.version import __version__
class LibGHDLException(GHDLBaseException):
- pass
+ _internalErrors: List[str]
+
+ def __init__(self, message: str, errors: List[str]):
+ super().__init__(message)
+ self._internalErrors = errors
+
+ @property
+ def InternalErrors(self):
+ return self._internalErrors
def _get_libghdl_name() -> Path:
diff --git a/pyGHDL/libghdl/_decorator.py b/pyGHDL/libghdl/_decorator.py
index 2001cb37e..a680cc9d1 100644
--- a/pyGHDL/libghdl/_decorator.py
+++ b/pyGHDL/libghdl/_decorator.py
@@ -93,7 +93,7 @@ def BindToLibGHDL(subprogramName):
return None
elif typ is int:
return c_int32
- elif type is float:
+ elif typ is float:
return c_double
elif typ is bool:
return c_bool
diff --git a/pyGHDL/requirements.txt b/pyGHDL/requirements.txt
index e6070f92e..6198d8044 100644
--- a/pyGHDL/requirements.txt
+++ b/pyGHDL/requirements.txt
@@ -1,2 +1,3 @@
pydecor>=2.0.1
-pyVHDLModel==0.10.2
+pyVHDLModel==0.10.3
+#https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel