简体   繁体   中英

How to write a Scala macro that evaluates to a Tree similar to “reify”

I want to write a macro that captures a program snippet and makes it available as a Tree at runtime. Basically, I want the functionality of reify but embed it in a different syntax. I want to call apply on a Workload companion object, supply some code and store the Tree of the supplied code in a member of a newly created Workload object.

val wl = Workload {
  // some code ...
}

wl.tree // Tree of 'some code'

Unfortunately, I can not just forward to reify because its a macro. I guess, I have to write my own macro similar to reify . But I have no idea how to return a Tree from a macro and the source of reify just mentions some hardwired implementation.

How can this be accomplished?

Update

I wrote a small example to underline my point

import scala.reflect.runtime.universe._

object MacroFun {
  import scala.reflect.macros.blackbox.Context
  import scala.language.experimental.macros

  def getSomeTree: Expr[Unit] = macro getTreeImpl

  def getTreeImpl(c: Context): c.Expr[Expr[Unit]] = {
    import c.universe._

    val expr = reify {
      println("Hello World!")
    }

    ???
  }
}

The only thing that is missing, is a way to turn expr into an c.Expr[Expr[Unit]]

Here is how I did it in the end. Just make sure to call reify on the runtime universe to get a Expr that does not depend on a Context .

class ErplMacro(val c: Context) {
  def lift[T:c.WeakTypeTag](exp: c.Expr[T]) = {
    import c.universe._
    q"""ErplRuntime.compile(scala.reflect.runtime.universe.reify($exp))"""
  }
}

object ErplRuntime {
  def compile[T](ctxElems: (scala.Symbol,Any)*)(exp: Expr[T]): Unit = // ...
}

trait ErplApi {
  def compile[T](exp: T): Unit = macro ErplMacro.lift[T]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM