Forth a vysvětlení příkladu

Martin

Forth a vysvětlení příkladu
« kdy: 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:
Kód: [Vybrat]
: VECTOR CREATE DUP , 0 DO , LOOP
                DOES>
;
b) Adresu polozky vektoru vraci slovo [] definovane nasledovne:
Kód: [Vybrat]
: []
  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.
« Poslední změna: 10. 01. 2013, 19:25:04 od Petr Krčmář »


j.t.d

Re:Forth a vysvětlení příkladu
« Odpověď #1 kdy: 10. 01. 2013, 22:57:06 »
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.

Viky

Re:Forth a vysvětlení příkladu
« Odpověď #2 kdy: 11. 01. 2013, 04:04:03 »
(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.
Kód: [Vybrat]
30 20 10 3 VECTOR vecpak 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ě:
Kód: [Vybrat]
: 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:
Kód: [Vybrat]
: []  ( n addr1  --  addr2 )
    CELL +
    SWAP
    CELLS + ;
(slovo CELLS násobí velikostí buňky)

Martin

Re:Forth a vysvětlení příkladu
« Odpověď #3 kdy: 11. 01. 2013, 21:09:24 »
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ěď.