Навскидку.

Цикл имеет смысл покомандной обработки. Т.е. взять команду - что-то сделать - если не стоп, то будет следующая команда...
В этом смысле то, что команды лежат по две в одном слове, является деталью, не относящейся к семантике цикла. И я бы скрыл это под какой-то процедурой типа GetLexem в сканерах, которая каждый нечётный вызов считывает новое слово, а каждый чётный - только берёт его вторую часть.

И будет цикл такого вида (схематично, я, конечно, каких-то тонкостей могу и не учитывать):

## Код:
```
error = 0;
GetCommand;
WHILE (cmd # stop) & (error = 0) DO
  Execute;
  GetCommand
END
```


Неформальный инвариант: (cmd - очередная команда, подлежащая обработке OR cmd = stop) & (error - результат последнего Execute)

Но вообще-то тут компоненты условия зависят от разных действий, и свести в такой простой WHILE можно только потому, что действия независимы. Иначе потребовалось бы ставить IF на GetCommand, или действительно удобнее LOOP-EXIT, про что Ткачёв и упоминал (когда перед каждым условием выхода надо какое-то действие по его вычислению сделать).