Skip to content

Instantly share code, notes, and snippets.

@lancelet
Last active March 2, 2016 10:19
Show Gist options
  • Save lancelet/9ca9ed48a9b37e689ff8 to your computer and use it in GitHub Desktop.
Save lancelet/9ca9ed48a9b37e689ff8 to your computer and use it in GitHub Desktop.
WillBeTrue
// (This is an older version of the Gist here: https://gist.github.com/lancelet/0d0713af7eb1401c9b1a)
// (Only hanging around because I posted it to a Gitter group.)
// Intended to be run in shapeless current master sbt console; use :paste
//--- paste this first to define the macro
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import scala.util.control.NonFatal
object WillBeTrue {
def apply(code: String): Boolean = macro WillBeTrueMacros.applyImpl
}
@macrocompat.bundle
class WillBeTrueMacros(val c: whitebox.Context) {
import c.universe._
def applyImpl(code: Tree): Tree = {
// unpack the string
val Literal(Constant(codeStr: String)) = code
// try to compile it and evaluate it as a Boolean
try {
val tree = c.parse(s"{ { $codeStr }: Boolean }")
val boolExpr = c.Expr[Boolean](tree)
val result: Boolean = c.eval(boolExpr)
q"$result"
} catch {
case NonFatal(e) =>
// println(s"Exception: $e")
q"false"
}
}
}
//--- paste this second
val wontCompile: Boolean = WillBeTrue(""" ("LambdaJam!": Int) == 42 """)
val willCompile: Boolean = WillBeTrue(""" (42: Int) == 42""")
val compilesButWrong: Boolean = WillBeTrue(""" (42: Int) == 43 """)
// expected result:
// wontCompile: Boolean = false
// willCompile: Boolean = true
// compilesButWrong: Boolean = false
// limitation: this doesn't work; my macro-fu fails me
val x = true; WillBeTrue(""" x """) // false (arrgh! - why, Scala, why?)
// ok - I figured out the answer. c.eval() is attempting to evaluate x at compile time,
// and so it doesn't know the value. Instead, you have to splice a tree back in which
// refers to x, like in this (updated) Gist:
// https://gist.github.com/lancelet/0d0713af7eb1401c9b1a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment