| FORTH | |
|||||
| Úvod | Výukové lekce | 05 06 07 | ||||
|
Lekce 6 - Definice, paměť, proměnné
Forth je tvořen slovy a nová
slova vytváří překladač z již
existujících slov, která
hledá ve
slovníku. Tato slova byla nadefinována buď
forthovským překladačem nebo jde o slova na
nejnižší úrovni, tzv. primitiva,
která jsou
napsána např. v assembleru. Překladač se
dá
také nadefinovat, což dává Forthu
velké
možnosti. Překladač si pak určuje,
jakým způsobem přečte zdrojový text,
jaké se
vytvoří datové struktury a jak se budou
zpracovávat.
Příklad 7:
Na
následujícím Obr. 7 jsou
příklady v F-PC
.![]() Obr. 7
Překladač pro definici nového slova (dvojtečka)
čte
slova oddělená mezerou, první
bude jméno
nového slova. Další slova
hledá ve
slovníku (pokud je nenalezne, ještě zjišťuje, zda jde o číslo) a vytváří strukturu, do
které
ukládá odkazy na tato slova. V každém
slově je
odkaz na strojový kód
výkonné části
překladače, který se spustí a slovo
zpracuje. V
primitivech je odkaz přímo na vlastní
strojový
kód. Definici slova ukončuje středník
(návrat ze
slova).
:
OBSAH DUP * PI * 100 / ; ( r
-- pi*r^2/100 )
Překladač pro definici proměnné (VARIABLE) přečte
následující slovo, což bude
jméno
proměnné, rezervuje paměťové místo pro
proměnnou a
vytvoří datovou strukturu kam uvede adresu
rezervované
paměti. Po zavolání proměnné se na TOS
ukládá adresa této
paměti a my potom čteme obsah adresy, nebo na ni
zapisujeme.
variable
VYSLEDEK
\ vytvoří proměnnou5 OBSAH VYSLEDEK ! \ spočítá obsah kruhu a ten uloží do proměnné VYSLEDEK VYSLEDEK @ . \ zobrazí obsah proměnné VYSLEDEK
Překladač pro definici
konstanty (CONSTANT) pracuje podobně, ale
neukládá do
struktury adresu, ale přímo hodnotu
konstanty, kterou si přečte při definici z TOS. Po
zavolání
konstanty se na TOS
ukládá hodnota konstanty.
314
constant PI Na obrázku obr.8
je ukázka výpisu paměti procesoru ATmega.
Nejdříve byla vytvořena konstanta PI, název je
znázorněn zeleně, kde první byte je délka
názvu (02). Tato délka leží na tzv. NFA - Name
Field Adress. Modré 16-bitové číslo je link na
začátek předchozího slova, tedy ukazuje na počet znaků
názvu předchozího slova. Modré číslo
leží na tzv. LFA - Link Field Adress, ukazuje na NFA
předchozího slova. Toto spojení je nutné pro
prohledávání slovníku. Růžové
číslo $3896 ukazuje na výkonou část překladače,
což je strojový kód, který v tomto případě
následující číslo $013A (314) uloží
na TOS. Leží na tzv. CFA - Code Field Adress.
Dále byla nadefinována proměnná VYSLEDEK, délka názvu 08, na LFA je $1CBB, která ukazuje na NFA slova PI (na číslo 02). Na CFA je odkaz na stejný překladač jako u konstanty PI, který následující číslo $01BB uloží na TOS. Je to adresa, na které je umístěna hodnota proměnné VYSLEDEK. Slovo OBSAH má
délku názvu 05, na LFA je $1CC0, ukazuje na NFA slova
VYSLEDEK (na číslo 08). Růžová adresa CFA ukazuje na
jiný překladač, než v předešlých případech.
Jde o překladač COLON (dvojtečka), který
čte nasledující 16-bitové odkazy na CFA
dalších slov. S velkou pravděpodobností tam najde
odkaz zase na překladač COLON, který bude číst odkazy na
CFAdalších slov a tak dál až k primitivu, kde na
CFA bude odkaz na následující adresu se
strojovým kódem. Šedé číslo je odkaz
na slovo EXIT (středník), které ukončuje slovo a
vrací běh slovu o úroveň výš.
![]() Obr.8: Výpis paměti |
|||
|
C!
( x addr -- )
|
Vyhodnotí se
příznak, pokud je true provedou se slova mezi IF .. THEN. <flag> IF <při true jdi sem> 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 |
||
| C@ ( addr -- x ) | 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 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 |
||
| ! ( x addr -- ) | 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. |
||
| @
( addr -- 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 |
||
| 2!
( d addr -- ) ( x1 x2 addr -- ) |
Nekonečná smyčka,
opakovaně provádí slova mezi BEGIN ... AGAIN. BEGIN <opakovaná slova> 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ě. |
||
| 2@
( addr -- d ) ( addr -- x1 x2 ) |
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. 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ě. |
||
| CREATE ( -- ) |
|||
| DOES>
( --
) |
Ukončí
právě definované slovo. Ve smyčce DO ... LOOP mu
musí předcházet slovo UNLOOP. |
||
| : ( --
) |
Zavolá
právě definované slovo. |
||
| ; ( --
) |
Ukončí
právě definované slovo. Ve smyčce DO ... LOOP mu
musí předcházet slovo UNLOOP. |
||
| :NONAME ( --
) |
Zavolá
právě definované slovo. |
||
| CODE ( --
) |
Ukončí
právě definované slovo. Ve smyčce DO ... LOOP mu
musí předcházet slovo UNLOOP. |
||
| ;CODE ( --
) |
Zavolá
právě definované slovo. |
||
| MARKER ( --
) |
Ukončí
právě definované slovo. Ve smyčce DO ... LOOP mu
musí předcházet slovo UNLOOP. |
||
| CONSTANT ( --
) |
Zavolá
právě definované slovo. |
||
| 2CONSTANT ( --
) |
Ukončí
právě definované slovo. Ve smyčce DO ... LOOP mu
musí předcházet slovo UNLOOP. |
||
| VARIABLE ( --
) |
Zavolá
právě definované slovo. |
||
| 2VARIABLE ( --
) |
Ukončí
právě definované slovo. Ve smyčce DO ... LOOP mu
musí předcházet slovo UNLOOP. |
||
| LITERAL ( --
) |
Zavolá
právě definované slovo. |
||
| 2LITERAL ( --
) |
Ukončí
právě definované slovo. Ve smyčce DO ... LOOP mu
musí předcházet slovo UNLOOP. |
||
| ____________________________________________________________________________________________________________________ 05.11.2008
- Luboš
Pěkný, čerpáno z
X3J14 dpANS-6. Podléhá
autorskému zákonu,
šíření povoleno jen s
uvedením autora.
|
|||