Parallel assignment is now handled correctly

Parallel assignment statements now allocate intermediate registers as
needed to avoid overwriting sources before reading them. That is, whereas
the statement "x, y = y, x;" used to result in both x and y assuming the
value from y, that statement will now swap the values of x and y, as one
would expect.

Some minor refactoring was done, and some code generator features were
added in the process of developing this epic enhancement.

See also #54, which was necessary to keep the optimizer from breaking
code issued by the new parallel assignment logic.

Closes #51.