Handle or_else cmds, fix a bug in _run_fn.

The bug in _run_fn was that updates to mode were not happening correctly.
In particular, push_mode was previously executed with a temporary dict as the
global scope, so that a 'mode = modes[-1]' type of assignment would only affect
the temporary dict, and not the real global mode variable.