You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Exception occurred while executing macro expansion.
java.lang.StackOverflowError
The output is:
b(a) : 3 = Some(3)
Recursing on Some(3)
b(a) : 3.-(1) = Some(2)
Recursing on Some(2)
b(a) : 3.-(1).-(1) = Some(1)
Recursing on Some(1)
b(a) : 3.-(1).-(1).-(1) = Some(0)
Recursing on Some(0)
b(a) : 3.-(1).-(1).-(1).-(1) = Some(-1)
Recursing on Some(-1)
b(a) : 3.-(1).-(1).-(1).-(1).-(1) = Some(-2)
Recursing on Some(-2)
b(a) : 3.-(1).-(1).-(1).-(1).-(1).-(1) = Some(-3)
Recursing on Some(-3)
Expectation
I expect the expression from:
valnext_b:Expr[Int] ='{$expr -1}
to match on the '{1} quote case on the next spliced call. Note that in the tests, these do match on 0 and 1 respectively when the values come from the original source code. I have the following code that works:
transparentinlinedefpower2(a: Int, b:Int):Any=${ power2Impl('a,'b) }
defpower2Impl(a: Expr[Int], b: Expr[Int])(usingq1: Quotes):Expr[Int] =importquotes.reflect.*// Ifs don't work
b matchcase'{0} =>'{1}
case'{1} => a
case'{ $expr: Int } =>
println(s"b(a) : ${b.show} = ${b.value}")
valnext_b:Expr[Int] ='{$expr -1}
next_b.value matchcaseNone=>
report.errorAndAbort("power2Impl: Unexpected value")
caseSome(0) =>// a^1 = a * a⁰ = a
a
caseSome(1) =>// a^2 = a * a¹'{$a*$a}
caseSome(x) =>// a^b = a * a^x
println(s"Recursing on Some($x)")
valnext= power2Impl(a, next_b)
println(s"next = ${next.value}")
'{$a * $next}
but extracting the value and repeating the same matches seems redundant and incorrect.
The text was updated successfully, but these errors were encountered:
Using quote pattern matching is not meant to be used to recover values, rather matches the structure of the expression. A '{1 + 2} will not match '{3} because they do not have the same structure. To match on the value one needs to match on the runtime value of the evaluated code. This is where .value, Expr.apply and Expr.unapply are useful.
While the other comment shows how to do this correctly and optimally, we can also use the shorter (slower) version that uses Expr.apply and Expr.unapply.
defpower3Impl(a: Expr[Int], b: Expr[Int])(usingq1: Quotes):Expr[Int] =
b matchcaseExpr(0) =>'{1} // or Expr(1)caseExpr(1) => a
caseExpr(n) =>
println(s"b(a) : ${b.show} = ${n}")
println(s"Recursing on ${n}")
valnext_b:Expr[Int] =Expr(n -1)
valnext= power3Impl(a, next_b)
println(s"next = ${next.value}")
'{$a * $next}
case _ =>
quotes.reflect.report.errorAndAbort("b must be a constant")
Compiler version
Scala version 3.2.1
Minimized code
I have the following macro to calculate a power of an integer (both base and exponent are integers).
and I test it in another file with:
Output
The line:
produces the following error:
The output is:
Expectation
I expect the expression from:
to match on the
'{1}
quote case on the next spliced call. Note that in the tests, these do match on 0 and 1 respectively when the values come from the original source code. I have the following code that works:but extracting the value and repeating the same matches seems redundant and incorrect.
The text was updated successfully, but these errors were encountered: