Давайте создадим компилятор! :: Креншоу Джек
Страница:
70 из 382
Для полноты давайте добавим и эту конструкцию. Это будет наш последний цикл.
Синтаксис и его перевод:
DO
{ Emit(SUBQ #1,D0);
L = NewLabel;
PostLabel(L);
Emit(MOVE D0,-(SP) }
ENDDO { Emit(MOVE (SP)+,D0;
Emit(DBRA D0,L) }
Это гораздо проще! Цикл будет выполняться раз. Вот код:
{–}
{ Parse and Translate a DO Statement }
procedure Dodo;
var L: string;
begin
Match('d');
L := NewLabel;
Expression;
EmitLn('SUBQ #1,D0');
PostLabel(L);
EmitLn('MOVE D0,-(SP)');
Block;
EmitLn('MOVE (SP)+,D0');
EmitLn('DBRA D0,' + L);
end;
{–}
Я думаю вы согласитесь, что это гораздо проще, чем классический цикл FOR. Однако, каждая конструкция имеет свое назначение.
ОПЕРАТОР BREAK
Ранее я обещал вам оператор BREAK для сопровождения цикла LOOP. Им я в некотором роде горд. На первый взгляд BREAK кажется действительно сложным. Моим первым подходом было просто использовать его как дополнительный ограничитель в Block и разделить все циклы на две части точно также как я сделал это для ELSE оператора IF. Но, оказывается, это не работает, потому что оператор BREAK редко находится на том же самом уровне, что и сам цикл. Наиболее вероятное место для BREAK – сразу после IF, что приводило бы к выходу из конструкции IF, а не из окружающего цикла. Неправильно. BREAK должен выходить из внутреннего LOOP даже если он вложен в несколько уровней IF.
Моей следующей мыслью было просто сохранять в какой-то глобальной переменной, метку окончания самого вложенного цикла.
|< Пред. 68 69 70 71 72 След. >|