gpt4 book ai didi

scala - Scala宏可以打印代码?

转载 作者:行者123 更新时间:2023-12-03 21:07:02 24 4
gpt4 key购买 nike

我想做这样的事情:

def assuming[A](condition: => Boolean)(f: => A): A = {
require(condition, /* print source-code of condition */)
f
}

用法示例:
def fib(n: Int) = n match { // yes, yes, I know this is not efficient
case 0 => 0
case 1 => 1
case i => assuming(i > 0) { fib(i-1) + fib(i-2) }
}

现在,例如,如果您调用 fib(-20),我希望它引发异常,并显示诸如 Assertion failed: -20 > 0Assertation failed: i > 0的消息

最佳答案

杜德(Dude),断言宏不是您学习的如何使用宏的基本用例之一吗?

好吧,那也是我的想法。

在我的其他答案中,“拾音片段”是指specs2做in its s2 macro

或者,您可以将其表示为in my variant rip-off of expecty

我以为我会在两行中将您的示例输入REPL。毕竟,您只是尝试从与代表您的条件的树相对应的源中打印摘录。

有什么会更容易?

当然,在-Yrangepos下更容易,但是我们可以假设位置。

我愿意分享失去兴趣之前我走了多远。

人们(例如paulp,他是vox paulpuli)希望树上有代表“我在键盘上键入的来源”的附件,因为,您知道,也许我想用它来发送消息或弄清楚用户想要做什么。完成。

谓词p似乎没有范围位置。因此,另一个想法是,我们知道宏应用程序的开始,它是第二个参数列表的paren,因此可以与第一个参数列表的结束paren匹配,通过源进行向后工作。

请注意,showCode并没有帮助,因为对于像10 < 5这样的条件,它会显示false,并整齐地折叠。

object X {
import reflect.macros.blackbox.Context
def impl[A: c.WeakTypeTag](c: Context)(p: c.Expr[Boolean])(body: c.Expr[A]) = {
import c.universe._
def treeLine(t: Tree): String = lineAt(t.pos)
def lineAt(pos: Position): String = if (pos.isRange) pos.lineContent.drop(pos.column - 1).take(pos.end - pos.start + 1) else "???"
val msg =
if (p.tree.pos.isRange) { // oh, joy
treeLine(p.tree)
} else {
/*
Console println s"content ${p.tree.pos.lineContent}"
Console println s"column ${p.tree.pos.column}" // alas, that's the column of the point of the top of the tree, e.g., < in "a < b".
val len = body.tree.pos.start - p.tree.pos.start
p.tree.pos.lineContent drop (p.tree.pos.column - 1) take len
*/
// OK, I get it: positions are a big mystery. Make woo-woo ghost noises.
// What we do know is the start of the apply, which must have a close paren or brace in front of it to match:
// apply(condition)(body)
showCode(p.tree)
}
q"require($p, $msg) ; $body"
}
def x[A](p: Boolean)(body: =>A): A = macro X.impl[A]
}

我只是想通过这种方式获得好职位:
object X {
import reflect.macros.blackbox.Context
def impl(c: Context)(p: c.Expr[Boolean]) = {
import c.universe._
def lineAt(pos: Position): String = if (pos.isRange) pos.lineContent.drop(pos.column - 1).take(pos.end - pos.start + 1) else "???"
val msg = lineAt(c.macroApplication.pos) // oh, joy
q"require($p, $msg) ; new { def apply[A](body: =>A): A = body }"
}
def x(p: Boolean): { def apply[A](body: =>A): A } = macro X.impl
}

用法 x(10 < 5)(println("hi")): requirement failed: (10 < 5)(p即将结束。 margin 错误。

关于scala - Scala宏可以打印代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23261082/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com