From 3f31acc7304b03996f045f39b9e1130a4ffdc330 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 02:55:48 +0200 Subject: Improved pretty-printing for hierarchy. --- pyGHDL/cli/dom.py | 1 - pyGHDL/dom/Concurrent.py | 30 ++++---- pyGHDL/dom/formatting/prettyprint.py | 144 +++++++++++++++++++++++++++++++---- testsuite/pyunit/Current.vhdl | 22 +++++- 4 files changed, 164 insertions(+), 33 deletions(-) diff --git a/pyGHDL/cli/dom.py b/pyGHDL/cli/dom.py index 4a9fd0b3c..69a0b92ec 100755 --- a/pyGHDL/cli/dom.py +++ b/pyGHDL/cli/dom.py @@ -323,7 +323,6 @@ class Application(LineTerminal, ArgParseMixin): for architecture in architectures: entity.Architectures.append(architecture) - PP = PrettyPrint() buffer = [] diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 990fc32c7..69ae8bdea 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -318,8 +318,15 @@ class ElseGenerateBranch(VHDLModel_ElseGenerateBranch): @export class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): - def __init__(self, generateNode: Iir, label: str, ifBranch: IfGenerateBranch): - super().__init__(label, ifBranch) + def __init__( + self, + generateNode: Iir, + label: str, + ifBranch: IfGenerateBranch, + elsifBranches: Iterable[ElsifGenerateBranch] = None, + elseBranch: ElseGenerateBranch = None, + ): + super().__init__(label, ifBranch, elsifBranches, elseBranch) DOMMixin.__init__(self, generateNode) @classmethod @@ -337,17 +344,18 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): print("if branch", generateNode, GetIirKindOfNode(generateNode)) ifBranch = IfGenerateBranch.parse(generateNode) + elsifBranches = [] + elseBranch = None # Python 3.8 syntax # elseClause = generateNode # while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir: elseClause = nodes.Get_Generate_Else_Clause(generateNode) while elseClause != nodes.Null_Iir: - print("els(if) branch", elseClause, GetIirKindOfNode(elseClause)) - ifBranch = ElsifGenerateBranch.parse(generateNode) + elsifBranches.append(ElsifGenerateBranch.parse(generateNode)) elseClause = nodes.Get_Generate_Else_Clause(elseClause) - return cls(generateNode, label, ifBranch) + return cls(generateNode, label, ifBranch, elsifBranches, elseBranch) @export @@ -381,18 +389,12 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): @export -class WaveformElement( - VHDLModel_WaveformElement, DOMMixin -): - def __init__( - self, - waveformNode: Iir, - expression: Expression, - after: Expression - ): +class WaveformElement(VHDLModel_WaveformElement, DOMMixin): + def __init__(self, waveformNode: Iir, expression: Expression, after: Expression): super().__init__(expression, after) DOMMixin.__init__(self, waveformNode) + @export class ConcurrentSimpleSignalAssignment( VHDLModel_ConcurrentSimpleSignalAssignment, DOMMixin diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 4d6fbb19a..1aefb570d 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -34,7 +34,16 @@ from typing import List, Union from pydecor import export -from pyGHDL.dom.Concurrent import ConcurrentBlockStatement, ProcessStatement +from pyGHDL.dom.Concurrent import ( + ConcurrentBlockStatement, + ProcessStatement, + IfGenerateStatement, + CaseGenerateStatement, + ForGenerateStatement, + ComponentInstantiation, + ConfigurationInstantiation, + EntityInstantiation, +) from pyVHDLModel.SyntaxModel import ( GenericInterfaceItem, NamedEntity, @@ -43,7 +52,8 @@ from pyVHDLModel.SyntaxModel import ( Function, BaseType, FullType, - BaseConstant, ConcurrentStatement, + BaseConstant, + ConcurrentStatement, ) from pyGHDL import GHDLBaseException @@ -108,7 +118,11 @@ class PrettyPrint: prefix = " " * level buffer.append("{prefix}Libraries:".format(prefix=prefix)) for library in design.Libraries.values(): - buffer.append("{prefix} - Name: {name}".format(prefix=prefix, name=library.Identifier)) + buffer.append( + "{prefix} - Name: {name}".format( + prefix=prefix, name=library.Identifier + ) + ) for line in self.formatLibrary(library, level + 2): buffer.append(line) buffer.append("{prefix}Documents:".format(prefix=prefix)) @@ -126,19 +140,41 @@ class PrettyPrint: prefix = " " * level buffer.append("{prefix}Entities:".format(prefix=prefix)) for entity in library.Entities: - buffer.append("{prefix} - {name}({architectures})".format(prefix=prefix, name=entity.Identifier, architectures=", ".join([a.Identifier for a in entity.Architectures]))) + buffer.append( + "{prefix} - {name}({architectures})".format( + prefix=prefix, + name=entity.Identifier, + architectures=", ".join( + [a.Identifier for a in entity.Architectures] + ), + ) + ) buffer.append("{prefix}Packages:".format(prefix=prefix)) for package in library.Packages: if isinstance(package, Package): - buffer.append("{prefix} - {name}".format(prefix=prefix, name=package.Identifier)) + buffer.append( + "{prefix} - {name}".format(prefix=prefix, name=package.Identifier) + ) elif isinstance(package, PackageInstantiation): - buffer.append("{prefix} - {name} instantiate from {package}".format(prefix=prefix, name=package.Identifier, package=package.PackageReference)) + buffer.append( + "{prefix} - {name} instantiate from {package}".format( + prefix=prefix, + name=package.Identifier, + package=package.PackageReference, + ) + ) buffer.append("{prefix}Configurations:".format(prefix=prefix)) for configuration in library.Configurations: - buffer.append("{prefix} - {name}".format(prefix=prefix, name=configuration.Identifier)) + buffer.append( + "{prefix} - {name}".format( + prefix=prefix, name=configuration.Identifier + ) + ) buffer.append("{prefix}Contexts:".format(prefix=prefix)) for context in library.Contexts: - buffer.append("{prefix} - {name}".format(prefix=prefix, name=context.Identifier)) + buffer.append( + "{prefix} - {name}".format(prefix=prefix, name=context.Identifier) + ) return buffer @@ -206,7 +242,9 @@ class PrettyPrint: buffer.append("{prefix} ...".format(prefix=prefix)) buffer.append("{prefix} Architecures:".format(prefix=prefix)) for item in entity.Architectures: - buffer.append("{prefix} - {name}".format(prefix=prefix, name=item.Identifier)) + buffer.append( + "{prefix} - {name}".format(prefix=prefix, name=item.Identifier) + ) return buffer @@ -240,8 +278,8 @@ class PrettyPrint: buffer.append("{prefix} Statements:".format(prefix=prefix)) for item in architecture.Statements: buffer.append("{prefix} ...".format(prefix=prefix)) -# for line in self.formatStatements(item, level + 2): -# buffer.append(line) + # for line in self.formatStatements(item, level + 2): + # buffer.append(line) return buffer @@ -268,10 +306,13 @@ class PrettyPrint: buffer = [] prefix = " " * level buffer.append( - "{prefix}- Name: {name}\n{prefix} File: {file}\n{prefix} Position: {line}:{column}".format(name=package.Identifier, prefix=prefix, + "{prefix}- Name: {name}\n{prefix} File: {file}\n{prefix} Position: {line}:{column}".format( + name=package.Identifier, + prefix=prefix, file=package.Position.Filename.name, line=package.Position.Line, - column=package.Position.Column,) + column=package.Position.Column, + ) ) buffer.append("{prefix} Declared:".format(prefix=prefix)) for item in package.DeclaredItems: @@ -605,13 +646,84 @@ class PrettyPrint: return " := {expr!s}".format(expr=item.DefaultExpression) - def formatHierarchy(self, statement: ConcurrentStatement, level: int = 0) -> StringBuffer: + def formatHierarchy( + self, statement: ConcurrentStatement, level: int = 0 + ) -> StringBuffer: buffer = [] prefix = " " * level if isinstance(statement, ProcessStatement): - buffer.append("{prefix}{label}: process(...)".format(prefix=prefix, label=statement.Label)) + buffer.append( + "{prefix}- {label}: process(...)".format( + prefix=prefix, label=statement.Label + ) + ) + elif isinstance(statement, EntityInstantiation): + buffer.append( + "{prefix}- {label}: entity {name}".format( + prefix=prefix, label=statement.Label, name=statement.Entity + ) + ) + elif isinstance(statement, ComponentInstantiation): + buffer.append( + "{prefix}- {label}: component {name}".format( + prefix=prefix, label=statement.Label, name=statement.Component + ) + ) + elif isinstance(statement, ConfigurationInstantiation): + buffer.append( + "{prefix}- {label}: configuration {name}".format( + prefix=prefix, label=statement.Label, name=statement.Configuration + ) + ) elif isinstance(statement, ConcurrentBlockStatement): - buffer.append("{prefix}{label}: block".format(prefix=prefix, label=statement.Label)) + buffer.append( + "{prefix}- {label}: block".format(prefix=prefix, label=statement.Label) + ) + for stmt in statement.Statements: + for line in self.formatHierarchy(stmt, level + 2): + buffer.append(line) + elif isinstance(statement, IfGenerateStatement): + buffer.append( + "{prefix}- {label}: if ... generate".format( + prefix=prefix, label=statement.Label + ) + ) + for stmt in statement.IfBranch.Statements: + for line in self.formatHierarchy(stmt, level + 2): + buffer.append(line) + for elsifBranch in statement.ElsifBranches: + buffer.append( + "{prefix} {label}: elsif ... generate".format( + prefix=prefix, label=statement.Label + ) + ) + for stmt in elsifBranch.Statements: + for line in self.formatHierarchy(stmt, level + 2): + buffer.append(line) + if statement.ElseBranch is not None: + buffer.append( + "{prefix} {label}: else generate".format( + prefix=prefix, label=statement.Label + ) + ) + for stmt in statement.ElseBranch.Statements: + for line in self.formatHierarchy(stmt, level + 2): + buffer.append(line) + elif isinstance(statement, CaseGenerateStatement): + buffer.append( + "{prefix}- {label}: case ... generate".format( + prefix=prefix, label=statement.Label + ) + ) + elif isinstance(statement, ForGenerateStatement): + buffer.append( + "{prefix}- {label}: for ... generate".format( + prefix=prefix, label=statement.Label + ) + ) + for stmt in statement.Statements: + for line in self.formatHierarchy(stmt, level + 2): + buffer.append(line) return buffer diff --git a/testsuite/pyunit/Current.vhdl b/testsuite/pyunit/Current.vhdl index d364a2b2e..f11ab764a 100644 --- a/testsuite/pyunit/Current.vhdl +++ b/testsuite/pyunit/Current.vhdl @@ -128,15 +128,33 @@ begin genIf: if True generate constant G0 : boolean := False; begin - + inst: IfDummy; elsif False generate constant G1 : boolean := False; begin - + inst: ElsifDummy; else generate constant G2 : boolean := False; begin + inst: ElseDummy; + end generate; + + genFor: for I in 0 to 3 generate + constant G3 : boolean := False; + begin + inst: ForDummy; + end generate; + + genCase: case selector generate + when 0 => + constant G4 : boolean := False; + begin + inst: Case0Dummy; + when others => + constant G5 : boolean := False; + begin + inst: OthersDummy; end generate; end architecture behav; -- cgit v1.2.3