I am trying to replicate de example here:
https://dotty.epfl.ch/docs/reference/metaprogramming/macros.html#lifting-expressions
I have the following code that will not compile:
enum Exp {
case Num(n: Int)
case Var(x: String)
case Add(e1: Exp, e2: Exp)
case Sub(e: Exp, in: Exp)
case Let(x: String, e: Exp, in: Exp)
}
object Exp {
private def compileImpl(e: Exp, env: Map[String, Expr[Int]])(using QuoteContext): Expr[Int] = e match {
case Num(n) =>
Expr(n)
case Add(e1, e2) =>
'{ ${ compileImpl(e1, env) } + ${ compileImpl(e2, env) } }
case Var(x) =>
env(x)
case Let(x, e, body) =>
'{ val y = ${ compileImpl(e, env) }; ${ compileImpl(body, env + (x -> 'y)) } }
}
inline def compile(inline expr: Exp, env: Map[String, Expr[Int]]): Unit = {
${compileImpl(expr, Map[String, Expr[Int]]())}
}
}
And I get the errors:
[error] -- Error: /home/hmf/IdeaProjects/snol/tutorial/src/dotty/Macros.scala:69:48 ----
[error] 69 | ${compileImpl(expr, Map[String, Expr[Int]]())}
[error] | ^^^^^^^^^^^^^^^^^^^^^^^^
[error] | Malformed macro parameter
[error] |
[error] | Parameters may only be:
[error] | * Quoted parameters or fields
[error] | * Literal values of primitive types
[error] -- Error: /home/hmf/IdeaProjects/snol/tutorial/src/dotty/Macros.scala:69:20 ----
[error] 69 | ${compileImpl(expr, Map[String, Expr[Int]]())}
[error] | ^^^^
[error] | access to value expr from wrong staging level:
[error] | - the definition is at level 0,
[error] | - but the access is at level -1.
[error] two errors found
Those errors make sense, so how should this be implemented?
TIA