aboutsummaryrefslogtreecommitdiffstats
path: root/pyGHDL/dom/_Translate.py
diff options
context:
space:
mode:
authorPatrick Lehmann <Patrick.Lehmann@plc2.de>2021-06-26 13:48:09 +0200
committerGitHub <noreply@github.com>2021-06-26 13:48:09 +0200
commit111fe055b2f0f3a0225d2553cf739572d691a14d (patch)
tree50d3a874bb78107627a6509fd4054c7fdc96cd25 /pyGHDL/dom/_Translate.py
parent15c6de72bc8dd316cb5262e1b5f373ca45b05f68 (diff)
downloadghdl-111fe055b2f0f3a0225d2553cf739572d691a14d.tar.gz
ghdl-111fe055b2f0f3a0225d2553cf739572d691a14d.tar.bz2
ghdl-111fe055b2f0f3a0225d2553cf739572d691a14d.zip
More DOM improvements (#1806)
* First try to handle names. * Reworked names. * Reworked range expressions. * Handle AttributeNames. * Added handling of file declaration and attribute declarations. * Improved error outputs. * Handle protected types. * Make black happy with ugly code. * Handle Null literal and File parameters. * File type and physical type. * Don't fail on reported syntax errors. Catch call errors into libghdl. * Improved Sanity checks for pyGHDL.dom. * Load sourcecode via Python and process in-memory. Fixed testcases. * Added package instantiations and packages with generics. * Added UseClause, AttributeSpecification and PhysicalTypes. * Improved pretty-printing. * Fixed AttributeName in subtype indication. * Get code position of IIR nodes. * Added DOMMixin into all derived classes. * Mark as not yet implemented. * Pinned pyVHDLModel version to v0.10.4. * Removed xfail in LSP test. Bumped requirement of pyVHDLModel to v0.10.4. Fixed some Codacy issues. (cherry picked from commit f64e7ed7c3d69cbf84cd60db8e9b085e90b846cb)
Diffstat (limited to 'pyGHDL/dom/_Translate.py')
-rw-r--r--pyGHDL/dom/_Translate.py209
1 files changed, 161 insertions, 48 deletions
diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py
index cb9448f09..502a94ad3 100644
--- a/pyGHDL/dom/_Translate.py
+++ b/pyGHDL/dom/_Translate.py
@@ -34,6 +34,8 @@ from typing import List, Generator
from pydecor import export
+from pyGHDL.dom import Position, DOMException
+from pyGHDL.dom.Object import Variable
from pyVHDLModel.VHDLModel import (
Constraint,
Direction,
@@ -44,6 +46,7 @@ from pyVHDLModel.VHDLModel import (
PortInterfaceItem,
ParameterInterfaceItem,
ModelEntity,
+ Name,
)
from pyGHDL.libghdl import utils
@@ -52,10 +55,14 @@ from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.dom._Utils import (
GetNameOfNode,
GetIirKindOfNode,
- GetPositionOfNode,
- GetSelectedName,
)
-from pyGHDL.dom.Common import DOMException
+from pyGHDL.dom.Names import (
+ SimpleName,
+ SelectedName,
+ AttributeName,
+ ParenthesisName,
+ AllName,
+)
from pyGHDL.dom.Symbol import (
SimpleObjectOrFunctionCallSymbol,
SimpleSubTypeSymbol,
@@ -69,10 +76,13 @@ from pyGHDL.dom.Type import (
ArrayType,
RecordType,
EnumeratedType,
- RecordTypeElement,
AccessType,
+ ProtectedType,
+ ProtectedTypeBody,
+ FileType,
+ PhysicalType,
)
-from pyGHDL.dom.Range import Range, RangeExpression
+from pyGHDL.dom.Range import Range
from pyGHDL.dom.Literal import (
IntegerLiteral,
CharacterLiteral,
@@ -80,7 +90,7 @@ from pyGHDL.dom.Literal import (
StringLiteral,
PhysicalIntegerLiteral,
PhysicalFloatingLiteral,
- EnumerationLiteral,
+ NullLiteral,
)
from pyGHDL.dom.Expression import (
SubtractionExpression,
@@ -114,6 +124,7 @@ from pyGHDL.dom.Expression import (
ShiftRightArithmeticExpression,
RotateLeftExpression,
RotateRightExpression,
+ RangeExpression,
)
from pyGHDL.dom.Subprogram import Function, Procedure
from pyGHDL.dom.Misc import Alias
@@ -123,6 +134,52 @@ __all__ = []
@export
+def GetNameFromNode(node: Iir) -> Name:
+ kind = GetIirKindOfNode(node)
+ if kind == nodes.Iir_Kind.Simple_Name:
+ name = GetNameOfNode(node)
+ return SimpleName(node, name)
+ elif kind == nodes.Iir_Kind.Selected_Name:
+ name = GetNameOfNode(node)
+ prefixName = GetNameFromNode(nodes.Get_Prefix(node))
+ return SelectedName(node, name, prefixName)
+ elif kind == nodes.Iir_Kind.Attribute_Name:
+ name = GetNameOfNode(node)
+ prefixName = GetNameFromNode(nodes.Get_Prefix(node))
+ return AttributeName(node, name, prefixName)
+ elif kind == nodes.Iir_Kind.Parenthesis_Name:
+ prefixName = GetNameFromNode(nodes.Get_Prefix(node))
+ associations = GetAssociations(node)
+
+ return ParenthesisName(node, prefixName, associations)
+ elif kind == nodes.Iir_Kind.Selected_By_All_Name:
+ prefixName = GetNameFromNode(nodes.Get_Prefix(node))
+ return AllName(node, prefixName)
+ else:
+ raise DOMException("Unknown name kind '{kind}'".format(kind=kind.name))
+
+
+def GetAssociations(node: Iir) -> List:
+ associations = []
+ for item in utils.chain_iter(nodes.Get_Association_Chain(node)):
+ kind = GetIirKindOfNode(item)
+
+ if kind == nodes.Iir_Kind.Association_Element_By_Expression:
+ actual = nodes.Get_Actual(item)
+ expr = GetExpressionFromNode(actual)
+
+ associations.append(expr)
+ else:
+ raise DOMException(
+ "Unknown association kind '{kindName}'({kind}) in array index/slice or function call '{node}'.".format(
+ kind=kind, kindName=kind.name, node=node
+ )
+ )
+
+ return associations
+
+
+@export
def GetArrayConstraintsFromSubtypeIndication(
subTypeIndication: Iir,
) -> List[Constraint]:
@@ -132,22 +189,19 @@ def GetArrayConstraintsFromSubtypeIndication(
):
constraintKind = GetIirKindOfNode(constraint)
if constraintKind == nodes.Iir_Kind.Range_Expression:
- constraints.append(RangeExpression(GetRangeFromNode(constraint)))
- elif constraintKind == nodes.Iir_Kind.Attribute_Name:
- name = GetNameOfNode(constraint)
- prefix = nodes.Get_Prefix(constraint)
- name2 = GetNameOfNode(prefix)
- kind2 = GetIirKindOfNode(prefix)
- print(name2, kind2, name)
-
- raise DOMException("[NOT IMPLEMENTED] Attribute name as range.")
- elif constraintKind == nodes.Iir_Kind.Simple_Name:
- raise DOMException("[NOT IMPLEMENTED] Subtype as range.")
+ constraints.append(RangeExpression.parse(constraint))
+ elif constraintKind in (
+ nodes.Iir_Kind.Simple_Name,
+ nodes.Iir_Kind.Parenthesis_Name,
+ nodes.Iir_Kind.Selected_Name,
+ nodes.Iir_Kind.Attribute_Name,
+ ):
+ constraints.append(GetNameFromNode(constraint))
else:
- position = GetPositionOfNode(constraint)
+ position = Position.parse(constraint)
raise DOMException(
"Unknown constraint kind '{kind}' for constraint '{constraint}' in subtype indication '{indication}' at {file}:{line}:{column}.".format(
- kind=constraintKind,
+ kind=constraintKind.name,
constraint=constraint,
indication=subTypeIndication,
file=position.Filename,
@@ -168,21 +222,27 @@ def GetTypeFromNode(node: Iir) -> BaseType:
if kind == nodes.Iir_Kind.Range_Expression:
r = GetRangeFromNode(typeDefinition)
- return IntegerType(typeName, r)
+ return IntegerType(node, typeName, r)
+ elif kind == nodes.Iir_Kind.Physical_Type_Definition:
+ return PhysicalType.parse(typeName, typeDefinition)
elif kind == nodes.Iir_Kind.Enumeration_Type_Definition:
return EnumeratedType.parse(typeName, typeDefinition)
elif kind == nodes.Iir_Kind.Array_Type_Definition:
return ArrayType.parse(typeName, typeDefinition)
elif kind == nodes.Iir_Kind.Array_Subtype_Definition:
- print("Array_Subtype_Definition")
+ print("[NOT IMPLEMENTED] Array_Subtype_Definition")
- return ArrayType
+ return ArrayType(typeDefinition, "????", [], None)
elif kind == nodes.Iir_Kind.Record_Type_Definition:
return RecordType.parse(typeName, typeDefinition)
elif kind == nodes.Iir_Kind.Access_Type_Definition:
return AccessType.parse(typeName, typeDefinition)
+ elif kind == nodes.Iir_Kind.File_Type_Definition:
+ return FileType.parse(typeName, typeDefinition)
+ elif kind == nodes.Iir_Kind.Protected_Type_Declaration:
+ return ProtectedType.parse(typeName, typeDefinition)
else:
- position = GetPositionOfNode(typeDefinition)
+ position = Position.parse(typeDefinition)
raise DOMException(
"Unknown type definition kind '{kindName}'({kind}) for type '{name}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -207,10 +267,19 @@ def GetSubTypeIndicationFromNode(node: Iir, entity: str, name: str) -> SubTypeOr
def GetSubTypeIndicationFromIndicationNode(
subTypeIndicationNode: Iir, entity: str, name: str
) -> SubTypeOrSymbol:
+ if subTypeIndicationNode is nodes.Null_Iir:
+ print(
+ "[NOT IMPLEMENTED]: Unhandled multiple declarations for {entity} '{name}'.".format(
+ entity=entity, name=name
+ )
+ )
+ return None
kind = GetIirKindOfNode(subTypeIndicationNode)
- if kind == nodes.Iir_Kind.Simple_Name:
- return GetSimpleTypeFromNode(subTypeIndicationNode)
- elif kind == nodes.Iir_Kind.Selected_Name:
+ if kind in (
+ nodes.Iir_Kind.Simple_Name,
+ nodes.Iir_Kind.Selected_Name,
+ nodes.Iir_Kind.Attribute_Name,
+ ):
return GetSimpleTypeFromNode(subTypeIndicationNode)
elif kind == nodes.Iir_Kind.Subtype_Definition:
return GetScalarConstrainedSubTypeFromNode(subTypeIndicationNode)
@@ -226,8 +295,8 @@ def GetSubTypeIndicationFromIndicationNode(
@export
def GetSimpleTypeFromNode(subTypeIndicationNode: Iir) -> SimpleSubTypeSymbol:
- subTypeName = GetSelectedName(subTypeIndicationNode)
- return SimpleSubTypeSymbol(subTypeName)
+ subTypeName = GetNameFromNode(subTypeIndicationNode)
+ return SimpleSubTypeSymbol(subTypeIndicationNode, subTypeName)
@export
@@ -238,7 +307,7 @@ def GetScalarConstrainedSubTypeFromNode(
typeMarkName = GetNameOfNode(typeMark)
rangeConstraint = nodes.Get_Range_Constraint(subTypeIndicationNode)
r = GetRangeFromNode(rangeConstraint)
- return ConstrainedScalarSubTypeSymbol(typeMarkName, r)
+ return ConstrainedScalarSubTypeSymbol(subTypeIndicationNode, typeMarkName, r)
@export
@@ -249,14 +318,16 @@ def GetCompositeConstrainedSubTypeFromNode(
typeMarkName = GetNameOfNode(typeMark)
constraints = GetArrayConstraintsFromSubtypeIndication(subTypeIndicationNode)
- return ConstrainedCompositeSubTypeSymbol(typeMarkName, constraints)
+ return ConstrainedCompositeSubTypeSymbol(
+ subTypeIndicationNode, typeMarkName, constraints
+ )
@export
-def GetSubTypeFromNode(node: Iir) -> SubTypeOrSymbol:
- subTypeName = GetNameOfNode(node)
+def GetSubTypeFromNode(subTypeNode: Iir) -> SubTypeOrSymbol:
+ subTypeName = GetNameOfNode(subTypeNode)
- return SubType(subTypeName)
+ return SubType(subTypeNode, subTypeName)
@export
@@ -274,7 +345,10 @@ def GetRangeFromNode(node: Iir) -> Range:
__EXPRESSION_TRANSLATION = {
nodes.Iir_Kind.Simple_Name: SimpleObjectOrFunctionCallSymbol,
+ nodes.Iir_Kind.Selected_Name: IndexedObjectOrFunctionCallSymbol,
+ nodes.Iir_Kind.Attribute_Name: IndexedObjectOrFunctionCallSymbol,
nodes.Iir_Kind.Parenthesis_Name: IndexedObjectOrFunctionCallSymbol,
+ nodes.Iir_Kind.Null_Literal: NullLiteral,
nodes.Iir_Kind.Integer_Literal: IntegerLiteral,
nodes.Iir_Kind.Floating_Point_Literal: FloatingPointLiteral,
nodes.Iir_Kind.Physical_Int_Literal: PhysicalIntegerLiteral,
@@ -282,6 +356,7 @@ __EXPRESSION_TRANSLATION = {
nodes.Iir_Kind.Character_Literal: CharacterLiteral,
nodes.Iir_Kind.String_Literal8: StringLiteral,
nodes.Iir_Kind.Negation_Operator: NegationExpression,
+ nodes.Iir_Kind.Range_Expression: RangeExpression,
nodes.Iir_Kind.Addition_Operator: AdditionExpression,
nodes.Iir_Kind.Concatenation_Operator: ConcatenationExpression,
nodes.Iir_Kind.Not_Operator: InverseExpression,
@@ -322,7 +397,7 @@ def GetExpressionFromNode(node: Iir) -> Expression:
try:
cls = __EXPRESSION_TRANSLATION[kind]
except KeyError:
- position = GetPositionOfNode(node)
+ position = Position.parse(node)
raise DOMException(
"Unknown expression kind '{kindName}'({kind}) in expression '{expr}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -346,11 +421,17 @@ def GetGenericsFromChainedNodes(
if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem
- genericConstant = GenericConstantInterfaceItem.parse(generic)
-
- yield genericConstant
+ yield GenericConstantInterfaceItem.parse(generic)
+ elif kind == nodes.Iir_Kind.Interface_Type_Declaration:
+ print("[NOT IMPLEMENTED] generic type")
+ elif kind == nodes.Iir_Kind.Interface_Package_Declaration:
+ print("[NOT IMPLEMENTED] generic package")
+ elif kind == nodes.Iir_Kind.Interface_Procedure_Declaration:
+ print("[NOT IMPLEMENTED] generic procedure")
+ elif kind == nodes.Iir_Kind.Interface_Function_Declaration:
+ print("[NOT IMPLEMENTED] generic function")
else:
- position = GetPositionOfNode(generic)
+ position = Position.parse(generic)
raise DOMException(
"Unknown generic kind '{kindName}'({kind}) in generic '{generic}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -376,7 +457,7 @@ def GetPortsFromChainedNodes(
yield portSignal
else:
- position = GetPositionOfNode(port)
+ position = Position.parse(port)
raise DOMException(
"Unknown port kind '{kindName}'({kind}) in port '{port}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -407,8 +488,12 @@ def GetParameterFromChainedNodes(
from pyGHDL.dom.InterfaceItem import ParameterSignalInterfaceItem
yield ParameterSignalInterfaceItem.parse(parameter)
+ elif kind == nodes.Iir_Kind.Interface_File_Declaration:
+ from pyGHDL.dom.InterfaceItem import ParameterFileInterfaceItem
+
+ yield ParameterFileInterfaceItem.parse(parameter)
else:
- position = GetPositionOfNode(parameter)
+ position = Position.parse(parameter)
raise DOMException(
"Unknown parameter kind '{kindName}'({kind}) in parameter '{param}' at {file}:{line}:{column}.".format(
kind=kind,
@@ -437,11 +522,16 @@ def GetDeclaredItemsFromChainedNodes(
if nodes.Get_Shared_Flag(item):
yield SharedVariable.parse(item)
else:
- raise DOMException("Found non-shared variable.")
+ yield Variable.parse(item)
+ # raise DOMException("Found non-shared variable.")
elif kind == nodes.Iir_Kind.Signal_Declaration:
from pyGHDL.dom.Object import Signal
yield Signal.parse(item)
+ elif kind == nodes.Iir_Kind.File_Declaration:
+ from pyGHDL.dom.Object import File
+
+ yield File.parse(item)
elif kind == nodes.Iir_Kind.Type_Declaration:
yield GetTypeFromNode(item)
elif kind == nodes.Iir_Kind.Anonymous_Type_Declaration:
@@ -458,18 +548,41 @@ def GetDeclaredItemsFromChainedNodes(
elif kind == nodes.Iir_Kind.Procedure_Body:
# procedureName = NodeToName(item)
print("found procedure body '{name}'".format(name="????"))
+ elif kind == nodes.Iir_Kind.Protected_Type_Body:
+ yield ProtectedTypeBody.parse(item)
elif kind == nodes.Iir_Kind.Object_Alias_Declaration:
yield GetAliasFromNode(item)
elif kind == nodes.Iir_Kind.Component_Declaration:
from pyGHDL.dom.DesignUnit import Component
yield Component.parse(item)
+ elif kind == nodes.Iir_Kind.Attribute_Declaration:
+ from pyGHDL.dom.Attribute import Attribute
+
+ yield Attribute.parse(item)
+ elif kind == nodes.Iir_Kind.Attribute_Specification:
+ from pyGHDL.dom.Attribute import AttributeSpecification
+
+ yield AttributeSpecification.parse(item)
+ elif kind == nodes.Iir_Kind.Use_Clause:
+ from pyGHDL.dom.DesignUnit import UseClause
+
+ yield UseClause.parse(item)
+ elif kind == nodes.Iir_Kind.Package_Instantiation_Declaration:
+ from pyGHDL.dom.DesignUnit import PackageInstantiation
+
+ yield PackageInstantiation.parse(item)
+ elif kind == nodes.Iir_Kind.Configuration_Specification:
+ print(
+ "[NOT IMPLEMENTED] Configuration specification in {name}".format(
+ name=name
+ )
+ )
else:
- position = GetPositionOfNode(item)
+ position = Position.parse(item)
raise DOMException(
- "Unknown declared item kind '{kindName}'({kind}) in {entity} '{name}' at {file}:{line}:{column}.".format(
- kind=kind,
- kindName=kind.name,
+ "Unknown declared item kind '{kind}' in {entity} '{name}' at {file}:{line}:{column}.".format(
+ kind=kind.name,
entity=entity,
name=name,
file=position.Filename,
@@ -479,7 +592,7 @@ def GetDeclaredItemsFromChainedNodes(
)
-def GetAliasFromNode(node: Iir):
- aliasName = GetNameOfNode(node)
+def GetAliasFromNode(aliasNode: Iir):
+ aliasName = GetNameOfNode(aliasNode)
- return Alias(aliasName)
+ return Alias(aliasNode, aliasName)