Программирование >>  Формирование пользовательского контейнера 

1 ... 140 141 142 [ 143 ] 144 145 146 ... 156


int count;

count = 99;

if(n > 0) {

int count; эта переменная count локальная для оператора if

count = 100 относится к переменной count в блоке if

return count; относится к внешней переменной count

В этом случае внешняя переменная count (объявленная в начальных строках

кода функции) помещается в стек local var stack первой. Далее в этот же

стек попадает переменная count, локальная для блока в операторе if. Таким

образом, когда выполняется следующая строка:

count = 100 относится к переменной count в блоке if

функция assign var() ищет переменную count и находит первой, как и

должна, ее копию, локально описанную в блоке if.

Последнее замечание: в функции interpO при каждом выходе из блока стек local var stack укорачивается до размера, который был у него до входа в блок. Этот технический прием позволяет эффективно удалять из стека все переменные, описанные внутри данного блока. Стек iocai var stack также укорачивается при каждом возврате из функции, удаляя все переменные и параметры, связанные с этой функцией.

Выполнение оператора if

Теперь, когда базовая структура интерпретатора Mini С++ описана, самое время познакомиться с реализацией управляющих операторов. Вообще, каждый раз, когда обнаружено ключевое слово, функция interpO вызывает функцию, обрабатывающую обнаруженный оператор. Имена всех функций, интерпретирующих различные управляющие операторы, начинаются с префикса ехес . Например, цикл for интерпретируется функцией exec for(), а оператор switch - функцией exec switch() и т. д.

Один из легчайших операторов для интерпретации - оператор if. Он обрабатывается функцией exec if о, приведенной далее.

Выполняет оператор if. void exec ifО



int cond;

eval eзф(cond); получает вьгражение оператора if.

if(cond) { если tnae, обрабатывает блок в составе IF Подтверждает начало блока. if(*token != {)

throw InterpExc(BRACE EXPECTED);

interpO ;

else {

В противном случае пропускает блок IF и обрабатывает ELSE, если он есть.

find eob(); находит начало следующей строки get token();

if(tok != ELSE) {

Возвращает лексему, если нет ELSE.

putbackO ;

return;

Подтверждает начало блока. get token(); if(*token != {)

throw InterpExc(BRACE EXPECTED); putbackO ;

interpO ;

Давайте рассмотрим внимательно действие этой функции. Сначала функция exec if о вызывает функцию eval exp() для вычисления значения условного выражения. Если оно равно true (ненулевое), вызывается функция interpO, которая выполняет код блока оператора if. Если условное выражение равно false, вызывается функция find eob(), которая



продвигает указатель программы в точку, расположенную сразу после блока if. Если есть ветка else, выполняется связанный с ней блок кода. В противном случае выполнение начинается со следующей строки кода. Если выполняется блок if и в программе есть блок else, должен быть способ обхода блока else. Это действие выполняется в функции interpO, когда встречается оператор else. В этом случае функция interpO просто вызывает функцию find eob() ДЛЯ обхода блока else. Помните, что блок else будет обрабатываться функцией interpO (в синтаксически корректной программе) только после того, как выполнен блок if.

Еще одно замечание: обратите внимание на то, что функция exec if о проверяет, что формирующий результат код ветвей if и else заключен в блоки. Как объяснялось, для упрощения интерпретатора все формирующие результат части управляющих операторов должны содержаться в блоках. Это ограничение делает код интерпретатора более простым.

Операторы break vi switch

Интерпретация оператора switch требует больше труда, чем обработка оператора if. Одна из причин кроется в более сложном синтаксисе. Другая состоит в том, что оператор switch зависит от оператора break. Следовательно, обработка оператора switch влечет за собой также интерпретацию оператора break. Далее обсуждаются оба.

Действительно, обработка оператора break довольно легка, потому что он выполняется одинаково: независимо от того, где используется, в операторе switch или в цикле, break вызывает завершение блока, связанного с указанными операторами. Интерпретатор Mini С++ обрабатывает оператор break С ПОМОЩЬЮ глобэльной персменной-флага breakfound, которая первоначально равна false. Когда обнаружен оператор break, переменной breakfound присваивается значение true. Затем эта переменная проверяется при обработке оператора switch (и описанных далее операторов цикла), для того чтобы выяснить, выполнялся ли оператор break. Если переменная breakfound равна true, выполнение текущего блока завершается и ей присваивается значение false.

Оператор break интерпретируется в функции interp () с помощью следующего кода:

case BREAK: обрабатьшает break breakfound = true;

Восстанавливает вложенную область видимости. local var stack,resize(nest scope stack.top()); nest scope stack.pop(); return;



1 ... 140 141 142 [ 143 ] 144 145 146 ... 156

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика