This seems to make things work. I'm worried I might have an ordering bug
where we might choose the wrong precedence if we write ambiguous code
somehow, but at least for now, let's commit this and move on. Hopefully
the nonassoc stuff is actually correct.
Instead of in the lexer. I think this simplifies things and gives the
parser more information which should hopefully make it easier to parse
without shift/reduce conflicts.
It's a normally named function for now, until we think of a common
package to move it into.
Hopefully this makes improving the lexer and parser easier for now. We
can consider bringing it back if needed.
There were a bunch of packages that weren't well documented. With the
recent split up of the lang package, I figured it would be more helpful
for new contributors who want to learn the structure of the project.
This is a giant refactor to split the giant lang package into many
subpackages. The most difficult piece was figuring out how to extract
the extra ast structs into their own package, because they needed to
call two functions which also needed to import the ast.
The solution was to separate out those functions into their own
packages, and to pass them into the ast at the root when they're needed,
and to let the relevant ast portions call a handle.
This isn't terribly ugly because we already had a giant data struct
woven through the ast.
The bad part is rebasing any WIP work on top of this.