Nanopass Compiler?

I realized that in order to really leverage my contract stuff I'm going to need a multi-pass compiler. For example, I want to have the compiler let you know that there's a problem when you feed the output of a function that returns an Integer to the input of a function that takes a String. You can't do that until you've ingested all the functions in your app, and processed their contract definitions. So, it's really an "ok, your syntax is fine, let's see if your usage is too" phase of compilation.

A multipass compiler is thus required. The Nanopass Compiler framework is the king of that hill. If you aren't familiar with it I recommend you watch this talk from 2013. It's about 40 minutes and moves fast but don't worry if some of the stuff goes over your head. It's the basic gist of how things work that's important, not the actual implementation details.

I'm having a really hard time finding a good guide for how to do much of anything with transpilers though. I figured that Racket has been a playground for language prototyping and design for years now, so surely there must be something. There really wasn't; at least, not that I could find. So, I asked on the Racket subreddit. I got some useful responses about Nanopass compilers, but nothing really about tutorials on transpiler creation.

Create Your Own Freaking Awesome Programming Language is still the best i've found but I don't believe it covers multipass compilation. It's not that I can't figure out how to do it from the resources available. The problem is that I don't know what the right way to approach the problem is. What's the right way to structure my passes? How do i decide how much to tackle in each pass or what order to do them in? The how isn't that hard. It's just learning syntax. It's the approach that's unclear.

I don't know how to think about compiler design, especially multipass ones.

So, last night was a rabbit hole of education. I watched the video linked above. I learned that nanopass compilation isn't just a general technique but a general technique coupled with a specific framework that has only been implemented in a couple languages (not Janet).

As an aside, I'm getting really sick of how much emacs hates inserting tabs, so i went on a little side-track as to what it'd take to define a new language in emacs and have tab indentation be the default there. The long and short of it is that indentation is complicated in emacs, and written by monsters who not only think that spaces are better because they "keep everything the same" when different people have different tab widths, but also think that it's fine to mix tabs and spaces for indentation so that it minimizes the number of characters used (why?!?!). If you care at all about accessibility for low vision users you will stop indenting with spaces.

Anyway. Lots of time. Little actual progress. I then spent far to much time awake in the middle of the night not-quite-dreaming about writing compiler code based on the little I'd learned.