Skip to content

Commit 577781c

Browse files
Merge pull request #3845 from dotty-staging/quote-lib
Quote lib
2 parents bfb65c6 + 6ff3921 commit 577781c

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
quote lib ok
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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

Comments
 (0)