|
Программирование >> Формирование пользовательского контейнера
Как видите, кроме присваивания значения true переменной breakfound восстанавливается стек локальных переменных до состояния, которое он имел перед началом выполнения прерываемого блока. Напоминаю, что внутри любого блока могут быть объявлены переменные, локальные по отношению к нему. Следовательно, когда встречается оператор break, все ло-, кальные переменные прерываемого блока должны быть удалены. Оператор switch выполняется функцией exec switch(), код которой приведен далее. Выполняет оператор switch. void exec switch() int sval, cval; int brace; eval eзф(sval); Получает выражение switch. Проверяет начало блока. if(*token != {) throw InterpExc(BRACE EXPECTED); Записывает новую область видимости. nest scope stack.push(local var stack.size О); Теперь проверяет операторы case. for(;;) { brace = 1; Находит оператор case, do { get token(); if(*token == {) brace++; else if(*token == }) brace-; } while(tok != CASE && tok != END && brace); Если соответствутего оператора case не найдено, то пропускает, if(!brace) break; if(tok == END) throw Interpexc(SYNTAX); Получает значение метки оператора case. Сначала функция exec switch() получает значение выражения оператора switch и запоминает его в переменной sval. Затем она находит начало блока switch и сохраняет вершину стека локальных переменных в стеке nest scope stack. Этот шаг необходим, потому что оператор switch создает вложенную область видимости. Далее исследуются значения меток операторов case, пока не встретится то, которое совпадает со значением переменной sval. или не будет достигнут конец оператора switch (напоминаю, что для простоты реализации интерпретатор Mini С++ не поддерживает метку default в операторе switch). Если совпадение найдено, выполняются операторы, связанные с этой меткой, до тех пор, пока не встретится оператор break eval exp(cval); Читает и отбрасывает : get token () ; if(*token != :) throw InterpExc(COLON EXPECTED); Если значения совпадгиот, то интерпретирует, if(cval == sval) brace = 1; do { interpO ; if(*token == {) brace++; else if(*token == ) ) brace--; ) while(!breakfound && tok != END && brace); Находит конец оператора switch, while(brace) { get token(); if(*token == {) brace++; else if(*token == }) brace--; breakfound = false; break; (т. е. пока переменная breakfound не равна true) или пока не будет найден конец блока оператора switch. После обнаружения оператора break функция exec switch() завершается поиском конца блока оператора switch и установкой значения переменной breakfound равным false. Выполнение цикла while Цикл while интерпретировать совсем легко. Эту задачу выполняет функция exec while (), КОД которой Приведен далее. Выполняет цикл while. void exec while() int cond; char *tenp; putbackO; возвращает во входной поток лексему while tenp = prog; сохраняет начало цикла while gettokenO ; eval eзф(cond); проверяет условное выражение Подтверждает начало блока. if(*token != {) throw InterpExc(BRACE EXPECTED); if(cond) interpO; если true, интерпретирует else { в противном случае переходит к концу цикла find eob(); return; prog = tenp; возвращается к началу Ищет оператор break в цикле, if(breakfound) { Ищет начало блока в цикле. do { get token();
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |