FORTH
Úvod Výukové lekce  04 05 06 


   Lekce 5 - Podmínky, smyčky


   V této kapitole se seznámíme se slovy pro podmíněný příkaz a větvení běhu programu (určitá část programu se provede jen za určitých podmínek) a
se slovy pro smyčky (část programu se opakuje daný počet cyklů nebo za určitých podmínek). Další slova slouží k předčasnému ukončení smyček.
   Tyto nová slova využívají zásobník návratových adres (ZNA, Return stack) pro ukládání svých parametrů. Pokud uložíme do ZNA číslo před spuštěním smyčky (podmíněného příkazu, atd.) a chceme číslo vyčíst v průběhu smyčky (podmíněného příkazu), musíme přesně znát funkci těchto nových slov, kde naše číslo ve ZNA přesně leží. Toto neplatí, pokud číslo vyčteme až po skončení smyčky (podmíněného příkazu), nebo číslo uložíme a vyčteme uvnitř smyčky (podmíněného příkazu).

Příklad 6: Na následujícím Obr. 6 jsou příklady v F-PC .

FPC06
Obr. 6
flag IF ... THEN  ( flag -- )


Vyhodnotí se příznak, pokud je true provedou se slova mezi IF .. THEN.
<flag> IF <při true jdi sem> THEN
if-then

Např.
: inc8  dup  8  <  if  1+  then ;
 \  přičte k TOS číslo 1, pokud na TOS je číslo menší než 8
7 inc8 .  9 inc8 .    zobrazí  8  9

flag IF ... ELSE ... THEN
( flag -- )
Vyhodnotí se příznak, pokud je true provedou se slova mezi IF .. ELSE, jinak mezi ELSE .. THEN.
<flag> IF <při true jdi sem> ELSE <jinak při false sem> THEN
if-else

Např.
:  koule 5  =
   if
     25
  else
      0
  then  ;  \  pokud je na TOS číslo 5, ulož na TOS číslo 25, jinak 0
3 koule .  5 koule .    zobrazí  0  25

n2 n1  DO ... LOOP
n2 n1 ?DO ... LOOP
n2 n1  DO ... n3 +LOOP
n2 n1 ?DO ... n3 +LOOP
( n2 n1 -- )

I - index smyčky
J - index vnější smyčky
( -- n )

LEAVE - ukončení
UNLOOP - opuštění
Smyčka pro opakování slov mezi DO ... LOOP  od n1 do n2-1.
?DO navíc testuje n2=n1, pak se smyčka neprovede.
+LOOP  zvyšuje index smyčky o n3.
max  min   DO  <zde opakuj od min do max-1>  LOOP
max  min   DO   <zde opakuj od min do max-1, s krokem n>  +LOOP

LEAVE  předčasně ukončí smyčku.
UNLOOP  EXIT  předčasně ukončí smyčku a opustí vykonávané slovo.

Např.
: test1  5  0  do  i  .  loop ;   \ zobrazi 0 1 2 3 4
: test1z  -5  0  do  i  .  -1 +loop ;  \ zobrazí 0 -1 -2 -3 -4 -5
: test2  9  6  do  2  4  do  i  .  j  .  loop  loop  ;  \ zobrazi 2 6 3 6 2 7 3 7 2 8 3 8
: test3  31  3  do  i  .  3  +loop  ;   \ zobrazi nasobilku čísla 3,  3 6 9 12 15 18 21 24 27 30
: test4
   5  0  do
      i  2 =  if  i  leave then
   loop  .   
 \  při indexu 2 ukončí smyčku, vytiskne 2
   5  0  do
       i  3 =  if unloop exit then
   loop 3 . ;
 \  při indexu 3 ukončí smyčku a slovo test4, k tisku čísla 3 nedojde.

x CASE
...
x1 OF ... ENDOF
...
xn OF ... ENDOF
...
ENDCASE
( x -- )

 
Vybere případ, pro x = xi se provedou slova mezi OF ... ENDOF.
OF
porovna TOS a NOS, pokud se rovnají provedou se slova mezi OF ... ENDOF a skočí se na ENDCASE.
Pokud se nerovnají, zachová se hodnota x na NOS pro další porovnání a smaže se hodnota xi na TOS.

Např.
: testcase  ( x -- x )
   case
   3 of  1  endof
   4 of  2  endof
   5 of  9  endof
   drop 0
   endcase ;
 \  zmeni cislo 3 na 1, 4 na 2, 5 na 9, ostatni hodnoty na 0.
5 testcase .  6 testcase .    zobrazí  9  0

BEGIN ... AGAIN
( -- )
Nekonečná smyčka, opakovaně provádí slova mezi BEGIN ... AGAIN.
BEGIN  <opakovaná slova> AGAIN
beg-again

Např.
 : testESC1
    begin
       1  .  key  27  =  if  exit  then
    again  2  .  
;  \  při stisku klávesy zobrazí číslo jedna, při ESC opustí slovo testESC1, nezobrazí číslo dvě.

BEGIN ... flag UNTIL
( -- )
Opakuj do splnění podmínky.
BEGIN <opakovaná slova flag> UNTIL
Slova se provedou alespoň jednou, pokud UNTIL na TOS najde TRUE, ukončí smyčku.
beg-until

Např.
: testESC2
   begin
      1  .  key 27 =
   until  2  . ;  \  při stisku klávesy zobrazí číslo jedna, při ESC ukončí smyčku, zobrazí číslo dvě.

BEGIN
...
flag WHILE
...
REPEAT
( -- )
Opakuj, pokud je splněna podmínka.
BEGIN <slova flag> WHILE <opakovaná slova> REPEAT
Slova se opakují, jen když WHILE na TOS najde TRUE, nemusí se opakovat ani jednou.
beg-repeat

Např.
: testESC3
   begin
      key  27  <>
   while
      1  .
   repeat  2  . ;
 \ při stisku klávesy zobrazí číslo jedna, při ESC ukončí smyčku, zobrazí číslo dvě.

EXIT  ( -- )
Ukončí právě definované slovo. Ve smyčce DO ... LOOP mu musí předcházet slovo UNLOOP.

Např.
: Deleni  ( n1 n2 )  dup  0=
   if
     drop drop ." Deleni nulou "  exit
   then  /  .  ;   
\  Pokud je na TOS číslo 0 zobrazí nápis a opustí slovo deleni, jinak zobrazí podíl n1/n2

RECURSE  ( -- )
Zavolá právě definované slovo.

Např. typický příklad výpočtu faktoriálu z dpANS-6.
: FACTORIAL ( +n1 -- +n2)  DUP  2  >  IF  DUP  1-  RECURSE  *  THEN ;

____________________________________________________________________________________________________________________
09.07.2008 - Luboš Pěkný, čerpáno z  X3J14 dpANS-6.