@@ -21,23 +21,10 @@ import scala.quoted._
21
21
22
22
23
23
object DiagrammedExprMacro {
24
- def let [S : Type , T : Type ](expr : Expr [S ])(body : Expr [S ] => Expr [T ]): Expr [T ] =
25
- ' {
26
- val x = $expr
27
- $ { body(' {x}) }
28
- }
29
-
30
- def lets [S : Type , T : Type ](xs : List [Expr [S ]])(body : List [Expr [S ]] => Expr [T ]): Expr [T ] = {
31
- def rec (xs : List [Expr [S ]], acc : List [Expr [S ]]): Expr [T ] = xs match {
32
- case Nil => body(acc)
33
- case x :: xs => let(x) { (x : Expr [S ]) => rec(xs, x :: acc) }
34
- }
35
- rec(xs, Nil )
36
- }
37
-
38
24
// Transform the input expression by parsing out the anchor and generate expression that can support diagram rendering
39
25
def parse [T : Type ](expr : Expr [T ])(implicit refl : Reflection ): Expr [DiagrammedExpr [T ]] = {
40
26
import refl ._
27
+ import util ._
41
28
42
29
def isXmlSugar (apply : Apply ): Boolean = apply.tpe <:< typeOf[scala.xml.Elem ]
43
30
def isJavaStatic (tree : Tree ): Boolean = tree.symbol.flags.is(Flags .Static )
@@ -49,6 +36,14 @@ object DiagrammedExprMacro {
49
36
50
37
def default : Expr [DiagrammedExpr [T ]] = ' { DiagrammedExpr .simpleExpr($expr, $ { getAnchor(expr) } ) }
51
38
39
+ def lets (xs : List [Term ])(body : List [Term ] => Term ): Term = {
40
+ def rec (xs : List [Term ], acc : List [Term ]): Term = xs match {
41
+ case Nil => body(acc)
42
+ case x :: xs => let(x) { (x : Term ) => rec(xs, x :: acc) }
43
+ }
44
+ rec(xs, Nil )
45
+ }
46
+
52
47
expr.unseal.underlyingArgument match {
53
48
case Apply (Select (New (_), _), _) => default
54
49
@@ -121,41 +116,45 @@ object DiagrammedExprMacro {
121
116
case Apply (sel @ Select (lhs, op), args) =>
122
117
type S
123
118
implicit val tpS : quoted.Type [S ] = lhs.tpe.seal.asInstanceOf [quoted.Type [S ]]
124
- val left = parse[S ](lhs.seal.asInstanceOf [Expr [S ]])
119
+ val left = parse[S ](lhs.seal.asInstanceOf [Expr [S ]]).unseal
125
120
val anchor = getAnchorForSelect(refl)(sel.asInstanceOf [Select ])
126
121
127
122
val rights = args.map { arg =>
128
123
type V
129
124
implicit val tpV : quoted.Type [V ] = arg.tpe.seal.asInstanceOf [quoted.Type [V ]]
130
- parse[V ](arg.seal.asInstanceOf [Expr [V ]])
125
+ parse[V ](arg.seal.asInstanceOf [Expr [V ]]).unseal
131
126
}
132
127
133
- let(left) { (l : Expr [DiagrammedExpr [_]]) =>
134
- lets(rights) { (rs : List [Expr [DiagrammedExpr [_]]]) =>
135
- val res = apply(' {($l).value}, op, Nil , rs)
136
- ' { DiagrammedExpr .applyExpr($l, $ {rs.toExprOfList}, $res, $anchor) }
128
+ let(left) { l =>
129
+ lets(rights) { rs =>
130
+ val left = l.seal.cast[DiagrammedExpr [_]]
131
+ val rights = rs.map(_.seal.cast[DiagrammedExpr [_]])
132
+ val res = Select .overloaded(' {$left.value}.unseal, op, Nil , rs).seal.cast[T ]
133
+ ' { DiagrammedExpr .applyExpr($left, $ {rights.toExprOfList}, $res, $anchor) }.unseal
137
134
}
138
- }
135
+ }.seal.cast[ DiagrammedExpr [ T ]]
139
136
140
137
// TODO: Dotty produces a confusing error message about `let`
141
- // case Apply(TypeApply(sel @ Select(lhs, op), targs), args) =>
142
- // type S
143
- // implicit val tpS: quoted.Type[S] = lhs.tpe.seal.asInstanceOf[quoted.Type[S]]
144
- // val left = parse[S](lhs.seal.asInstanceOf[Expr[S]])
145
- // val anchor = getAnchorForSelect(refl)(sel.asInstanceOf[Select])
146
-
147
- // val rights = args.map { arg =>
148
- // type V
149
- // implicit val tpV: quoted.Type[V] = arg.tpe.seal.asInstanceOf[quoted.Type[V]]
150
- // parse[V](arg.seal.asInstanceOf[Expr[V]])
151
- // }
152
-
153
- // let(left) { (l: Expr[DiagrammedExpr[_]]) =>
154
- // lets(rights) { (rs: List[Expr[DiagrammedExpr[_]]]) =>
155
- // val res = apply('{($l).value}, op, targs, rs)
156
- // '{ DiagrammedExpr.applyExpr($l, ${rs.toExprOfList}, $res, $anchor) }
157
- // }
158
- // }
138
+ case Apply (TypeApply (sel @ Select (lhs, op), targs), args) =>
139
+ type S
140
+ implicit val tpS : quoted.Type [S ] = lhs.tpe.seal.asInstanceOf [quoted.Type [S ]]
141
+ val left = parse[S ](lhs.seal.asInstanceOf [Expr [S ]]).unseal
142
+ val anchor = getAnchorForSelect(refl)(sel.asInstanceOf [Select ])
143
+
144
+ val rights = args.map { arg =>
145
+ type V
146
+ implicit val tpV : quoted.Type [V ] = arg.tpe.seal.asInstanceOf [quoted.Type [V ]]
147
+ parse[V ](arg.seal.asInstanceOf [Expr [V ]]).unseal
148
+ }
149
+
150
+ let(left) { l =>
151
+ lets(rights) { rs =>
152
+ val left = l.seal.cast[DiagrammedExpr [_]]
153
+ val rights = rs.map(_.seal.cast[DiagrammedExpr [_]])
154
+ val res = Select .overloaded(' {$left.value}.unseal, op, targs.map(_.tpe), rs).seal.cast[T ]
155
+ ' { DiagrammedExpr .applyExpr($left, $ {rights.toExprOfList}, $res, $anchor) }.unseal
156
+ }
157
+ }.seal.cast[DiagrammedExpr [T ]]
159
158
160
159
case _ =>
161
160
default
0 commit comments