[r=Rocky]Check unary/binary const expressions

This is not my proudest moment. I've gone back and forth between using parts of the go.types library and doing things from scratch. The below mess is what it takes to evaluate binary and unary ops with untyped const operands.

The biggest problem I found with go.types was getting errors to match the format of what's generated by gc. I think clinging to the reference implementation will help give the project a bit of legitimacy if it were ever to see adoption. Consistent error messages help with that.

At this point I wouldn't bother going through reading all the changes. This pull is ridiculously huge.

Where I do want to get your advice though is testing. As you can see checkbinaryexpr_test.go is about 500 lines long. It is essentially a grid test for binary ops, so far for cost types

`(int, rune, float, complex) x (int, rune, float, complex, bool, string, nil)`

However maintaining this is becoming painful. I'm thinking about code gen'ing a test for each `lhs x op x rhs` case. This will become even more extreme for mixed typed untyped operations. The logic for computing these is quite simple, but there are a huge number of corner cases with truncations and overflows for different sizes. I would guess the generated file could be in the order of 10k lines long. What are your thoughts on that approach.

Code gen'ing error messages would also mean that if the errors from gc change, perhaps after a new version, then the changes could be reflected in the tests by just regenerating the test files.

I've been searching for projects that do something similar. The "fmt" package tests are quite involved but usually only loop through one dimension. I haven't found anything specifically that generates test code though.