Refactor UnaryOp and BinaryOp with codes for operations.

This has various benefits:
* The IR is smaller (store a byte instead of a string + type)
* The dispatch codes are faster because they are switches
* It is just cleaner
Typecheck more accurately the body of MethodDefs and Functions.

When a MethodDef or Function returns NoType, its body can be
a statement (possibly NoType). However, if it returns anything
else, its body must typecheck as Nothing.

For this to work, we had to make sure that the infinite while
loops used to translate tail recursive methods can indeed
typecheck as Nothing.
MethodDef and Function have an implicit Return unless NoType.

This makes them more Scala-ish, in the sense that a MethodDef
or a Function implicitly returns its body. This simplifies a
few things, but is mostly more elegant, and it should enable
more elegance in the inliner as well.
Merge pull request #664 from sjrd/ir-tweaks

IR tweaks