增加解析 case (x, y) =>
函数定义
This commit is contained in:
parent
adc60400a7
commit
f5e43657b3
9 changed files with 63 additions and 53 deletions
|
@ -3,10 +3,9 @@ name := "minisql"
|
||||||
scalaVersion := "3.7.1"
|
scalaVersion := "3.7.1"
|
||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"org.scalameta" %% "munit" % "1.0.3" % Test
|
"org.scalameta" %% "munit" % "1.1.1" % Test
|
||||||
)
|
)
|
||||||
|
|
||||||
javaOptions ++= Seq("-Xss16m")
|
|
||||||
|
|
||||||
scalacOptions ++= Seq(
|
scalacOptions ++= Seq(
|
||||||
"-deprecation",
|
"-deprecation",
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
sbt.version=1.10.10
|
sbt.version=1.11.2
|
||||||
|
|
|
@ -72,9 +72,6 @@ private def joinQueryOf[E1, E2](
|
||||||
'{
|
'{
|
||||||
Join($jt, $a, $b, $aliasA, $aliasB, $on)
|
Join($jt, $a, $b, $aliasA, $aliasB, $on)
|
||||||
}
|
}
|
||||||
case o =>
|
|
||||||
println("====================---" + o.show)
|
|
||||||
throw new Exception(s"Fail")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,9 +164,6 @@ private given FromExpr[Query] with {
|
||||||
Some(FlatJoin(t, a, ia, on))
|
Some(FlatJoin(t, a, ia, on))
|
||||||
case '{ Nested(${ Expr(a) }) } =>
|
case '{ Nested(${ Expr(a) }) } =>
|
||||||
Some(Nested(a))
|
Some(Nested(a))
|
||||||
case o =>
|
|
||||||
// println(s"Cannot extract ${o.show}")
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,6 +400,20 @@ private given FromExpr[If] with {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private given FromExpr[Block] with {
|
||||||
|
def unapply(x: Expr[Block])(using Quotes): Option[Block] = x match {
|
||||||
|
case '{ Block(${ Expr(statements) }) } =>
|
||||||
|
Some(Block(statements))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private given FromExpr[Val] with {
|
||||||
|
def unapply(x: Expr[Val])(using Quotes): Option[Val] = x match {
|
||||||
|
case '{ Val(${ Expr(n) }, ${ Expr(b) }) } =>
|
||||||
|
Some(Val(n, b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension (e: Expr[Any]) {
|
extension (e: Expr[Any]) {
|
||||||
private def toTerm(using Quotes) = {
|
private def toTerm(using Quotes) = {
|
||||||
import quotes.reflect.*
|
import quotes.reflect.*
|
||||||
|
@ -411,30 +422,6 @@ extension (e: Expr[Any]) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private def fromBlock(using
|
|
||||||
Quotes
|
|
||||||
)(block: quotes.reflect.Block): Option[Ast] = {
|
|
||||||
import quotes.reflect.*
|
|
||||||
val empty: Option[List[Ast]] = Some(Nil)
|
|
||||||
val stmts = block.statements.foldLeft(empty) { (r, stmt) =>
|
|
||||||
stmt match {
|
|
||||||
case ValDef(n, _, Some(body)) =>
|
|
||||||
r.flatMap { astList =>
|
|
||||||
body.asExprOf[Ast].value.map { v =>
|
|
||||||
astList :+ v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case o =>
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stmts.flatMap { stmts =>
|
|
||||||
block.expr.asExprOf[Ast].value.map { last =>
|
|
||||||
minisql.ast.Block(stmts :+ last)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
given astFromExpr: FromExpr[Ast] = new FromExpr[Ast] {
|
given astFromExpr: FromExpr[Ast] = new FromExpr[Ast] {
|
||||||
|
|
||||||
def unapply(e: Expr[Ast])(using Quotes): Option[Ast] = {
|
def unapply(e: Expr[Ast])(using Quotes): Option[Ast] = {
|
||||||
|
@ -444,6 +431,7 @@ given astFromExpr: FromExpr[Ast] = new FromExpr[Ast] {
|
||||||
case '{ $x: ScalarValueLift } => x.value
|
case '{ $x: ScalarValueLift } => x.value
|
||||||
case '{ $x: Property } => x.value
|
case '{ $x: Property } => x.value
|
||||||
case '{ $x: Ident } => x.value
|
case '{ $x: Ident } => x.value
|
||||||
|
case '{ $x: Val } => x.value
|
||||||
case '{ $x: Tuple } => x.value
|
case '{ $x: Tuple } => x.value
|
||||||
case '{ $x: Value } => x.value
|
case '{ $x: Value } => x.value
|
||||||
case '{ $x: Operation } => x.value
|
case '{ $x: Operation } => x.value
|
||||||
|
@ -453,6 +441,7 @@ given astFromExpr: FromExpr[Ast] = new FromExpr[Ast] {
|
||||||
case '{ $x: Infix } => x.value
|
case '{ $x: Infix } => x.value
|
||||||
case '{ $x: CaseClass } => x.value
|
case '{ $x: CaseClass } => x.value
|
||||||
case '{ $x: OptionOperation } => x.value
|
case '{ $x: OptionOperation } => x.value
|
||||||
|
case '{ $x: Block } => x.value
|
||||||
case o =>
|
case o =>
|
||||||
import quotes.reflect.*
|
import quotes.reflect.*
|
||||||
report.warning(s"Cannot get value from ${o.show}", o.asTerm.pos)
|
report.warning(s"Cannot get value from ${o.show}", o.asTerm.pos)
|
||||||
|
|
|
@ -22,6 +22,25 @@ private[parsing] def statementParsing(astParser: => Parser[ast.Ast])(using
|
||||||
valDefParser
|
valDefParser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private[parsing] def parseBlockList(
|
||||||
|
astParser: => Parser[ast.Ast],
|
||||||
|
e: Expr[Any]
|
||||||
|
)(using Quotes): List[Expr[ast.Ast]] = {
|
||||||
|
import quotes.reflect.*
|
||||||
|
|
||||||
|
lazy val statementParser = statementParsing(astParser)
|
||||||
|
|
||||||
|
e.asTerm match {
|
||||||
|
case Block(st, t) =>
|
||||||
|
(st :+ t).map {
|
||||||
|
case e if e.isExpr => astParser(e.asExpr)
|
||||||
|
case `statementParser`(x) => x
|
||||||
|
case o =>
|
||||||
|
report.errorAndAbort(s"Cannot parse statement: ${o.show}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private[parsing] def blockParsing(
|
private[parsing] def blockParsing(
|
||||||
astParser: => Parser[ast.Ast]
|
astParser: => Parser[ast.Ast]
|
||||||
)(using Quotes): Parser[ast.Ast] = {
|
)(using Quotes): Parser[ast.Ast] = {
|
||||||
|
|
|
@ -1,12 +1 @@
|
||||||
package minisql.parsing
|
|
||||||
|
|
||||||
import minisql.ast
|
|
||||||
import scala.quoted.*
|
|
||||||
|
|
||||||
private[parsing] def infixParsing(
|
|
||||||
astParser: => Parser[ast.Ast]
|
|
||||||
)(using Quotes): Parser[ast.Infix] = {
|
|
||||||
|
|
||||||
import quotes.reflect.*
|
|
||||||
???
|
|
||||||
}
|
|
||||||
|
|
|
@ -59,7 +59,6 @@ private[minisql] object Parsing {
|
||||||
.orElse(ifParser)
|
.orElse(ifParser)
|
||||||
.orElse(traversableOperationParser)
|
.orElse(traversableOperationParser)
|
||||||
.orElse(patMatchParser)
|
.orElse(patMatchParser)
|
||||||
// .orElse(infixParser)
|
|
||||||
.orElse {
|
.orElse {
|
||||||
case o =>
|
case o =>
|
||||||
val str = scala.util.Try(o.show).getOrElse("")
|
val str = scala.util.Try(o.show).getOrElse("")
|
||||||
|
@ -106,8 +105,6 @@ private[minisql] object Parsing {
|
||||||
}
|
}
|
||||||
lazy val patMatchParser: Parser[ast.Ast] = patMatchParsing(astParser)
|
lazy val patMatchParser: Parser[ast.Ast] = patMatchParsing(astParser)
|
||||||
|
|
||||||
// lazy val infixParser: Parser[ast.Infix] = infixParsing(astParser)
|
|
||||||
|
|
||||||
lazy val traversableOperationParser: Parser[ast.IterableOperation] =
|
lazy val traversableOperationParser: Parser[ast.IterableOperation] =
|
||||||
traversableOperationParsing(astParser)
|
traversableOperationParsing(astParser)
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,22 @@ private[parsing] def patMatchParsing(
|
||||||
|
|
||||||
termParser {
|
termParser {
|
||||||
// Val defs that showd pattern variables will cause error
|
// Val defs that showd pattern variables will cause error
|
||||||
case e @ Match(t, List(CaseDef(IsTupleUnapply(binds), None, body))) =>
|
case e @ Match(
|
||||||
val bm = binds.zipWithIndex.map {
|
Ident(t),
|
||||||
case (Bind(n, ident), idx) =>
|
List(CaseDef(IsTupleUnapply(binds), None, body))
|
||||||
n -> Select.unique(t, s"_${idx + 1}")
|
) =>
|
||||||
}.toMap
|
val bindStmts = binds.map {
|
||||||
blockParsing(astParser)(body.asExpr)
|
case Bind(bn, _) =>
|
||||||
|
'{
|
||||||
|
ast.Val(
|
||||||
|
ast.Ident(${ Expr(bn) }),
|
||||||
|
ast.Property(ast.Ident(${ Expr(t) }), "_1")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val allStmts = bindStmts ++ parseBlockList(astParser, body.asExpr)
|
||||||
|
'{ ast.Block(${ Expr.ofList(allStmts.toList) }) }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,4 +124,14 @@ class FromExprsSuite extends FunSuite {
|
||||||
testFor("CaseClass") {
|
testFor("CaseClass") {
|
||||||
CaseClass(List(("name", Ident("value"))))
|
CaseClass(List(("name", Ident("value"))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testFor("Block") { // Also tested Val
|
||||||
|
Block(
|
||||||
|
List(
|
||||||
|
Val(Ident("x"), Constant(1)),
|
||||||
|
Val(Ident("y"), Constant(2)),
|
||||||
|
BinaryOperation(Ident("x"), NumericOperator.+, Ident("y"))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue