-
Notifications
You must be signed in to change notification settings - Fork 20
/
IfTransform.scala
75 lines (68 loc) · 2.29 KB
/
IfTransform.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package cps.macros.forest
import scala.quoted._
import cps._
import cps.macros._
object IfTransform:
/**
*'''
* '{ if ($cond) $ifTrue else $ifFalse }
*'''
**/
def run[F[_]:Type,T:Type,C<:CpsMonadContext[F]:Type](cpsCtx: TransformationContext[F,T,C],
cond: Expr[Boolean], ifTrue: Expr[T], ifFalse: Expr[T]
)(using Quotes): CpsExpr[F,T] =
import quotes.reflect._
import util._
import cpsCtx._
val cR = Async.nestTransform(cond, cpsCtx)
val tR = Async.nestTransform(ifTrue, cpsCtx)
val fR = Async.nestTransform(ifFalse, cpsCtx)
var isAsync = true
val cnBuild = {
if (!cR.isAsync) then
if (!tR.isAsync && !fR.isAsync) then
isAsync = false
if (cR.isChanged || tR.isChanged || fR.isChanged) then
CpsExpr.sync(monad,
'{ if (${cR.syncOrigin.get})
${tR.syncOrigin.get}
else
${fR.syncOrigin.get}
},
true
)
else
CpsExpr.sync(monad, patternCode, false)
else
CpsExpr.async[F,T](monad,
'{ if ($cond)
${tR.transformed}
else
${fR.transformed} })
else // (cR.isAsync)
def condAsyncExpr() = cR.transformed
if (!tR.isAsync && !fR.isAsync)
CpsExpr.async[F,T](monad,
'{ ${monad}.map(
${condAsyncExpr()}
)( c =>
if (c) {
${ifTrue}
} else {
${ifFalse}
}
)})
else
CpsExpr.async[F,T](monad,
'{ ${monad}.flatMap(
${condAsyncExpr()}
)( c =>
if (c) {
${tR.transformed}
} else {
${fR.transformed}
}
)
})
}
cnBuild