1
1
// Import Expr and some extension methods
2
2
import scala .quoted ._
3
+ import scala .quoted .staging ._
3
4
import scala .tasty ._
4
5
5
6
object Vectors {
6
7
7
8
// Needed to show quotes
8
- implicit val toolbox : scala.quoted. Toolbox = scala.quoted. Toolbox .make
9
+ given Toolbox = Toolbox .make(getClass.getClassLoader)
9
10
10
11
/** Compute the dot product of the vectors (represented as arrays)
11
12
* Returns (v1(0) * v2(0)) + (v1(1) * v2(1)) + ... + (v1(v1.length - 1) * v2(v2.length - 1))
12
13
* Or throws an exception if v1.length != v2.length
13
14
* Both arrays are assumed to be immutable.
14
15
*/
15
- inline def dot (v1 : => Array [Int ], v2 : => Array [Int ]): Int = ~ dotImpl('(v1) , ' (v2))( Tasty .macroContext)
16
+ inline def dot (v1 : => Array [Int ], v2 : => Array [Int ]): Int = $ { dotImpl(' {v1} , ' {v2})}
16
17
17
18
/** Generates code to compute the dot product.
18
19
* Will try to partially evaluate any statically available data.
19
20
*/
20
- def dotImpl (v1 : Expr [Array [Int ]], v2 : Expr [Array [Int ]])(reflect : Tasty ): Expr [Int ] = {
21
- import reflect . _
21
+ def dotImpl (v1 : Expr [Array [Int ]], v2 : Expr [Array [Int ]])(using qctx : QuoteContext ): Expr [Int ] = {
22
+ import qctx . tasty .{ _ }
22
23
23
24
object EmptyArray {
24
25
def unapply (arg : Tree ): Boolean = arg match {
25
- case Term . Apply (Term . Apply (Term . TypeApply (Term . Select (Term . Ident (" Array" ), " apply" , _), List (TypeTree . Synthetic ())), List (Term . Typed (Term . Repeated (Nil ), TypeTree . Synthetic ()))), _) => true
26
+ case Apply (Apply (TypeApply (Select (Ident (" Array" ), " apply" ), List (Inferred ())),List (Typed (Repeated (Nil , Inferred ()), Inferred ()))),_) => true
26
27
case _ => false
27
28
}
28
29
}
29
30
30
31
// Useful methods
31
32
// Use i.toExpr to lift an i:Int into an quoted.Expr[Int]
32
- // Use q.toTasty to transform a q:quoted.Expr[_] to a Tasty.Tree
33
+ // Use q.unseal to transform a q:quoted.Expr[_] to a Tasty.Tree
33
34
// Use tree.toExpr[Int] to transform a tree:Tasty.Tree to a quoted.Expr[Int]
34
35
// Use q.show to show the code of a q:quoted.Expr[_]
35
- // Use tree.show to show the extractors needed to pattern match a tree:Tasty.Tree
36
+ // Use tree.showExtractors to show the extractors needed to pattern match a tree:Tasty.Tree
36
37
37
- val generatedCode = (v1.toTasty .underlyingArgument, v2.toTasty .underlyingArgument) match {
38
- case (EmptyArray (), EmptyArray ()) => '(0)
38
+ val generatedCode = (v1.unseal .underlyingArgument, v2.unseal .underlyingArgument) match {
39
+ case (EmptyArray (), EmptyArray ()) => ' { 0 }
39
40
// TODO Exercise: optimize more cases
40
- // case (EmptyArray(), _) => '()
41
+ // case (EmptyArray(), _) => '{0}
41
42
// ...
42
43
case (tv1, tv2) =>
43
44
// Print the extractors of tv1 and tv2
@@ -61,10 +62,10 @@ object Vectors {
61
62
generatedCode
62
63
}
63
64
64
- /** Staged code that computes the the dot product with a while loop */
65
- def dynamicDot (v1 : Expr [Array [Int ]], v2 : Expr [Array [Int ]]): Expr [Int ] = ' {
66
- val vv1 = ~ v1
67
- val vv2 = ~ v2
65
+ /** Staged code that computes the dot product with a while loop */
66
+ def dynamicDot (v1 : Expr [Array [Int ]], v2 : Expr [Array [Int ]])( using qctx : QuoteContext ) : Expr [Int ] = ' {
67
+ val vv1 = $ v1
68
+ val vv2 = $ v2
68
69
val len = vv1.length
69
70
if (vv2.length != len)
70
71
throw new Exception (s " Vectors must have the same sizes ( $len, ${vv2.length}" )
0 commit comments