So, at the core of Tangent is the code that takes all of the phrases the user has defined and figures out how to grok that statement. In previous iterations of the language, that code has been hairy, nasty, nested cruft that has made it difficult to add features and debug things when they go south.
In this iteration, things were better. I was explicit in defining the various things that the language could define, and good about keeping things simple. Unfortunately, this led to a bit of duplication in this core code because the simplest way to deal with these definitions was just to have different handlers that did almost the same thing.
Not great. So I spent some time making some better abstractions and cleaning up that core code. In the end, it works akin to a shift reduce parser - the phrases define what pattern should be matched and depending on what is being declared (a parameter, a type, a function, etc.) it creates a different expression type in the abstract syntax tree. The new design better shares the matching and use of phrases, while leaving the "what happens when this is matched" variable. That allows better testing too, which is nice.
That should let me more easily move into local variables or delegates depending on what I feel like doing.