Skip to content

Instantly share code, notes, and snippets.

@xeno-by
Created February 13, 2014 00:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xeno-by/8967571 to your computer and use it in GitHub Desktop.
Save xeno-by/8967571 to your computer and use it in GitHub Desktop.
import scala.language.experimental.macros
import scala.language.higherKinds
import scala.reflect.macros.blackbox.Context
case class Wrapper[A](arr: Array[A])
object Wrapper {
def literal[A](as: A*): Wrapper[A] = macro Example.wrapperMacro[A, Wrapper]
}
object Example {
def arrayMacro[A: c.WeakTypeTag](c: Context)(as: c.Expr[A]*): c.Expr[Array[A]] = {
import c.mirror._
import c.universe._
val n = as.length
val tpe = implicitly[c.WeakTypeTag[A]].tpe
val valdef = q"val arr = new Array[$tpe]($n)"
val updates = as.toList.zipWithIndex.map { case (a, i) =>
q"arr($i) = ${a.tree}"
}
c.Expr[Array[A]](Block(valdef :: updates, q"arr"))
}
def wrapperMacro[A: c.WeakTypeTag, M[_]](c: Context)(as: c.Expr[A]*): c.Expr[M[A]] = {
import c.mirror._
import c.universe._
val arr = arrayMacro(c)(as: _*)
c.Expr[M[A]](q"${c.prefix.tree.duplicate}($arr)")
}
}
=======
object Test extends App {
Wrapper.literal(1, 2, 3)
}
=======
01:44 ~/Projects/Master/sandbox (master)$ sst
[[syntax trees at end of typer]] // Test.scala
package <empty> {
object Test extends AnyRef with App {
def <init>(): Test.type = {
Test.super.<init>();
()
};
(Wrapper.apply[Int]({
val arr: Array[Int] = new Array[Int](3);
arr.update(0, 1);
arr.update(1, 2);
arr.update(2, 3);
arr
}): Wrapper[Int])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment