Skip to content

Commit e1afa10

Browse files
committed
Add regression tests
with prototype of places macro
1 parent 040d141 commit e1afa10

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

tests/run-macros/places-proto.check

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2
2+
List(3, 2, 4)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import scala.quoted.*
2+
3+
object Places:
4+
def withPlace[T: Type, R: Type](x: Expr[T])(body: Quotes ?=> Place[T] => Expr[R])(using Quotes): Expr[R] = {
5+
x match
6+
case '{ ($arr: Array[T]).apply($index) } => // TODO use more general version using reflection (apply/update methods)
7+
'{
8+
val idx = $index
9+
${
10+
body(
11+
new Place[T]:
12+
def set(x: Expr[T]): Expr[Unit] = '{ $arr(idx) = $x }
13+
def get: Expr[T] = '{ $arr(idx) }
14+
)
15+
}
16+
}
17+
case '{ $x: T } =>
18+
import quotes.reflect.*
19+
x.asTerm match
20+
case ident: Ident if ident.symbol.flags.is(Flags.Mutable) =>
21+
body(
22+
new Place[T]:
23+
def set(x: Expr[T]): Expr[Unit] = Assign(ident, x.asTerm).asExprOf[Unit]
24+
def get: Expr[T] = x
25+
)
26+
case Apply(Select(place, "apply"), List(idx)) => // TODO check that place has an update method
27+
'{???} // TODO
28+
case tree =>
29+
throw new MatchError(tree.show(using Printer.TreeStructure))
30+
}
31+
32+
trait Place[T]:
33+
def set(x: Expr[T]): Expr[Unit]
34+
def get: Expr[T]
35+
36+
37+
inline def increment(inline x: Int): Unit = ${ incrementExpr('x) } // TODO generalize to Numeric types
38+
39+
private def incrementExpr(x: Expr[Int])(using Quotes): Expr[Unit] =
40+
Places.withPlace(x) { place => place.set('{ ${place.get} + 1 }) }
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
@main def Test: Unit =
3+
var x = 1
4+
increment(x)
5+
println(x)
6+
7+
val arr = Array(1, 2, 3)
8+
increment(arr(0))
9+
increment(arr(0))
10+
increment(arr(2))
11+
println(arr.toList)

0 commit comments

Comments
 (0)