Best method for evaluating Expr/TypedExpr during Initialization Macro?

I’m looking to evaluate an expression generated at compile-time (specifically during an initialization macro call). Something like:

var e = macro {
  final a = "test";
  a;
};
eval(e); // test

While I could use the expression in a type definition and generate that using Context.defineModule, I am looking for a value I can use during the initialization macro. The Expr is pure enough it can be typed using Context.typeExpr, so I figured there’s more than enough data to execute it, yet I could not find any tools for this in the macro api?

ExprTools.getValue doesn’t work as I’m hoping to evaluate blocks with variable declarations, basic API access, etc. I also tried placing the Expr in a type definition, using Context.defineModule, then using Type.resolveClass to access it, but this only worked at runtime, returning null during initialization.

Maybe I could define it in a module, then wait for a later stage of compilation (onAfterTyping or onGenerate?). Thought it can’t be so far back I can no longer use Context.defineModule afterwards.

Perhaps this is just a no macro-in-macro restriction situation? I suppose I could make a quick and dirty interpreter that stores everything as Dynamic for eval runtime-type checking? Thoughts?

You can use Exprs.eval from tink_macro. You can also define new modules in onAfterTyping, but no later than that. If you can move things out of init macros, it’s usually a good way to stay out of trouble in the long run.

2 Likes

I cannot begin to describe how absolutely brilliant and perfect the tink_macro eval is. I really thought all hope was lost, but it’s exactly what I was looking for. You are an absolute legend for coming up with it. Thank you so much!!

1 Like