Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Martin 10. 01. 2013, 14:17:09
-
Ahoj,
v jedne pisemce na skole byl priklad na Forth. Ukolem bylo definovat slovo AVERAGE, ktere ocekava na vrcholu zasobniku adresu vektoru typu VECTOR a vrati celociselny odhad prumeru jeho hodnot.
a) Datovy typ VECTOR je definovan slovem:
: VECTOR CREATE DUP , 0 DO , LOOP
DOES>
;
b) Adresu polozky vektoru vraci slovo [] definovane nasledovne:
: []
4 +
SWAP
4 *
+ ;
c) slovo definujte stylem pouzitym v predchozim bode, pricemz v komentarich budou uvadeny polozky na vrcholu zasobniku
No a ja bych chtel poprosit, jestli by mi tady nekdo vysvetlit slovy tu definici z bodu a) a b) a pak napsal jak by mel vypadat kod toho slova AVERAGE a opet s nejakym slovnim popisem. Forth jsem nikdy nemel a videl jsem ho ted prvne v zivote, takze jsem v nem uplne ztracenej. Diky predem za vysvetleni.
-
Pokud to dobře chápu:
Vytvoření definice VECTORu:
parametr na zásobníku (počet prvků vektoru) zálohovat pro smyčku, uložit jeho adresu do definice slova (","), a smyčkou (nkrát) opakovat totéž pro další položky na zásobníku.
(CREATE DOES> se volá jen při prvním použití VECTOR, jinak - za DOES> - nedělá nic.)
Takže zřejmě
11 15 31 43 4 VECTOR MUJVEKTOR
vytvoří MUJVEKTOR se 4 vyjmenovanými prvky.
[] k adrese dat VECTORu (v okamžiku volání VECTOR by měl TOS ukazovat na obsah vektoru) přičte 4, NOS (=TOS před vykonáním skoku na VECTOR) vynásobí čtyřmi (že by 32bitové prvky vektoru?), výsledky sečte (adresa_prvku_n = (adresa_nulteho_prvku + 4) + (4 * n)
Tedy
4 MUJVEKTOR []
vrací adresu čtvrtého 32bitového prvku vektoru.
(akorát jako první je ve vektoru uložen počet jeho prvků (adresa_vektoru+0) a až pak obsah nultého (adresa_vektoru+4) prvku vektoru, počet prvků tak teoreticky pomocí slova [] načíst nejde).
Ovšem bez záruky.
-
(akorát jako první je ve vektoru uložen počet jeho prvků (adresa_vektoru+0) a až pak obsah nultého (adresa_vektoru+4) prvku vektoru, počet prvků tak teoreticky pomocí slova [] načíst nejde).
Proč taky, když tuto informaci nám zanechají na zásobníku přímo slova vytvořená pomocí VECTORu, tedy jednotlivé vektory. DOES> v jeho definici sice nedělá nic (v daném případě je tam napsáno úplně zbytečně), ale každé slovo vytvořené pomocí CREATE jednu věc přeci jen dělá vždycky: zanechá na zásobníku svou PFA. Vytvoříme-li si např. nový 3-složkový vektor vec := (10, 20, 30), tj.
30 20 10 3 VECTOR vec
pak použití slova vec způsobí, že na zásobníku je adresa jeho prvního datového členu, tj. počtu jeho složek, čili pomocí vec @ získáme počet jeho složek. Jeho průměr pak získáme pomocí vec AVERAGE, definovaného např. následovně:
: AVERAGE ( addr -- n )
DUP @ 0 ROT ( počet-složek 0 addr )
DUP @ ( počet-složek 0 addr počet-složek )
0 DO ( počet-složek mezisoučet-složek addr )
CELL + DUP @ ( počet-složek mezisoučet-složek addr-přičítané-složky přičítaná-složka )
ROT + SWAP ( počet-složek mezisoučet-složek addr-přičítané-složky )
LOOP
DROP SWAP / ; ( arit.průměr-složek )
Nejprve si na prvním řádku těla AVERAGE uschováme počet složek vektoru a připravíme si místo pro mezisoučet inicialisovaný nulou. Následující smyčka DO...LOOP se provede počet-složek-krát, k adrese addr přičítáme vždy jednu buňku (CELL) a poskakujeme tak postupně po jednotlivých složkách vektoru, přičítajíce jejich obsah k mezisoučtu (kde byla na začátku nula). Po skončení smyčky zahodíme addr-přičítané-složky, kterou už k ničemu nepotřebujeme, prohodíme operandy tak, jak je očekává dělení, a vydělíme (/).
Pozn.: CELL je konstanta určující, kolik bajtů tvoří jednu buňku. V zájmu přenositelnosti a přehlednosti se doporučuje používat ji místo číselné hodnoty. V definici slova [] by taktéž bylo vhodné ji použít místo čísla 4:
: [] ( n addr1 -- addr2 )
CELL +
SWAP
CELLS + ;
(slovo CELLS násobí velikostí buňky)
-
Super to jsem potřeboval, ještě se v tom trošku pošťourám, abych to pořádně pochopil, ale fakt moc děkuju za vyčerpávající odpověď.