Are there any languages which allow you to get access to the AST during compile time, to use some part of the AST to generate code, or to possibly rewrite the code/AST to optimize it in a heuristic way?
I just found out about Rust's derive
(procedural macros), which gives you the AST that you have to implement a handler for, like in this example from the diesel crate.
pub fn derive_insertable(input: TokenStream) -> TokenStream {
insertable::derive(parse_macro_input!(input))
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}
I also feel like I remember reading somewhere in the Julia language documentation that you could get the AST at compile time and rewrite it to get further optimizations, but maybe I misread and I can't find the link.
I am in particular wondering what could be done if you could get access to the AST at compile time, and what that might look like. Are there any other examples of languages doing this? If so, what do they allow you to do (and what is a quick example)?
For the (imperative/object oriented) language I'm working on, I am imagining potentially taking the definition of a recursive function and rewriting that using a flat iterative/stack based approach for optimizations. But not necessarily build this into the main compiler; somehow make it pluggable so you could write your own "function optimizer" and swap it out with a new one, or something like that. I am imagining like how ESLint for JavaScript allows you to rewrite the AST, maybe there is something like that but for compilers. And how would that look, what an API example might look like.
But main thing I'm wondering about this in summary:
- What are the major examples of languages giving you access to the AST at compile time?
- What might be an API example of how you would use it (and what might be a use case)?
I would also be curious as to your perspective on if this would be valuable or a problematic complicated mess of a feature, but perhaps you can leave a comment on that if you've thought about it before or tried this before without success, or otherwise just know that it would be impractical.
syn
. This is different from the compiler passing its internal AST structure. $\endgroup$