summaryrefslogtreecommitdiff
path: root/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala
diff options
context:
space:
mode:
authorJack Koenig2021-09-17 21:01:26 -0700
committerJack Koenig2021-09-17 21:01:26 -0700
commit5c8c19345e6711279594cf1f9ddab33623c8eba7 (patch)
treed9d6ced3934aa4a8be3dec19ddcefe50a7a93d5a /macros/src/main/scala/chisel3/internal/InstantiableMacro.scala
parente63b9667d89768e0ec6dc8a9153335cb48a213a7 (diff)
parent958904cb2f2f65d02b2ab3ec6d9ec2e06d04e482 (diff)
Merge branch 'master' into 3.5-release
Diffstat (limited to 'macros/src/main/scala/chisel3/internal/InstantiableMacro.scala')
-rw-r--r--macros/src/main/scala/chisel3/internal/InstantiableMacro.scala77
1 files changed, 77 insertions, 0 deletions
diff --git a/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala b/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala
new file mode 100644
index 00000000..1d374198
--- /dev/null
+++ b/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chisel3.internal
+
+import scala.language.experimental.macros
+import scala.annotation.StaticAnnotation
+import scala.reflect.macros.whitebox
+
+
+private[chisel3] object instantiableMacro {
+
+ def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
+ import c.universe._
+ def processBody(stats: Seq[Tree]): (Seq[Tree], Iterable[Tree]) = {
+ val extensions = scala.collection.mutable.ArrayBuffer.empty[Tree]
+ extensions += q"implicit val mg = new chisel3.internal.MacroGenerated{}"
+ val resultStats = stats.flatMap {
+ case x @ q"@public val $tpname: $tpe = $name" if tpname.toString() == name.toString() =>
+ extensions += atPos(x.pos)(q"def $tpname = module._lookup(_.$tpname)")
+ Nil
+ case x @ q"@public val $tpname: $tpe = $_" =>
+ extensions += atPos(x.pos)(q"def $tpname = module._lookup(_.$tpname)")
+ Seq(x)
+ case x @ q"@public lazy val $tpname: $tpe = $_" =>
+ extensions += atPos(x.pos)(q"def $tpname = module._lookup(_.$tpname)")
+ Seq(x)
+ case other => Seq(other)
+ }
+ (resultStats, extensions)
+ }
+ val result = {
+ val (clz, objOpt) = annottees.map(_.tree).toList match {
+ case Seq(c, o) => (c, Some(o))
+ case Seq(c) => (c, None)
+ }
+ val (newClz, implicitClzs, tpname) = clz match {
+ case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
+ val defname = TypeName(tpname + c.freshName())
+ val instname = TypeName(tpname + c.freshName())
+ val (newStats, extensions) = processBody(stats)
+ (q""" $mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents with chisel3.experimental.hierarchy.IsInstantiable { $self => ..$newStats } """,
+ Seq(q"""implicit class $defname(module: chisel3.experimental.hierarchy.Definition[$tpname]) { ..$extensions }""",
+ q"""implicit class $instname(module: chisel3.experimental.hierarchy.Instance[$tpname]) { ..$extensions } """),
+ tpname)
+ case q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
+ val defname = TypeName(tpname + c.freshName())
+ val instname = TypeName(tpname + c.freshName())
+ val (newStats, extensions) = processBody(stats)
+ (q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents with chisel3.experimental.hierarchy.IsInstantiable { $self => ..$newStats }",
+ Seq(q"""implicit class $defname(module: chisel3.experimental.hierarchy.Definition[$tpname]) { ..$extensions }""",
+ q"""implicit class $instname(module: chisel3.experimental.hierarchy.Instance[$tpname]) { ..$extensions } """),
+ tpname)
+ }
+ val newObj = objOpt match {
+ case None => q"""object ${tpname.toTermName} { ..$implicitClzs } """
+ case Some(obj @ q"$mods object $tname extends { ..$earlydefns } with ..$parents { $self => ..$body }") =>
+ q"""
+ $mods object $tname extends { ..$earlydefns } with ..$parents { $self =>
+ ..$implicitClzs
+ ..$body
+ }
+ """
+ }
+ q"""
+ $newClz
+
+ $newObj
+ """
+ }
+ c.Expr[Any](result)
+ }
+}
+
+private[chisel3] class instantiable extends StaticAnnotation {
+ def macroTransform(annottees: Any*): Any = macro instantiableMacro.impl
+}
+private[chisel3] class public extends StaticAnnotation