Make QueueOptimizer easier to read.

QueueOptimizer is really hard to read. Enough so that it's blocking my
efforts to streamline the representation used for operator lists.

This patch improves its readability in the following ways.

- More descriptive variable names make the sequence checking much clearer,
  as do additional comments.

- The addState() functions now return the index of the first op past the
  sequence, instead of setting context.currentOperation to the last op of
  the sequence.

- The loop in optimize() is clearer.

- The array modification in the fourth addState() function is much clearer
  -- we're just removing trios of ops.

- All four |addState| functions are now more consistent with each other.

I used some debug printfs to find documents where these optimizations are
used and then checked that the number of optimized ops was the same before
and after my changes.
Travis complains about this:
```
src/core/evaluator.js: line 2577, col 11, It's not necessary to initialize 'state' to 'undefined'.
```