Интерпретация цикла for представляет собой более сложную задачу по сравнению с обработкой других циклов. Отчасти это связано с тем, что структура цикла for в языке С++ разрабатывалась в расчете на компиляцию. Главное неудобство состоит в том, что условное выражение должно проверяться в начале цикла, а наращивание управляющей переменной цикла выполняется в конце цикла. Следовательно, несмотря на то, что эти два компонента цикла for следуют один за другим в исходном коде, их интерпретация разделена повторно выполняемым блоком кода (телом цикла). Немного усилий и цикл for все-таки можно корректно интерпретировать. Когда функция interpo обнаруживает оператор for, она вызывает функцию exec_f or (), код которой приведен далее. // Выполняет цикл for. void exec_for() { int cond; char *temp, *temp2; int paren ; get_token(); // пропускает открывающую скобку ( eval_exp(cond); // выражение инициализации if(*token != ';') throw InterpExc(SEMI_EXPECTED); prog++; // переходит за ";" в исходном коде temp = prog; for(;;) { // Получает значение условного выражения. eval_exp(cond); if(*token ! = ';') throw InterpExc(SEMI_EXPECTED); prog++; // переходит за ";" в исходном коде temp2 = prog; // Ищет начало блока for. paren = 1; while(paren) { get_token(); if(*token == '(') paren++; if(*token == ')') paren—; } // Подтверждает начало блока. get_token(); if(*token •= '{') throw InterpExc(BRACE_EXPECTED); putback(); // Если условие true, интерпретирует if(cond) interp(); else { // в противном случае переходит к концу блока find_eob(); return; } prog = temp2; // переходит к инкрементному выражению // Ишет оператор break в цикле, if(breakfound) { // Ищет начало блока в цикле. do { get_token(); } while(*token != '{' && tok != END); putback(); breakfound = false; find_eob(); // теперь ищет конец цикла return; } II Вычисляет инкрементное выражение. eval_exp(cond); prog = temp; // возвращается к началу цикла } } Функция начинается с вычисления инициализирующего выражения в цикле for. Инициализирующая часть выполняется один раз и не входит в состав тела цикла. Далее указатель программы продвигается к позиции, следующей за точкой с запятой, завершающей инициализирующую часть цикла for и адрес этой позиции присваивается переменной temp. Это местоположение начала условного выражения. Далее выполняется вход в бесконечный цикл, который проверяет условное выражение цикла for и присваивает переменной temp2 адрес начала инкрементного выражения. Затем определяется начало кода цикла. Наконец, если условное выражение равно true, интерпретируется блок цикла. В противном случае находится конец блока цикла и продолжается выполнение части программы, следующей за циклом for. Предположим, что цикл выполняется, тогда после завершения вызова функции interp о вычисляется инкрементное выражение и процесс повторяется. Конечно, процесс будет остановлен, если внутри блока цикла встретится оператор break.
|