diff options
author | Unai Martinez-Corral <38422348+umarcor@users.noreply.github.com> | 2021-06-23 16:07:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-23 16:07:10 +0100 |
commit | c6283d9a9b40c3e9afeba912fcb13aa9d56b9c52 (patch) | |
tree | e1706cb19a2439e3d94657e54c688a36c703f048 /pyGHDL | |
parent | 983236ac3dfd0c455a0ac910a9a468ea2c81e5d9 (diff) | |
parent | 240b4fdd90a9f3ca04e8e168bffdc92bea2ca3f3 (diff) | |
download | ghdl-c6283d9a9b40c3e9afeba912fcb13aa9d56b9c52.tar.gz ghdl-c6283d9a9b40c3e9afeba912fcb13aa9d56b9c52.tar.bz2 ghdl-c6283d9a9b40c3e9afeba912fcb13aa9d56b9c52.zip |
DOM: Functions and types (#1804)
Diffstat (limited to 'pyGHDL')
-rwxr-xr-x | pyGHDL/cli/DOM.py | 20 | ||||
-rw-r--r-- | pyGHDL/dom/Common.py | 13 | ||||
-rw-r--r-- | pyGHDL/dom/DesignUnit.py | 100 | ||||
-rw-r--r-- | pyGHDL/dom/InterfaceItem.py | 32 | ||||
-rw-r--r-- | pyGHDL/dom/Literal.py | 22 | ||||
-rw-r--r-- | pyGHDL/dom/NonStandard.py | 12 | ||||
-rw-r--r-- | pyGHDL/dom/Object.py | 52 | ||||
-rw-r--r-- | pyGHDL/dom/Subprogram.py | 58 | ||||
-rw-r--r-- | pyGHDL/dom/Symbol.py | 17 | ||||
-rw-r--r-- | pyGHDL/dom/Type.py | 110 | ||||
-rw-r--r-- | pyGHDL/dom/_Translate.py | 232 | ||||
-rw-r--r-- | pyGHDL/dom/_Utils.py | 66 | ||||
-rw-r--r-- | pyGHDL/dom/formatting/prettyprint.py | 80 | ||||
-rw-r--r-- | pyGHDL/libghdl/__init__.py | 11 | ||||
-rw-r--r-- | pyGHDL/libghdl/_decorator.py | 2 | ||||
-rw-r--r-- | pyGHDL/requirements.txt | 3 |
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 |