Split up typechecker

Resolves #650, or at least makes a start on it.