aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorSchuyler Eldridge2018-11-05 12:10:21 -0500
committerSchuyler Eldridge2018-11-05 15:57:43 -0500
commita5c3589e7bd680bcf7db25e8fd3282d73c5e24ae (patch)
treeba71817c8d30f79dcdad031eae0633281ecc3a6a /src/main
parent3935914116d7289a8b545cc8d758785d9f8dcd13 (diff)
Add prettyPrint method to Target
This adds a pretty printer for firrtl.annotation.Target and associated tests. This uses a tree-like output where the following target ~Circuit|Module/foo:Foo>ref.field[0] will serialize to: circuit Circuit: └── module Module: └── foo of Foo: └── ref.field[0] This enables better error messages and a human readable syntax better than the existing serialize method (and avoiding the need for users to understand the Target serialization syntax), but that is not intended to be deserialized nor space efficient. Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/firrtl/annotations/Target.scala26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/annotations/Target.scala b/src/main/scala/firrtl/annotations/Target.scala
index dcf5cb02..8a9d68e8 100644
--- a/src/main/scala/firrtl/annotations/Target.scala
+++ b/src/main/scala/firrtl/annotations/Target.scala
@@ -55,6 +55,32 @@ sealed trait Target extends Named {
}
}
+ /** Pretty serialization, ideal for error messages. Cannot be deserialized.
+ * @return Human-readable serialization
+ */
+ def prettyPrint(tab: String = ""): String = {
+ val circuitString = s"""${tab}circuit ${circuitOpt.getOrElse("???")}:"""
+ val moduleString = s"""\n$tab└── module ${moduleOpt.getOrElse("???")}:"""
+ var depth = 4
+ val tokenString = tokens.map {
+ case Ref(r) => val rx = s"""\n$tab${" "*depth}└── $r"""; depth += 4; rx
+ case Instance(i) => val ix = s"""\n$tab${" "*depth}└── inst $i """; ix
+ case OfModule(o) => val ox = s"of $o:"; depth += 4; ox
+ case Field(f) => s".$f"
+ case Index(v) => s"[$v]"
+ case Clock => s"@clock"
+ case Reset => s"@reset"
+ case Init => s"@init"
+ }.mkString("")
+
+ (moduleOpt.isEmpty, tokens.isEmpty) match {
+ case (true, true) => circuitString
+ case (_, true) => circuitString + moduleString
+ case (_, _) => circuitString + moduleString + tokenString
+ }
+ }
+
+
/** @return Converts this [[Target]] into a [[GenericTarget]] */
def toGenericTarget: GenericTarget = GenericTarget(circuitOpt, moduleOpt, tokens.toVector)