Comment by sklogic
10 years ago
> that don't use an AST at all but generate machine code directly during parsing
It is not any different. A "sufficiently smart" compiler must be capable of fusing the lowering passes straight into a parser. Parsing is not that different from the other kinds of passes.
> that becomes harder the more stages you introduce
My usual trick is to have a "unit test" simple AST which, when building in a certain mode, is fed into the compilation pipeline and displayed with all the annotations. It helps a lot to understand what exactly each pass is doing. In the next version of my DSL for building compilers (currently a work in progress) it will even be a part of an IDE.
> the more language dialects you need to manage to mentally separate when working on the stages
Ideally, one pass = one language. Nanopass handles it nicely.
I am using this approach for pretty much all kinds of languages, and never had any issues with too many IRs. In my book, the more distinct IRs, the better.
> A "sufficiently smart" compiler must be capable of fusing the lowering passes straight into a parser.
Given the state of compiler-generation tools (i.e. they're not even viable for generating parsers for production quality compilers), I have little hope of seeing a tool like that in the next couple of decades at least. Probably longer. At least in a form I'll be able to use for anything.
> Ideally, one pass = one language. Nanopass handles it nicely.
That was exactly what I see as a nightmare of a maintenance problem. Even with half a dozen or so variations at most, I find it annoying.