Scala中焚烧使用LabelDef(2.10)(Using LabelDef in scala m

2019-07-30 15:35发布

我与斯卡拉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外标签申请? (也许这是一个多余的问题)

在回答任何宏实现的例子,当然很欢迎!
干杯,

Answer 1:

因为如果预期没有错误,这意味着我的宏实现可能是马车。
是的,这似乎是一个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")
}


文章来源: Using LabelDef in scala macros (2.10)