Self-hosting: major milestone on the path has been reached!
I exulted over this rather vocally on Twitter, but in case you don't follow me (@ApochPiQ), I'll repeat it here:
At 12:15AM this morning, Epoch's compiler successfully generated itself, when provided with a decorated AST from the C++ compiler front-end.
What this means is that I have a fully working layer that translates the decorated Epoch AST into machine code (via transitional forms and LLVM, but that's just technical detail). The compiler was loaded as a plugin to the C++ compiler, compiled once using C++, and then the compiled version was executed on the compiler's source code.
The output is not bit-identical to the generated results of the C++ compiler, but it is functionally identical, which is more important.
The byte-level differences originate from things being reordered a bit during the handoff from the C++ side to the Epoch side (I blame unordered_map) and, curiously enough, from the C++ compiler emitting some vestigial bytecode that does nothing useful.
So the Epoch compiler is already better than the C++ one, in at least one trivial and irrelevant detail :-D
I've already started on porting the type system logic to the Epoch core compiler. After that milestone is reached, more compilation will be done in Epoch than in C++. Right now all the type system analyses and inference is being done by C++ code, but that is quickly changing.
One of the things that worried me the most was implementing a viable version of Shunting Yard for operator precedence reordering. Turns out that only took about an hour to port over and perfect, which is pretty cool.
The next big worrisome item is the process of overload resolution and expression type deduction, which are intimately tied together due to operators having overloads at the language level. (I still haven't decided if I want to expose operator overloading to the end programmer.)
That's a huge chunk of the C++ compiler by itself, and moving all the intricate details to Epoch will be tedious and finicky to say the least. I'm hesitant to make predictions on a timeframe because I have a feeling I'll need to step away from it more than once for extended periods to regain my sanity.
That said, with a couple of hacks and shortcuts in place, I did get two of the most trivial compiler tests to pass this afternoon using the new type system implementation (such as it is currently). So my end-of-year target for finishing all of self-hosting seems reachable.
As a minor recap, to get to full self-hosting, I need to port the type system and then also rewrite the entire parser. Redoing the parser is probably not going to be terribly hard, but it may take some time for the same reasons as above (i.e. I may need a lot of breaks). What'll be the most interesting aspect of it is getting rid of having any kind of codified grammar for the language; the implementation will be 100% ad hoc hand-rolled recursive descent, at least to start out. Writing an Epoch-compatible LR parser generator does not appeal to me right now.
So those are the happenings... I'm also racking up a huge mental checklist of things I want to improve on for the language as a whole, so if nothing else, this is a tremendous opportunity to dogfood my own work and figure out how to make it appealing as a larger ecosystem.