加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在scala宏中使用LabelDef(2.10)

发布时间:2020-12-16 18:30:01 所属栏目:安全 来源:网络整理
导读:我正在尝试使用 scala 2.10宏功能.但是,在某些情况下我无法使用LabelDef.在某种程度上,我偷看了编译器的代码,阅读 Miguel Garcia’s papers的摘录,但我仍然卡住了. 如果我的理解是正确的,那么伪定义将是: ?LabelDef(labelName,listOfParameters,stmsAndAppl
我正在尝试使用 scala 2.10宏功能.但是,在某些情况下我无法使用LabelDef.在某种程度上,我偷看了编译器的代码,阅读 Miguel Garcia’s papers的摘录,但我仍然卡住了.

如果我的理解是正确的,那么伪定义将是:
?LabelDef(labelName,listOfParameters,stmsAndApply),其中3个参数是Trees和:
– labelName是正在定义的标签$L的标识符
– listOfParameters对应于发生label-apply时传递的参数,如$L(a1,…,an),并且可以为空
– stmsAndApply对应于语句块(可能没有)和最终的apply-expression
label-apply或多或少意味着标签的GOTO

例如,在简单循环的情况下,LabelDef最终可以自行应用:
LabelDef($L,(),{…; $L()})

现在,如果我想定义2个彼此跳转的LabelDef:

...
LabelDef($L1,$L2())
...
LabelDef($L2,$L1())
...

第二个LabelDef很好,但是编译器在第一个输出错误,“未找到:值$L2”.我想这是因为在尝试应用它时,还没有定义$L2.这是一棵正在建造的树,这对我来说很有意义.到目前为止我的理解是否正确?因为如果没有预期的错误,这意味着我的宏实现可能是错误的.

无论如何,我认为必须有一种方法可以从$L1中应用$L2(即跳到$L2),不知何故,但我不知道如何做到这一点.有人有这样做的例子,或任何指针?

关于在宏中使用LabelDef的其他不明确点(但现在不太关注)是:
– 具体来说,第二个参数是什么,当非空时它是如何使用的?换句话说,标签应用参数的机制是什么?
– 除了label-apply之外,将第三个参数的最终表达式放在第三个参数中是否有效? (不是我不能尝试,但宏仍然是实验性的)
– 是否可以在LabelDef外执行转发标签? (也许这是一个多余的问题)

当然,答案中的任何宏实现示例都非常受欢迎!
干杯,

解决方法

因为如果没有预期的错误,这意味着我的宏实现可能是错误的.
是的,这似乎是一个错误(^^;虽然我不确定是否存在Block / 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,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,ld2,c.reify{println("The End")}.tree) )
}

我认为一个Block被解析为{statements;表达式}因此最后一个参数是表达式.如果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")
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读