FORTH
Úvod Výukové lekce  01  02 

 
   Lekce 1 - Datový zásobník


   Forth pro předávání dat mezi operacemi, slovy, používá datový zásobník, což má tu vlastnost, že volané funkce nemusí znát adresy operandů, ví, že je najdou v zásobníku. Datový zásobník je vyhrazená oblast v paměti RAM, do které se postupně, za sebou, ukládají 16-bitová data a čtou se opět postupně, od posledně vložené položky. Vrchol zásobníků, posledně uložená položka, která se bude číst nejdříve, se nazývá TOS (top of stack). Položka, která
se bude číst příště je NOS (next on stack).

Příklad 1: Spustíme si F-PC nebo nainstalujeme Win32Forth . Napíšeme několik čísel oddělených mezerami, 1 2 3 4 a stiskneme ENTER.
Do zásobníku se nejdříve uloží 1, naposledy 4. Na vrcholu zásobníku (TOS) je tedy 4, NOS je 3.
 
FPC01
Obr. 1
Pro zobrazení obsahu TOS napíšeme tečku a stiskneme ENTER. Tím se přečte ze zásobníku 4 a zobrazí se. Napíšeme tři tečky oddělené mezerami a stiskneme ENTER. Zobrazí se 3 2 1 . Příklad znázorňuje Obr. 1 a animace.
Stack040

Příklad 2: Na následujícím Obr. 2  jsou prakticky vyzkoušeny operace se zásobníkem.
 
FPC02
Obr. 2
DUP
(x1 -- x1 x1)
stav zásobníku
před a po operaci,
x1 - libovolné 16b číslo
dupe Zduplikuje TOS.
5  DUP - do zásobníku se uloží číslo 5 a DUP přidá do zásobníku ještě další číslo 5.

Např. napíšeme 1 2 a stiskneme ENTER . Uloží se 1 (NOS) a 2 (TOS).
Napíšeme DUP  .  .  stiskneme ENTER. Na TOS je 2, tak DUP uloží do zásobníku další 2.
Tečky zobrazí 2 2 . Po další tečce se zobrazí 1, která se ničeho nezúčastnila.
dup
?DUP (x1 -- 0 | x1 x1)
po operaci
0 nebo x1 x1
question-dupe Pokud TOS neni 0, pak zduplikuje TOS.
Na TOS zůstane 0, nebo se TOS zduplikuje, symbolický zápis (0 | x1 x1).
Pro 1 2  ?DUP dostáváme stejný výsledek jako pro DUP.
Pro 1 0  ?DUP se operace neprovede, na TOS zůstáva 0 a na NOS 1.
Když napíšeme tři tečky s mezerami a ENTER, pak se zobrazí 0 1 a chybová hláška,
protože už je prázdný zásobník.
2DUP (d1 -- d1 d1)
(x1 x2 -- x1 x2 x1 x2)
d1 = x2*10000h+x1
two-dupe Zduplikuje pár, x1 na NOS, x2 na TOS (dvojnásobná přesnost 32b), hodnota=TOS*10000h+NOS.
Např. 1 0  2DUP přidá do zásobníku 1 a 0, DUP by přidal jen 0.
2 3  2DUP D. D. zkopíruje 2 na NOS, 3 na TOS, zobrazí dvakrát 32-bitové číslo 196610 (3*65536+2).
2dup
DROP (x1 -- ) drop Odstraní TOS.
Např. 1 2  DROP . . odstraní 2, tečka zobrazí 1 a druhá tečka způsobí chybovou hlášku, zásobník je už prázdný
drop
2DROP (d1 -- )
(x1 x2 -- )
two-drop Odstraní pár, TOS a NOS.
Např. 1 2 3 4 5  2DROP odstraní 5 a 4, na TOS je teď 3, NOS je 2,
tři tečky s mezerami a ENTER pak zobrazí zbylé 3 2 1
Možná definice     : 2DROP  DROP  DROP ;
2drop
OVER (x1 x2 -- x1 x2 x1) over Zkopíruje x1 (NOS) na TOS.
Např. 1 2 3  OVER zkopíruje 2 na TOS, tečkou zobrazíme 2, dalšími tečkami původní 3 2 1.
S tímto slovem se dá nadefinovat     : 2DUP  OVER  OVER ;
over
2OVER (d1 d2 -- d1 d2 d1)
(x1 x2 x3 x4 --
 x1 x2 x3 x4 x1 x2)
two-over Zkopíruje d1 (pár x1,x2) na NOS, TOS.
Např. 1 2 3  2OVER zkopíruje na TOS jen 1, pak nemá co kopírovat.
1 2 3 4 5  2OVER zkopíruje 2 a 3, při vyčítání pak zobrazí 3 2 a původní 5 4 3 2 1.
2over
ROT (x1 x2 x3 -- x2 x3 x1) rote Rotace, přesune x1 na TOS
Např. 1 2 3  ROT smaže 1 a uloží ji za 3, na TOS. Při vyčítání zobrazí 1, pak 3 2.
rot
2ROT (d1 d2 d3 -- d2 d3 d1)
(x1 x2 x3 x4 x5 x6 --
 x3 x4 x5 x6 x1 x2)
two-rote Rotace, přesune d1 (pár x1,x2) na NOS, TOS.
Např. 1 2 3 4 5 6  2ROT smaže 1 2 a uloží je za 6. Při vyčítání zobrazí 2 1 a 6 5 4 3.
2rot
SWAP (x1 x2 -- x2 x1) swap Prohodí NOS a TOS.
Např. 1 2 3 4  SWAP prohodí 3 a 4. Při vyčítání ze zásobníku se zobrazí 3 4 a zbylé 2 1.
swap
2SWAP (d1 d2 -- d2 d1)
(x1 x2 x3 x4 --
x3 x4 x1 x2)
two-swap Prohodí dvojité buňky d1 a d2 ( x1 a x3, x2 a x4)
Např. 1 2 3 4  2SWAP prohodí 1 a 3, 2 a 4. Při vyčítání ze zásobníku se zobrazí 2 14 3.
2swap
NIP (x1 x2 -- x2) nip Odstraní NOS (x1). DROP by odstranil TOS (x2)
Např. 1 2 3  NIP odstraní 2, při vyčítání se zobrazí 3 1.
nip
PICK (xu..x0 u -- xu..x0 xu) pick Zkopíruje u-té číslo od NOS na TOS
Např. 1 2 3 4 3  PICK zkopíruje 3.číslo od NOS (NOS je 4, 1. je 3,  2. je 2,  3. je 1),
 tedy 1 na TOS. Při vyčítání ze zásobníku se zobrazí 1 a zbylé 4 3 2 1.
pick
ROLL (xu..x0 u -- xu-1..x0 xu) roll Rotace, přesune u-té číslo od NOS na TOS.
Např. 1 2 3 4 2  ROLL přesune 2.číslo od 4 (1. je 3,  2. je 2) na TOS. Při vyčítání ze zásobníku se zobrazí 2 4 3, dvojka byla přesunuta a 1.
roll
TUCK (x1 x2 -- x2 x1 x2) tuck Zkopíruje TOS (x2) pod NOS (před x1).
Např. 1 2 3 4  TUCK zkopíruje 4 mezi 2 a 3. Při vyčítání se zobrazí 4 3, vložená 4 a pak 2 1.
tuck
____________________________________________________________________________________________________________________
01.11.2007 - Luboš Pěkný, čerpáno z  X3J14 dpANS-6.