13

在 Scala 中使用 SBT 工具链时,是否可以编写一个任务来读取项目源代码的特殊部分以在编译时生成 scala 代码。

关于此的任何想法甚至文章/教程?我正在寻找类似于 Template Haskell 的东西。

4

3 回答 3

13

treehugger.scala是一个为代码生成而设计的库。

import treehugger.forest._
import definitions._
import treehuggerDSL._

val tree: Tree = Predef_println APPLY LIT("Hello, world!")

println(tree)
println(treeToString(tree))

上面的代码打印了两行:

Apply(Ident(println),List(Literal(Constant(Hello, world!))))
println("Hello, world!")

treehugger 确实生成了一个 AST,但不符合 scalac 的 AST。

于 2012-07-09T18:49:14.673 回答
7

Scala 2.10 对类似于复杂的编译时代码生成的宏具有实验性支持。有关更多详细信息,请参见此处

Jason Zaugg 的macrocosm git 存储库中有一些有趣的示例,以及SLICK库,它是 ScalaQuery SQL DSL 的演变,使类型安全的数据库(和集合)查询能够以类似 LINQ 的方式表达。

而这个例子,来自expecty断言库:

import org.expecty.Expecty

case class Person(name: String = "Fred", age: Int = 42) {
  def say(words: String*) = words.mkString(" ")
}

val person = Person()
val expect = new Expecty()

...
val word1 = "ping"
val word2 = "pong"

expect {
  person.say(word1, word2) == "pong pong"
}

产量:

java.lang.AssertionError:

person.say(word1, word2) == "pong pong"
|      |   |      |      |
|      |   ping   pong   false
|      ping pong
Person(Fred,42)
于 2012-07-09T18:17:34.543 回答
5

我最近做了一些研究。几乎有3个选项可用:

  1. 字符串模板。
  2. 环境保护狂
  3. Scala 宏

更多细节在这里:http: //yefremov.net/blog/scala-code-generation/

于 2015-01-08T17:55:48.603 回答