Do you run an optimization pass on the AST between parsing and evaluation?

For an interpreter / AST executor, I think a big win would be efficient parsing in the first place, in particular using a precedence parser for expressions vs recursive descent, which would avoid the need to optimize the AST to remove the 1:1 "unit productions" in the grammar.

I run a “resolve” pass.

That’s where for example getter inference happens.