Use do-while instead of tail recursion

Since javascript doesn't do tail call elimination a recursive solution
still builds up a big pile of stack frames (one per character) each
containing a string (ch) that doesn't get garbage collected until the
whole thing has returned. It's trivial to replace tail recursion with a
do-while loop which doesn't suffer from the negative effects.