summaryrefslogtreecommitdiff
path: root/macros
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
parente63b9667d89768e0ec6dc8a9153335cb48a213a7 (diff)
parent958904cb2f2f65d02b2ab3ec6d9ec2e06d04e482 (diff)
Merge branch 'master' into 3.5-release
Diffstat (limited to 'macros')
-rw-r--r--macros/src/main/scala/chisel3/internal/InstantiableMacro.scala77
-rw-r--r--macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala48
2 files changed, 125 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
diff --git a/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala b/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala
index 4533aa39..a8a7e8d5 100644
--- a/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala
+++ b/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala
@@ -47,6 +47,36 @@ class InstTransform(val c: Context) extends SourceInfoTransformMacro {
}
// Workaround for https://github.com/sbt/sbt/issues/3966
+object DefinitionTransform
+// Module instantiation transform
+class DefinitionTransform(val c: Context) extends SourceInfoTransformMacro {
+ import c.universe._
+ def apply[T: c.WeakTypeTag](proto: c.Tree): c.Tree = {
+ q"$thisObj.do_apply($proto)($implicitSourceInfo, $implicitCompileOptions)"
+ }
+}
+
+object DefinitionWrapTransform
+// Module instantiation transform
+class DefinitionWrapTransform(val c: Context) extends SourceInfoTransformMacro {
+ import c.universe._
+ def wrap[T: c.WeakTypeTag](proto: c.Tree): c.Tree = {
+ q"$thisObj.do_wrap($proto)($implicitSourceInfo)"
+ }
+}
+
+
+// Workaround for https://github.com/sbt/sbt/issues/3966
+object InstanceTransform
+// Module instantiation transform
+class InstanceTransform(val c: Context) extends SourceInfoTransformMacro {
+ import c.universe._
+ def apply[T: c.WeakTypeTag](definition: c.Tree): c.Tree = {
+ q"$thisObj.do_apply($definition)($implicitSourceInfo, $implicitCompileOptions)"
+ }
+}
+
+// Workaround for https://github.com/sbt/sbt/issues/3966
object MemTransform
class MemTransform(val c: Context) extends SourceInfoTransformMacro {
import c.universe._
@@ -81,9 +111,27 @@ class VecTransform(val c: Context) extends SourceInfoTransformMacro {
def tabulate(n: c.Tree)(gen: c.Tree): c.Tree = {
q"$thisObj.do_tabulate($n)($gen)($implicitSourceInfo, $implicitCompileOptions)"
}
+ def tabulate2D(n: c.Tree, m: c.Tree)(gen: c.Tree): c.Tree = {
+ q"$thisObj.do_tabulate($n,$m)($gen)($implicitSourceInfo, $implicitCompileOptions)"
+ }
+ def tabulate3D(n: c.Tree, m: c.Tree, p: c.Tree)(gen: c.Tree): c.Tree = {
+ q"$thisObj.do_tabulate($n,$m,$p)($gen)($implicitSourceInfo, $implicitCompileOptions)"
+ }
def fill(n: c.Tree)(gen: c.Tree): c.Tree = {
q"$thisObj.do_fill($n)($gen)($implicitSourceInfo, $implicitCompileOptions)"
}
+ def fill2D(n: c.Tree, m: c.Tree)(gen: c.Tree): c.Tree = {
+ q"$thisObj.do_fill($n,$m)($gen)($implicitSourceInfo, $implicitCompileOptions)"
+ }
+ def fill3D(n: c.Tree, m: c.Tree, p: c.Tree)(gen: c.Tree): c.Tree = {
+ q"$thisObj.do_fill($n,$m,$p)($gen)($implicitSourceInfo, $implicitCompileOptions)"
+ }
+ def fill4D(n: c.Tree, m: c.Tree, p: c.Tree, q: c.Tree)(gen: c.Tree): c.Tree = {
+ q"$thisObj.do_fill($n,$m,$p,$q)($gen)($implicitSourceInfo, $implicitCompileOptions)"
+ }
+ def iterate(start: c.Tree, len: c.Tree)(f: c.Tree): c.Tree = {
+ q"$thisObj.do_iterate($start,$len)($f)($implicitSourceInfo, $implicitCompileOptions)"
+ }
def contains(x: c.Tree)(ev: c.Tree): c.Tree = {
q"$thisObj.do_contains($x)($implicitSourceInfo, $ev, $implicitCompileOptions)"
}