2013-08-28 4 views
1

Я деконструкции Функция, он получил vparams, и теперь я могу назвать:Как передать аргументы функции произвольного числа параметров с помощью макроса?

case class Action(f: Function, ts: List[TypeName]) { 
    def render(ruleName: String): Expr[Unit] = c.Expr[Unit](q""" 
     val p = ${c.prefix} 
     val value1 = p.valueStack.pop().asInstanceOf[${ts(0)}] 
     val value2 = p.valueStack.pop().asInstanceOf[${ts(1)}] 
     p.valueStack.push($f(value1, value2)) 
    """) 
    } 

е имеет произвольное число параметров, которые, как известно, во время компиляции.

Как пройти ts.count параметры из p.valueStack к функции е?

ответ

1

Как о чем-то вроде этого:

case class Action(f: Function, ts: List[TypeName]) { 
    def render(ruleName: String): Expr[Unit] = { 
    val argNames = (1 to ts.size).map(i => newTermName(s"value$i")) 
    val args = argNames.map(name => Ident(name)) 
    val valDefs = (ts zip argNames).map { 
     case (tn, argName) => 
     q"val $argName = p.valueStack.pop().asInstanceOf[$tn]" 
    } 

    c.Expr[Unit](q""" 
     val p = ${c.prefix} 
     ..$valDefs 
     p.valueStack.push($f(..$args)) 
     """) 
    } 
} 

Это компилирует (в Scala 2.10.2 с Macro Paradise плагин), но я не проверял, работает ли он.

+0

В конечном счете это действительно работает. Вы можете найти святую магию в [parboiled2 wip branch] (https://github.com/sirthias/parboiled2/commit/e6f0f51b6a13cabb713916855b37155dabedc8a0#L2R231) –