As someone who writes a lot of toy languages, I made this scaffolding for a LLVM-based compiler: https://github.com/finiteloop/compiler It uses Bison and Flex for parsing and lexing unlike this post, but may be a useful starting point for those building their own toy languages.
Doesn’t the LLVM API go through breaking changes fairly often? How do you track all that and keep your sanity?
I think LLVM is an excellent demonstration of how to design and implement big systems well in C++, and as a part of that, they also do breaking changes pretty well.