Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [ 22 ] 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97

реализованы довольно эффективно... обычно очень сложно улучшить код, сгенерированный для IF или WHILE. Но практически каждый компилятор, который я когда-либо видел, генерирует ужасный код, по сравнению с ассемблером, для вычисления булевых функций и особенно отношений. Причина как раз в том, о чем я упомянул выше. Когда я пишу код на ассемблере, я двигаюсь вперед и выполняю проверку наиболее удобным для меня способом, и затем подготавливаю ветвление так чтобы переход был выполнен на нужную ветку. Фактически, я "подстраиваю" каждое ветвление под ситуацию. Компилятор не может сделать этого (практически) и он также не может знать, что нам не нужно сохранять результат проверки как булевскую переменную. Поэтому он должен генерировать код по очень строгим правилам и часто заканчивает сохранением результата как булевой переменной, которая никогда не будет использована для чего-либо.

В любом случае мы теперь готовы рассмотреть код для Relation. Он показан ниже с сопровождающими процедурами:

{ Recognize and Translate a Relational "Equals" }

procedure Equals;

begin

Match(=);

Expression;

EmitLnCCMP (SP) + ,D0);

EmitLn(SEQ D0);

end;

{ Recognize and Translate a Relational "Not Equals" }

procedure NotEquals;

begin

Match(#);

Expression;

EmitLn(CMP (SP)+,D0); EmitLn(SNE D0);

end;

{ Recognize and Translate a Relational "Less Than" }

procedure Less;

begin

Match(<);

Expression;

EmitLn(CMP (SP)+,D0); EmitLn(SGE D0);

end;

{ Recognize and Translate a Relational "Greater Than" }

procedure Greater;

begin

Match(>);

Expression;

EmitLn(CMP (SP)+,D0); EmitLn(SLE D0); end;

{ Parse and Translate a Relation }

procedure Relation;

begin

Expression;

if IsRelop(Look) then begin EmitLn(MOVE D0,-(SP));



case Look of

=: Equals;

#: NotEquals;

<: Less;

>: Greater; end;

EmitLnCTST D0); end; end;

Теперь этот вызов Expression выглядит знакомым! Вот где редактор вашей системы оказывается полезным. Мы уже генерировали код для Expression и его близнецов на предыдущих уроках. Теперь вы можете скопировать их в ваш файл. Не забудьте использовать односимвольную версию. Просто чтобы быть уверенным, я продублировал арифметические процедуры ниже. Если вы наблюдательны, вы также увидите, что я их немного изменил чтобы привести в соответствие с последней версией синтаксиса. Эти изменения не являются необходимыми, так что вы можете предпочесть оставить все как есть до тех пор, пока не будете уверены, что все работает.

{ Parse and Translate an Identifier } procedure Ident; var Name: char; begin

Name:= GetName; if Look = ( then begin MatchCC); Match());

EmitLn(BSR + Name); end else

EmitLnCMOVE + Name + (PC),D0);

end;

{ Parse and Translate a Math Factor } procedure Expression; Forward; procedure Factor; begin

if Look = ( then begin MatchCC); Expression; Match()); end

else if IsAlpha(Look) then

Ident else

EmitLnCMOVE # + GetNum + ,D0);

end;

{ Parse and Translate the First Math Factor }

procedure SignedFactor;

begin

if Look = + then

GetChar; if Look = - then begin GetChar;

if IsDigit(Look) then

EmitLn(MOVE #- + GetNum + ,D0) else begin



Factor;

EmitLn(NEG D0);

end;

else Factor; end;

{ Recognize and Translate a Multiply } procedure Multiply; begin

Match(*); Factor;

EmitLn(MULS (SP)+,D0);

end;

{ Recognize and Translate a Divide } procedure Divide; begin

Match(/); Factor;

EmitLn(MOVE (SP)+,D1); EmitLn(EXS.L D0); EmitLn(DIVS D1,D0); end;

{ Parse and Translate a Math Term } procedure Term; begin

SignedFactor;

while Look in [*, /] do begin EmitLnCMOVE D0,-(SP)); case Look of *: Multiply; /: Divide; end; end; end;

{ Recognize and Translate an Add } procedure Add; begin

Match(+); Term;

EmitLn(ADD (SP)+,D0);

end;

{ Recognize and Translate a Subtract } procedure Subtract; begin

Match(-); Term;

EmitLn(SUB (SP)+,D0); EmitLn(NEG D0); end;



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [ 22 ] 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97