Make a current-state PRNG thing.
Remove old typechecking proof-of-concept
Minor notes and cleanup.

Did a read-through from start to end and you know, it's not terrible.
Attempt to make generic inference work.

It's uh...  there's some weird fucking shit going on in there.  I've updated
what I have in the issue: https://todo.sr.ht/~icefox/garnetc/21
thiiiiiiink this gets rid of @ sigils for type parameters.

Need to go through more tests and clean them up tho.
Oops we allow direct recursive types.

https://todo.sr.ht/~icefox/garnetc/29
Type double-checker is now complete.

Fixed the bug that are actual bugs, idk how to fix one of them
so it's in https://todo.sr.ht/~icefox/garnetc/28
Oops I found lots of cases where the type checker fucks up~

I mean, I guess they were there anyway.
Now that I've done this flattened-HIR thing I don't need to worry about it.
Experiment with flattening our tree-based HIR into a vec of nodes.

It's certainly possible, but doing it is at least as much of a pain in the
ass as writing it was in the first place.  And I doubt the benefit
is that high, since we tend to allocate all our IR nodes at once
anyway so locality is probably decentish.  I'm sure the benefit is
PRESENT, but doesn't matter right now.  I just wanted to see what
the API would look like and, as expected, there are some annoying
wrinkles.
Revert commit 24722db3fc92

Rc'ing types instead of cloning does improve performance of passes and other
tree-manip-stuff by roughly 10%, but is inconvenient enough that it's prolly
not worth it.  Interning them would work better and also be easier since it'd
make all our types Copy.

But that attempt also had a bit of nice code cleanup in it, so I've
tried to preserve it.
turns out cloning the parser is expensive
play around with benchmarking and Rc in types vs. Box.

The results are... not worth it, to say the least.  Rc'ing
vs Box'ing in types does indeed save a bit of time, about 10%,
in various passes since we probably avoid a lot of copying of types.
However, what takes the most time apart from executing rustc of course
is actually the parser!

Given my propensity for saying "parsing isn't slow, don't worry about
it" to new PL devs, all I can say is... lol.  lmao.

But it's still 60k lines a second or whatever, so it's fine even if
I expected it to be like 3x that.  But attempting to profile garnetfmt
(while commenting out anything it does besides parsing) results in
`perf` saying that 93% of the time is spent in
`__memmove_avx_unaligned_erms`.  And if that isn't a sign from on high
to shrug and get on with life then idk what is.  XD

If we wanna optimize types then really they should be interned and/or
flattened into a vec instead of a tree, I suspect.  Then the AST and
HIR should be flattened into a vec as well, though honestly they tend
to be allocated all together so I bet data locality is pretty
ok anyway.  But none of that matters compared to the parser!

Well this was a weird Learning Experience, I guess.
Minor cleanup and a failing test I should make succeed.
set default run binary to garnetc
Make unsigned integers work.

Our integer values are all stored as i128, so our own i128 type
has been sacrificed on the altar of simplicity.  But I'm willing
to let that be the case for now.
Allow you to elide trailing {} rettype in function signatures.

Took a little more finesse than expected but not too bad.
Add while loops.
Add a basic PRNG to the unit tests.

Exposes lots of flaws tbqh, and we need unsigned numbers to make it
really work properly.  But it does work!
Add borrow checking test case
Next