Проще всего объяснить поведение <инструкции цикла>, написав на «метаМини» небольшой фрагмент, заменяющий эту инструкцию. Чтобы найти результат работы <инструкции цикла>, нужно применить к ней «определение», данное на рис. 27.1. Подчеркнем, что, согласно этому определению, <цель цикла>, <предел> и <шаг> перевычисляются при каждом повторении. Предикат «существует» позволяет метаМини узнать, присутствуют ли соответствующие необязательные части в конкретной <инструкции цикла>. Если употреблен закрывающий <идентификатор>, он должен совпадать с <обязательно присутствующей> <меткой>.
В данном определении <инструкции цикла> педагог вновь победил практика. Динамическое переопределение управляющих значений унаследовано из Алгола; большинство других языков отказалось от этого по соображениям эффективности. Однако, если вы сможете реализовать динамическое определение, полученных знаний с избытком хватит на построение более простых статических циклов. Шаговый и условный циклы соединены в одной инструкции, чтобы сделать Мини поменьше; в реальном языке их можно разделить. Соблюдайте осторожность при повторной обработке <цели цикла>; если цель — это формальный параметр или элемент массива, при каждом повторении за целью могут скрываться различные переменные.
<инструкция выбора>::=<простая инструкция выбора>
|<метка> <простая инструкция выбора>
<простая инструкция выбора> ::= <заголовок инструкции выбора> <тело инструкции выбора> <конец инструкции выбора>
<заголовок инструкции выбора> ::= SELECT <выражение> OF
<тело инструкции выбора>::=<список случаев>
|<список случаев> <прочие случаи>
<конец инструкции выбора> ::= END SELECT;
|END SELECT <идентификатор>;
<список случаев> ::= <случай>
|<список случаев> <случай>
<случай> ::= <заголовок случая> <тело случая>
<заголовок случая> ::= CASE <селектор>:
<селектор>::= <заголовок селектора>)
<заголовок селектора>::= <<выражение>
|<заголовок селектора>, <выражение>
<прочие случаи>::=<заголовок прочих случаев> <тело случая>
<заголовок прочих случаев> ::= OTHERWISE:
<тело случая> ::= <тело сегмента>
<Инструкция выбора> работает следующим образом.
Вычисляется <выражение> в <заголовке инструкции выбора>. Обрабатываются все <случаи>, от первого до последнего, в <списке случаев>. Для каждого <случая>, слева направо, одно за другим вычисляются <выражения> в <селекторе>. Как только <выражение> вычислено, его значение сравнивается со значением первоначального <выражения> из <заголовка инструкции выбора>. Если они равны, выполняется соответствующее <тело случая>; на этом <инструкция выбора> завершает свою работу, и управление передается на следующую < инструкцию>.
Если ни один из случаев не выбран и если имеются <прочие случаи>, выполняется <тело случая> и <инструкция выбора> завершает работу. Иначе <инструкция выбора> ни на что не влияет, если не считать побочных эффектов от вычисления выражений.
Типы всех выражений, используемых для выбора <случая>, должны быть одинаковы. Если в конце <инструкции выбора> употреблен <идентификатор>, он должен совпадать с <обязательно присутствующей> <меткой> <инструкции выбора>.
<инструкция возобновления>::=REPEAT <идентификатор>;
<инструкция выхода>::=REPENT <идентификатор>;
<Инструкция возобновления> вызывает возврат управления на начало объемлющего тела инструкции, помеченной <идентификатором>. Выполнение всех промежуточных объемлющих тел сегментов и инструкций, частями которых эти тела являются, завершается, как если бы произошел нормальный выход из них. Вся связанная с ними память разрушается. <Метка>, на которую выполняется переход, должна принадлежать той же процедуре, что и <инструкция возобновления>. Если не существует объемлющей инструкции с указанной меткой, <инструкция возобновления> рассматривается как семантически ошибочная. Семантика <инструкции выхода> аналогична, с той лишь разницей, что управление передается не на начало помеченной инструкции, а в точку, непосредственно следующую за помеченной объемлющей инструкцией. Заметим, что <инструкция возобновления> вызывает повторное выполнение инструкции, на начало которой передается управление.
<инструкция ввода>::= INPUT <список ввода>;
<список ввода> ::= <переменная>
|<список ввода>, переменная>
<инструкция вывода>::== OUTPUT <список вывода>;
<список вывода>::= <выражение>
|<список вывода> <выражение>