diff --git a/README.md b/README.md new file mode 100644 index 0000000..be1eb92 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# Scala3 编译期代码生成探索 + +`Scala3` 新增的 `inline` 和 quoted Expression 的可以简化代码生成逻辑。 + +大部分场景不用在 `macro` 对 Ast 进行复杂模式匹配来分析代码。 + + +## 核心思路 使用 inline 和 `FromExpr` 代替大部分 parsing 工作 + +`FromExpr` 是 `scala3` 内置的 typeclass,用来获取编译期值 。 + + +```scala +inline def compile(inline x: Dsl): Option[String] = ${ compileImpl('x) } + +private def compileImpl(x: Expr[Dsl])(using Quotes): Expr[Option[String]] = { + import quotes.reflect.* + x.value match { + case Some(xv) => '{ Some(${ Expr(xv.ast.toString()) }) } + case None => '{ None } + } +} +``` +如上述代码所示,只要提供 `FromExpr[Dsl]` 就可以通过 `x.value` 在编译期获取到值 + +## Function parsing + +`scala` 当前没有对函数进行模式匹配简单方法,所以还是只能通过解析 Ast 来实现,或者如 `slick` 那样通过操作符重载实现 diff --git a/src/main/scala/minisql/dsl.scala b/src/main/scala/minisql/dsl.scala index 106bc6e..64346db 100644 --- a/src/main/scala/minisql/dsl.scala +++ b/src/main/scala/minisql/dsl.scala @@ -65,7 +65,6 @@ private def compileImpl(x: Expr[Dsl])(using Quotes): Expr[Option[String]] = { case Some(xv) => '{ Some(${ Expr(xv.ast.toString()) }) } case None => '{ None } } - } case class Foo(id: Long)