I want to use the power of Scala's pattern matching within a set of `condition-action' rules. These rules are not known in advance, but rather are generated at runtime according to some complex critera. The algorithmic generation mechanism can be considered as a completely separate and is not part of this question, which is concerned with how to express this via Scala reflection/quasiquotes.
Concretely, I'm looking to generate case definitions (of the general form case v0@x(v1,_,v2): X => f(v1,v2)
) at runtime.
It is presumably possible to do this via toolBox.parse(str)
for some string that is generated at runtime. However, if possible it would seem desirable to incorporate a greater degree of type-safety than this:
More specifically, I want the case defs to match against a sealed case class hierarchy of Terms (Term,Var(name: Char),Lit(value:Int),Group(a: Term,b: Term,c: Term)
).
For example, the generated case def would in general, return some function of none, some or all of v0,v1,v2:
t match {
case v0@Group(v1@_,v2@Var('a')) => Group(v2,v0,Group(v1,Var('z'),Lit(17))) // etc
}
I'm attempting to follow through on the description of quasiquotes for case defs given here, but the syntax is rather mind-bending (and eclipse with Scala 2.11 refuses to show me the types), so below is as far as I've got. My specific questions are embedded in the code:
def dynamicMatch(condition: SomeType, action: SomeType, tb: ToolBox)
(t: Term): Option[Term] = {
// Q1. What type should condition and action be for maximum
// typesafety in the calling code? Symbols? Quasiquotes?
// Would they best be combined into a single actual CaseDef?
// This is obviously a hardcoded placeholder expression, in general:
// Q2. How to bind in t, condition and action?
val q"$expr match { case ..$cases }" =
q"foo match { case _ : Term => Some(expr) case _ => None }"
val cq"$pat1 => $body1" :: cq"$pat2 => $body2" :: Nil = cases
// Q3. how should this be invoked to return the desired result?
???
}