I'm not really clear about the semantics used to talk about clojurescript's compiler.
So in this document, i'm gonna call the analyzer, every phase before emit, so that include parse / macroexpansion / analyze.
If the compiler is to be made backend-agnostic, it will still need to be provided some informations about the backend.
Most notably, for the moment, the analyzer needs to know about the namespaces which contains all the cljs.core macros, to be able to expand them, see Decoupling cljs.core
So we need a way to provide this backend specific information to the analyzer. There are several options to do so.
I'm gonna sort them on how much effort is gonna be required to implement them.
This solution is easy and might work. It has several drawbacks
2. is almost more problematic than 1., because the js backend uses some variables (most notably the namespaces atom) that are backend-specific, and needs to be initialized.
If this solution is used, we'd need to wrap those access through getters that would perform needed initializations. For the moment, this only means providing a function that provides a fresh environment.
This is an improvement on the previous solution. The idea is to regroup every piece that the analyzer needs onto a protocol, and to only bind that dynamically.
It mitigates the first drawback of the first solution, but still has the same problem regarding analyzer initialization
This is probably the best solution.
Optionally, it also makes the use of several analyzers for different backends in the same program easier, by making the stateful information local to each analyzer instance.
I'm looking for feedback about how to implement this, my solution for the moment is to gradually transform the analyzer to be parametric, so using the first solution, and then maybe implement solution 3, by solidifying those changes into a protocol.
Comments and alternatives solutions much appreciated !