aboutsummaryrefslogtreecommitdiffstats
path: root/pyGHDL/dom/formatting
diff options
context:
space:
mode:
authorPatrick Lehmann <Patrick.Lehmann@plc2.de>2021-06-17 13:11:32 +0200
committertgingold <tgingold@users.noreply.github.com>2021-06-17 21:34:16 +0200
commit4ec5cdcd77aa1b6fc384197e1208061d62f16ba2 (patch)
tree3c386d35b39b001db4e128abda379ddeb5ba7b2c /pyGHDL/dom/formatting
parent1eea725dedae1fe3eee47c2b4bfc18c7ac35e806 (diff)
downloadghdl-4ec5cdcd77aa1b6fc384197e1208061d62f16ba2.tar.gz
ghdl-4ec5cdcd77aa1b6fc384197e1208061d62f16ba2.tar.bz2
ghdl-4ec5cdcd77aa1b6fc384197e1208061d62f16ba2.zip
Updates to the dom namespace in pyGHDL.
Diffstat (limited to 'pyGHDL/dom/formatting')
-rw-r--r--pyGHDL/dom/formatting/__init__.py0
-rw-r--r--pyGHDL/dom/formatting/prettyprint.py296
2 files changed, 296 insertions, 0 deletions
diff --git a/pyGHDL/dom/formatting/__init__.py b/pyGHDL/dom/formatting/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/pyGHDL/dom/formatting/__init__.py
diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py
new file mode 100644
index 000000000..a64f2a4f5
--- /dev/null
+++ b/pyGHDL/dom/formatting/prettyprint.py
@@ -0,0 +1,296 @@
+from typing import List, Union
+
+from pydecor import export
+
+from pyGHDL.dom.Object import Constant, Signal
+from pyVHDLModel.VHDLModel import GenericInterfaceItem, Expression, Direction, Mode, NamedEntity, PortInterfaceItem, BinaryExpression, IdentityExpression, \
+ UnaryExpression
+
+from pyGHDL import GHDLBaseException
+from pyGHDL.dom.Misc import Document
+from pyGHDL.dom.DesignUnit import Entity, Architecture, Package, PackageBody, Configuration, Context
+from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem, PortSignalInterfaceItem
+from pyGHDL.dom.Symbol import SimpleSubTypeSymbol, ConstrainedSubTypeSymbol, SimpleObjectSymbol
+from pyGHDL.dom.Literal import IntegerLiteral, CharacterLiteral, FloatingPointLiteral
+
+from pyGHDL.dom.Expression import SubtractionExpression, AdditionExpression, MultiplyExpression, DivisionExpression, InverseExpression, AbsoluteExpression, \
+ NegationExpression, ExponentiationExpression
+
+StringBuffer = List[str]
+
+DirectionTranslation = {
+ Direction.To: "to",
+ Direction.DownTo: "downto"
+}
+
+ModeTranslation = {
+ Mode.In: "in",
+ Mode.Out: "out",
+ Mode.InOut: "inout",
+ Mode.Buffer: "buffer",
+ Mode.Linkage: "linkage"
+}
+
+UnaryExpressionTranslation = {
+ IdentityExpression: " +",
+ NegationExpression: " -",
+ InverseExpression: "not ",
+ AbsoluteExpression: "abs ",
+}
+
+BinaryExpressionTranslation = {
+ AdditionExpression: " + ",
+ SubtractionExpression: " - ",
+ MultiplyExpression: " * ",
+ DivisionExpression: " / ",
+ ExponentiationExpression: "**"
+}
+
+@export
+class PrettyPrintException(GHDLBaseException):
+ pass
+
+@export
+class PrettyPrint:
+ # _buffer: StringBuffer
+ #
+ # def __init__(self):
+ # self._buffer = []
+
+ def formatDocument(self, document: Document, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}Document '{doc!s}':".format(doc=document.Path, prefix=prefix))
+ buffer.append("{prefix} Entities:".format(prefix=prefix))
+ for entity in document.Entities:
+ for line in self.formatEntity(entity, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} Architectures:".format(prefix=prefix))
+ for architecture in document.Architectures:
+ for line in self.formatArchitecture(architecture, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} Packages:".format(prefix=prefix))
+ for package in document.Packages:
+ for line in self.formatPackage(package, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} PackageBodies:".format(prefix=prefix))
+ for packageBodies in document.PackageBodies:
+ for line in self.formatPackageBody(packageBodies, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} Configurations:".format(prefix=prefix))
+ for configuration in document.Configurations:
+ for line in self.formatConfiguration(configuration, level+1):
+ buffer.append(line)
+ buffer.append("{prefix} Contexts:".format(prefix=prefix))
+ for context in document.Contexts:
+ for line in self.formatContext(context, level+1):
+ buffer.append(line)
+
+ return buffer
+
+ def formatEntity(self, entity: Entity, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=entity.Name, prefix=prefix))
+ buffer.append("{prefix} Generics:".format(prefix=prefix))
+ for generic in entity.GenericItems:
+ for line in self.formatGeneric(generic, level + 1):
+ buffer.append(line)
+ buffer.append("{prefix} Ports:".format(prefix=prefix))
+ for port in entity.PortItems:
+ for line in self.formatPort(port, level + 1):
+ buffer.append(line)
+ buffer.append("{prefix} Declared:".format(prefix=prefix))
+ for item in entity.DeclaredItems:
+ for line in self.formatDeclaredItems(item, level + 1):
+ buffer.append(line)
+
+ return buffer
+
+ def formatArchitecture(self, architecture: Architecture, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=architecture.Name, prefix=prefix))
+ buffer.append("{prefix} Declared:".format(prefix=prefix))
+ for item in architecture.DeclaredItems:
+ for line in self.formatDeclaredItems(item, level + 2):
+ buffer.append(line)
+
+ return buffer
+
+ def formatPackage(self, package: Package, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=package.Name, prefix=prefix))
+ buffer.append("{prefix} Declared:".format(prefix=prefix))
+ for item in package.DeclaredItems:
+ for line in self.formatDeclaredItems(item, level + 1):
+ buffer.append(line)
+
+ return buffer
+
+ def formatPackageBody(self, packageBody: PackageBody, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=packageBody.Name, prefix=prefix))
+ buffer.append("{prefix} Declared:".format(prefix=prefix))
+ for item in packageBody.DeclaredItems:
+ for line in self.formatDeclaredItems(item, level + 1):
+ buffer.append(line)
+
+ return buffer
+
+ def formatConfiguration(self, configuration: Configuration, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=configuration.Name, prefix=prefix))
+
+ return buffer
+
+ def formatContext(self, context: Context, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ buffer.append("{prefix}- {name}".format(name=context.Name, prefix=prefix))
+
+ return buffer
+
+ def formatGeneric(self, generic: Union[NamedEntity, GenericInterfaceItem], level: int = 0) -> StringBuffer:
+ if isinstance(generic, GenericConstantInterfaceItem):
+ return self.formatGenericConstant(generic, level)
+ else:
+ raise PrettyPrintException("Unhandled generic kind for generic '{name}'.".format(name=generic.Name))
+
+ def formatPort(self, port: Union[NamedEntity, PortInterfaceItem], level: int = 0) -> StringBuffer:
+ if isinstance(port, PortSignalInterfaceItem):
+ return self.formatPortSignal(port, level)
+ else:
+ raise PrettyPrintException("Unhandled port kind for port '{name}'.".format(name=port.Name))
+
+ def formatGenericConstant(self, generic: GenericConstantInterfaceItem, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+ subType = generic.SubType
+ if isinstance(subType, SimpleSubTypeSymbol):
+ buffer.append(
+ "{prefix} - {name} : {mode} {type}".format(
+ prefix=prefix,
+ name=generic.Name,
+ mode=ModeTranslation[generic.Mode],
+ type=subType.SymbolName
+ )
+ )
+ elif isinstance(subType, ConstrainedSubTypeSymbol):
+ buffer.append(
+ "{prefix} - {name} : {mode} {type}({constraints})".format(
+ prefix=prefix,
+ name=generic.Name,
+ mode=ModeTranslation[generic.Mode],
+ type=subType.SymbolName,
+ constraints=", ".join(
+ ["{left} {dir} {right}".format(
+ left=self.formatExpression(constraint.Range.LeftBound),
+ right=self.formatExpression(constraint.Range.RightBound),
+ dir=DirectionTranslation[constraint.Range.Direction])
+ for constraint in subType.Constraints])
+ )
+ )
+ else:
+ raise PrettyPrintException("Unhandled constraint kind for generic '{name}'.".format(name=generic.Name))
+
+ return buffer
+
+ def formatPortSignal(self, port: PortSignalInterfaceItem, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+
+ buffer.append(
+ "{prefix} - {name} : {mode} {subtypeindication}".format(
+ prefix=prefix,
+ name=port.Name,
+ mode=ModeTranslation[port.Mode],
+ subtypeindication=self.formatSubtypeIndication(port.SubType, "port", port.Name)
+ )
+ )
+
+ return buffer
+
+ def formatDeclaredItems(self, item, level: int = 0) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+
+ if isinstance(item, Constant):
+ buffer.append(
+ "{prefix}- constant {name} : {subtype} := {expr}".format(
+ prefix=prefix,
+ name=item.Name,
+ subtype=self.formatSubtypeIndication(item.SubType, "constant", item.Name),
+ expr=self.formatExpression(item.DefaultExpression)
+ )
+ )
+ elif isinstance(item, Signal):
+ buffer.append(
+ "{prefix}- signal {name} : {subtype}{initValue}".format(
+ prefix=prefix,
+ name=item.Name,
+ subtype=self.formatSubtypeIndication(item.SubType, "signal", item.Name),
+ initValue=" := {expr}".format(
+ expr=self.formatExpression(item.DefaultExpression)
+ ) if item.DefaultExpression is not None else ""
+ )
+ )
+ else:
+ raise PrettyPrintException("Unhandled declared item kind.")
+
+ return buffer
+
+ def formatSubtypeIndication(self, subTypeIndication, entity: str, name: str) -> str:
+ if isinstance(subTypeIndication, SimpleSubTypeSymbol):
+ return "{type}".format(type=subTypeIndication.SymbolName)
+ elif isinstance(subTypeIndication, ConstrainedSubTypeSymbol):
+ constraints = ", ".join(
+ ["{left} {dir} {right}".format(
+ left=self.formatExpression(constraint.Range.LeftBound),
+ right=self.formatExpression(constraint.Range.RightBound),
+ dir=DirectionTranslation[constraint.Range.Direction]
+ ) for constraint in subTypeIndication.Constraints]
+ )
+
+ return "{type}({constraints})".format(
+ type=subTypeIndication.SymbolName,
+ constraints=constraints
+ )
+ else:
+ raise PrettyPrintException("Unhandled constraint kind for {entity} '{name}'.".format(entity=entity, name=name))
+
+ def formatExpression(self, expression: Expression) -> str:
+ if isinstance(expression, SimpleObjectSymbol):
+ return "{name}".format(name=expression.SymbolName)
+ elif isinstance(expression, IntegerLiteral):
+ return "{value}".format(value=expression.Value)
+ elif isinstance(expression, FloatingPointLiteral):
+ return "{value}".format(value=expression.Value)
+ elif isinstance(expression, CharacterLiteral):
+ return "'{value}'".format(value=expression.Value)
+ elif isinstance(expression, UnaryExpression):
+ try:
+ operator = UnaryExpressionTranslation[type(expression)]
+ except KeyError:
+ raise PrettyPrintException("Unhandled operator for unary expression.")
+
+ return "{operator}{operand}".format(
+ operand=self.formatExpression(expression.Operand),
+ operator=operator
+ )
+ elif isinstance(expression, BinaryExpression):
+ try:
+ operator = BinaryExpressionTranslation[type(expression)]
+ except KeyError:
+ raise PrettyPrintException("Unhandled operator for binary expression.")
+
+ return "{left}{operator}{right}".format(
+ left=self.formatExpression(expression.LeftOperand),
+ right=self.formatExpression(expression.RightOperand),
+ operator=operator
+ )
+ else:
+ raise PrettyPrintException("Unhandled expression kind.")