diff --git a/library/src-3.x/scala/quoted/Expr.scala b/library/src-3.x/scala/quoted/Expr.scala index 9d4b5046407f..c9d0271ed6cb 100644 --- a/library/src-3.x/scala/quoted/Expr.scala +++ b/library/src-3.x/scala/quoted/Expr.scala @@ -37,6 +37,15 @@ package quoted { tg.untupled(args => new FunctionAppliedTo[R](f, args.toArray.map(_.asInstanceOf[Expr[_]]))) } + /** Returns A expression containing a block with the given statements and ending with the expresion + * Given list of statements `s1 :: s2 :: ... :: Nil` and an expression `e` the resulting expression + * will be equivalent to `'{ $s1; $s2; ...; $e }`. + */ + def block[T](statements: List[Expr[_]], expr: Expr[T])(implicit refl: tasty.Reflection): Expr[T] = { + import refl._ + Block(statements.map(_.unseal), expr.unseal).seal.asInstanceOf[Expr[T]] + } + } } diff --git a/tests/run-macros/quoted-expr-block/quoted_1.scala b/tests/run-macros/quoted-expr-block/quoted_1.scala new file mode 100644 index 000000000000..06a6b4036043 --- /dev/null +++ b/tests/run-macros/quoted-expr-block/quoted_1.scala @@ -0,0 +1,10 @@ +import scala.quoted._ + +inline def replicate(inline times: Int, code: => Any) = ${replicateImpl(times, 'code)} + +private def replicateImpl(times: Int, code: Expr[Any]) given tasty.Reflection = { + @annotation.tailrec def loop(n: Int, accum: List[Expr[Any]]): List[Expr[Any]] = + if (n > 0) loop(n - 1, code :: accum) else accum + Expr.block(loop(times, Nil), '{}) + +} diff --git a/tests/run-macros/quoted-expr-block/quoted_2.scala b/tests/run-macros/quoted-expr-block/quoted_2.scala new file mode 100644 index 000000000000..459664fa21e9 --- /dev/null +++ b/tests/run-macros/quoted-expr-block/quoted_2.scala @@ -0,0 +1,8 @@ + +object Test { + def main(args: Array[String]): Unit = { + var a = 0 + replicate(500, a += 1) + assert(a == 500, a) + } +}