我与斯卡拉2.10微距功能试验。 我在某些情况下使用LabelDef麻烦,虽然。 在一定程度上我在编译器的代码偷看,阅读摘录米格尔·加西亚的论文 ,但我仍然坚持。
如果我的理解是正确的 ,伪的定义是:
LabelDef(labelName, listOfParameters, stmsAndApply)
其中3个参数是树木和:
- labelName
在标签$ L的标识符被定义
- listOfParameters
对应于传递的参数时,无标记申请时,如$ L(A1,...,AN),并且可以为空
- stmsAndApply
对应语句块(可能没有)和最终应用 -expression
标签应用这意味着更多的或多或少的一个GOTO到标签
例如,在一个简单的循环的情况下,可以LabelDef最终应用本身:
LabelDef($L, (), {...; $L()})
现在,如果我想定义2 LabelDef是跳到对方:
...
LabelDef($L1, (), $L2())
...
LabelDef($L2, (), $L1())
...
第二届LabelDef是好的,但是编译器输出一号错误,“未发现:价值$ L2”。 我想这是因为$ L2尚未确定,同时也将其应用的尝试。 这是正在建设一个树,以便将是有意义的我。 我的理解是正确的那么远? 因为如果预期没有错误,这意味着我的宏实现可能是马车。
无论如何,我相信一定会有申请从$ L1, 不知何故 $ L2(即跳转到$ L2)的方式,但我只是不知道如何做到这一点。 是否有人有这样做的例子,或任何指针?
其他不清楚的地方(但不太关心现在)关于宏使用LabelDef是:
- 什么第二个说法是,具体地说,它是如何使用的,当非空? 换句话说,什么是机制与参数标签申请?
-is它有效投入在第三个参数的最终表达任何东西比一个标签申请? (不,我不能尝试,但宏尚处于实验阶段)
-is可以进行转发的LabelDef外标签申请? (也许这是一个多余的问题)
在回答任何宏实现的例子,当然很欢迎!
干杯,
因为如果预期没有错误,这意味着我的宏实现可能是马车。
是的,这似乎是一个bug(^^;无论是否故意存在,虽然我不知道有座/ LabelDef组合的限制。
def EVIL_LABELS_MACRO = macro EVIL_LABELS_MACRO_impl
def EVIL_LABELS_MACRO_impl(c:Context):c.Expr[Unit] = { // fails to expand
import c.universe._
val lt1 = newTermName("$L1"); val lt2 = newTermName("$L2")
val ld1 = LabelDef(lt1, Nil, Block(c.reify{println("$L1")}.tree, Apply(Ident(lt2), Nil)))
val ld2 = LabelDef(lt2, Nil, Block(c.reify{println("$L2")}.tree, Apply(Ident(lt1), Nil)))
c.Expr( Block(ld1, c.reify{println("ignored")}.tree, ld2) )
}
def FINE_LABELS_MACRO = macro FINE_LABELS_MACRO_impl
def FINE_LABELS_MACRO_impl(c:Context):c.Expr[Unit] = { // The End isn't near
import c.universe._
val lt1 = newTermName("$L1"); val lt2 = newTermName("$L2")
val ld1 = LabelDef(lt1, Nil, Block(c.reify{println("$L1")}.tree, Apply(Ident(lt2), Nil)))
val ld2 = LabelDef(lt2, Nil, Block(c.reify{println("$L2")}.tree, Apply(Ident(lt1), Nil)))
c.Expr( Block(ld1, c.reify{println("ignored")}.tree, ld2, c.reify{println("The End")}.tree) )
}
我想,一座座被解析成{报表; 表达}因此最后一个参数是表达 。 如果LabelDef“落入” 表达 ,例如在EVIL_LABELS_MACRO图案,其膨胀不会在语句可见; 因此,“未发现:价值$ L2”的错误。
因此,它是更好地确保所有LabelDef“下降” 的语句 。 FINE_LABELS_MACRO这是否和扩展为:
{
$L1(){
scala.this.Predef.println("$L1");
$L2()
};
scala.this.Predef.println("ignored");
$L2(){
scala.this.Predef.println("$L2");
$L1()
};
scala.this.Predef.println("The End")
}