Improve codegen for GLSL

This PR improves GLSL code generation in the following ways:

- proper handling of vector arguments for expressions containing math functions and several operators that require special handling (lerp, integer division)
- correct rounding for lerp to match CPU implementation
- correct truncation when doing float->uint8 or float->uint16 casts

This PR also adds unit tests for the code generator and more extensive accuracy tests for GLSL math functions.

(Note: one unit test depends on the changes in #497, so that PR needs to be merged first.)
What happens if the weight type is uint(32) or greater? imax() won't work. Or is that already ruled out elsewhere?