1
+
2
+ import scala .quoted ._
3
+ import dotty .tools .dotc .quoted .Runners ._
4
+
5
+ import liftable .Units ._
6
+ import liftable .Lets ._
7
+ import liftable .Loops ._
8
+ import liftable .Tuples ._
9
+ import liftable .Lists ._
10
+ import liftable .Exprs ._
11
+
12
+ object Test {
13
+ def main (args : Array [String ]): Unit = {
14
+
15
+ val liftedUnit : Expr [Unit ] = ()
16
+
17
+ letVal('(1))(a => ' { ~ a + 1 }).show
18
+ letLazyVal('(1))(a => ' { ~ a + 1 }).show
19
+ letDef('(1))(a => ' { ~ a + 1 }).show
20
+
21
+ liftedWhile('(true))( ' { println(1 ) }).show
22
+ liftedDoWhile(' { println(1 ) })('(true)).show
23
+
24
+ val t1 : Expr [Tuple1 [Int ]] = Tuple1 (4 )
25
+ val t2 : Expr [(Int , Int )] = (2 , 3 )
26
+ val t3 : Expr [(Int , Int , Int )] = (2 , 3 , 4 )
27
+ val t4 : Expr [(Int , Int , Int , Int )] = (2 , 3 , 4 , 5 )
28
+
29
+ val list : List [Int ] = List (1 , 2 , 3 )
30
+ val liftedList : Expr [List [Int ]] = list
31
+
32
+ liftedList.foldLeft[Int ](0 )(' { (acc : Int , x : Int ) => acc + x }).show
33
+ liftedList.foreach(' { (x : Int ) => println(x) }).show
34
+
35
+ list.unrolledFoldLeft[Int ](0 )(' { (acc : Int , x : Int ) => acc + x }).show
36
+ list.unrolledForeach(' { (x : Int ) => println(x) }).show
37
+
38
+ println(" quote lib ok" )
39
+ }
40
+ }
41
+
42
+
43
+ package liftable {
44
+ import scala .quoted .Liftable
45
+ import scala .quoted .Liftable ._
46
+ import scala .reflect .ClassTag
47
+
48
+ object Exprs {
49
+ implicit class LiftExprOps [T ](x : T ) extends AnyVal {
50
+ def toExpr (implicit liftable : Liftable [T ]): Expr [T ] =
51
+ liftable.toExpr(x)
52
+ }
53
+ }
54
+
55
+ object Units {
56
+ implicit def UnitIsLiftable : Liftable [Unit ] = _=> ' { () }
57
+ }
58
+
59
+ object Lets {
60
+ def letVal [T , U ](expr : Expr [T ])(body : Expr [T ] => Expr [U ])(implicit t : Type [T ]): Expr [U ] =
61
+ ' { val letVal : ~ t = ~ expr; ~ body('(letVal)) }
62
+ def letLazyVal [T , U ](expr : Expr [T ])(body : Expr [T ] => Expr [U ])(implicit t : Type [T ]): Expr [U ] =
63
+ ' { lazy val letLazyVal : ~ t = ~ expr; ~ body('(letLazyVal)) }
64
+ def letDef [T , U ](expr : Expr [T ])(body : Expr [T ] => Expr [U ])(implicit t : Type [T ]): Expr [U ] =
65
+ ' { def letDef : ~ t = ~ expr; ~ body('(letDef)) }
66
+ }
67
+
68
+ object Loops {
69
+ def liftedWhile (cond : Expr [Boolean ])(body : Expr [Unit ]): Expr [Unit ] = ' { while (~ cond) ~ body }
70
+ def liftedDoWhile (body : Expr [Unit ])(cond : Expr [Boolean ]): Expr [Unit ] = ' { do ~ body while (~ cond) }
71
+ }
72
+
73
+ object Tuples {
74
+
75
+ implicit def Tuple1IsLiftable [T1 : Liftable ](implicit t1 : Type [T1 ]): Liftable [Tuple1 [T1 ]] = {
76
+ case Tuple1 (x1 : T1 ) => ' { Tuple1 [~ t1](~ x1.toExpr) }
77
+ }
78
+
79
+ implicit def Tuple2IsLiftable [T1 : Liftable , T2 : Liftable ](implicit t1 : Type [T1 ], t2 : Type [T2 ]): Liftable [(T1 , T2 )] = {
80
+ x => ' { Tuple2 [~ t1, ~ t2](~ x._1.toExpr, ~ x._2.toExpr) }
81
+ }
82
+
83
+ implicit def Tuple3IsLiftable [T1 : Liftable , T2 : Liftable , T3 : Liftable ](implicit t1 : Type [T1 ], t2 : Type [T2 ], t3 : Type [T3 ]): Liftable [(T1 , T2 , T3 )] = {
84
+ x => ' { Tuple3 [~ t1, ~ t2, ~ t3](~ x._1.toExpr, ~ x._2.toExpr, ~ x._3.toExpr) }
85
+ }
86
+
87
+ implicit def Tuple4IsLiftable [T1 : Liftable , T2 : Liftable , T3 : Liftable , T4 : Liftable ](implicit t1 : Type [T1 ], t2 : Type [T2 ], t3 : Type [T3 ], t4 : Type [T4 ]): Liftable [(T1 , T2 , T3 , T4 )] = {
88
+ x => ' { Tuple4 [~ t1, ~ t2, ~ t3, ~ t4](~ x._1.toExpr, ~ x._2.toExpr, ~ x._3.toExpr, ~ x._4.toExpr) }
89
+ }
90
+
91
+ // TODO more tuples
92
+
93
+ }
94
+
95
+
96
+ object Lists {
97
+ implicit def ListIsLiftable [T : Liftable ](implicit t : Type [T ]): Liftable [List [T ]] = {
98
+ case x :: xs => ' { (~ xs.toExpr).:: [~ t](~ x.toExpr) }
99
+ case Nil => ' { Nil : List [~ t] }
100
+ }
101
+
102
+ implicit class LiftedOps [T : Liftable ](list : Expr [List [T ]])(implicit t : Type [T ]) {
103
+ def foldLeft [U ](acc : Expr [U ])(f : Expr [(U , T ) => U ])(implicit u : Type [U ]): Expr [U ] =
104
+ ' { (~ list).foldLeft[~ u](~ acc)(~ f) }
105
+ def foreach (f : Expr [T => Unit ]): Expr [Unit ] =
106
+ ' { (~ list).foreach(~ f) }
107
+ }
108
+
109
+ implicit class UnrolledOps [T : Liftable ](list : List [T ])(implicit t : Type [T ]) {
110
+ def unrolledFoldLeft [U ](acc : Expr [U ])(f : Expr [(U , T ) => U ])(implicit u : Type [U ]): Expr [U ] = list match {
111
+ case x :: xs => xs.unrolledFoldLeft(' { (~ f).apply(~ acc, ~ x.toExpr) })(f)
112
+ case Nil => acc
113
+ }
114
+ def unrolledForeach (f : Expr [T => Unit ]): Expr [Unit ] = list match {
115
+ case x :: xs => ' { (~ f).apply(~ x.toExpr); ~ xs.unrolledForeach(f) }
116
+ case Nil => ()
117
+ }
118
+ }
119
+
120
+ object Arrays {
121
+ // FIXME missing hole for ~t
122
+ // implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], ct: Expr[ClassTag[T]]): Liftable[Array[T]] = (arr: Array[T]) => '{
123
+ // new Array[~t](~(arr.length: Expr[Int]))(~ct)
124
+ // }
125
+
126
+ }
127
+
128
+ }
129
+ }
0 commit comments