I've done more type annotating, which.... helped?

There's a confusing structure which this project has. For some reason the "generic" parser imports from the imp specific structures, which it should not. It also needs things imported in specific orders now, which super confuses me.
More typing!
Package it!
The imp parser works! Neato.
Define evaluators on our AST tree elements
Splitting AST into logically named modules
Add the imp parse to take advantage of our parser.

Our parser kind of lost its generic qualities. The keywords and loop structures for IMP are in the plain parser, now.
Implement parser logic using our AST elements

They make a bit more sense, but they seem very confusing to use, much less implement. I still don't understand them.
Some AST elements

Again, what these specifically are or mean is not entirely clear to me yet.
attrs lib is a *thiiiing* and I love it.
Implementing basic combinators for parsing

I'm actually rather... unclear about the function of much of these.
I wonder if there was a way I could have made them more clear, or if this is a good way I don't understand yet.
Defining a lexer is simple enough

Ordering token patterns by specificity is super important
I've traded out constants for Enums, since python did not support them when this guide was posted.
A generic lexer!