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