[size=150]Forth[/size]
Forth on hyvin vanha ohjelmointikieli, jota Charles Moore aloitti kehittelemään jo 1960-luvulla. Forth on pinokieli ja operaatiot kohdistuvat pinoon. Forth on yleensä tulkki ja kääntäjä yhdistelmä. Sillä voi kirjoittaa ohjelmia ja lisäksi tehdä interaktiivisia toimintoja. Lisäksi Forthissa on valkoista avaruutta eli välilyöntejä, tabeja jne sekä numeroita ja sanoja. Numero voi olla tietenkin desimaali tai vaikka heksadesimaali. Tämä riippuu mihin kantalukuun Forth on asetettu. Sana voi olla vakio, muuttuja tai jotain funktiota muistuttava asia. Sana siis manipuloi pinoa.
Forth on myös laajennettava. Omia sanoja, jotka jossain sopivassa ympäristössä voisi olla määriteltynä esimerkiksi
: pikapesu pese huuhtele linkoa ;
Kaksoispiste aloittaa sanan määrittelyn, pikapesu on sanan nimi ja pese, huuhtele ja linkoa ovat suoritettavia sanoja, jotka ovat erotettu välilyönneillä. Puolipiste päättää määrittelyn. Forth ei myöskään yleensä ole merkkikoosta tarkka. ISOSANA on yleensä sama sana kuin isosana.
Forthin kantava ajatus on, että ongelmat ovat yksinkertaisia, kun ne vain yksinkertaistetaan ja rajataan tarpeeksi. Suunnittele ylhäältä alas ja toteuta alhaalta ylös. Silloin pikapesu voi todellakin olla kuvatun kaltainen, kun monimutkaisuus on pilkottu pieniin palasiin alla oleviin kerroksiin yksinkertaistettuna.
Seuraavaksi käyn läpi kielestä läpi hyvin pienen pintaraapaisun. En sekaannu liukulukupinoon, enkä merkkijonojen käsittelyyn. Myös sanakirjan käsittely, muistin varaaminen ja monet muut asiat jätetään käsittelemättä. Kuitenkin kaikki sanat saa näkymään sanalla WORDS. Kannattaa tutustua itselle valitun toteutuksen dokumentaatioon, standardiin ja siihen miten jokin sana on määritelty.
Kooditagien sisään on kirjoitettu ja lähinnä kopipastetttu mitä tapahtui. Vastaukset ovat kommentoituina. Periaatteessa Voit kopioda näitä koodeja suoraan gForthiin, mutta jokaisen kommenttirivin perässä on sitten myös ok
[size=150]Pino[/size]
Koska Forth on pinokieli, se tekee tarjoaa käyttäjälleen käänteisen puolalaisen logiikan tai postfiksi notaation, kummaksi nyt haluaa kutsua. Mikäli Forthissa haluaa nähdä 3 + 7 laskutoimituksen tuloksen kirjoitetaan 3 7 + . Tuossa tapahtuu ensin 3 ja 7 pinoon laitto. Tämän jälkeen + ottaa pinosta kaksi elementtiä, laskee ne yhteen ja laittaa pinoon tuloksen. Piste ottaa pinosta päällimmäisen ja näyttää sen.
postfiksin voima näkyy parhaiten sulkeilla laskettaessa. 7 * ( 2 + 3 ) lasketaan
2 \ Vastaus: ok
3 \ Vastaus: ok
+ \ Vastaus: ok
7 \ Vastaus: ok
* \ Vastaus: ok
. \ Vastaus: 35 ok
Forthissa sulkeilla on oma merkityksensä. Koska pinon tila on tärkeä kehittäjälle, yleensä (luetaan aina) sanan määrittelyyn lisätään pinon vaikutuskommentti.
: laske_tilavuus ( leveys korkeus syvyys -- tilavuus ) * * ;
\ Pinon vaikutuskommentissa kerrotaan, että ennen suoritusta
\ tarvitaan kolme lukua, joista päällimmäinen on syvyys ja suorituksen jälkeen
\ pinossa on tilavuus
\ Normaalit kommentit alkavat kenoviivalla ja kommentti on koko rivi.
\ Ja testataan...
1 2 3 laske_tilavuus cr .
\ Laita 1, 2 ja 3 pinoon suorita laske_tilavuus, rivinvaihto ja
\ tulosta pinon päällimmäinen
\ Vastaus: 6 ok
\ cr aiheuttaa rivinvaihdon.
Pinoa voi myös manipuloida.
DUP ( x – x x ) Kopioi päällimmäisen pinossa.
SWAP ( x1 x2 – x2 x1 ) vaihtaa kahden päällimmäisen järjestystä pinossa
ROT ( x1 x2 x3 – x2 x3 x1 ) Kierrättää kolmea päällimmäistä pinossa
DROP ( x – ) poistaa ja unohtaa päällimmäisen pinosta
ovat yleisimmät, mutta eivät ainoat manipulaattorit.
[size=150]Kääntäminen ja tulkkaus[/size]
Kuten mainittu, Forthissa on kaksi tilaa: kääntäminen ja tulkkaus. Kääntäessä luodaan sanoja, kuten ylemmässä koodissa luotiin laske_tilavuus ja tulkattaessa ajetaan näitä sanoja esimerkkinä 1 2 3 laske_tilavuus cr .
Näissä tiloissa on käytössä eri sanoja. Joitain ei voi ajaa kääntäessä ja toisia ei voi ajaa tulkatessa. Ja tämähän on sitten täysin riippuvainen mitä Forthin toteutusta käytetään.
2 0> if ." Ei onnistu." then
\ Vastaus: :32: Interpreting a compile-only word
\ Vastaus: 2 0> >>>if<<< ." Ei onnistu." then
: parannettu_hello_world cr dup 0> if . ." kertaa heippa maailma!" else ." Negatiivinen tervehdys." then cr ; \ Vastaus: ok
-2 parannettu_hello_world
\ Vastaus: Negatiivinen tervehdys.
\ Vastaus: ok
2 parannettu_hello_world
\ Vastaus: 2 kertaa heippa maailma!
\ Vastaus: ok
Tulkatessa ei voi käyttää if else then vuonohjausrakennetta. Siksi se tarvitsee kääntää. Ja siksi on luotu parannettu_hello_world. Ensin tulostetaan rivinvaihto ja kopioidaan päällimmäinen pinosta. Päällimmäistä verrataan nollaan, jolloin pinoon jää numero ja totuusarvo. IF suorittaa if … else välin, mikäli totuusarvo on totta ja else … then mikäli ei. ." Tulostettava juttu" käskyllä tulostuu tekstiä ruudulle. ." jälkeinen välilyönti ei kuitenkaan tulostu, sillä se on sanan erotin.
Totuusarvot ovat määritelty seuraavasti 0 on epätosi (kaikki bitit alhaalla) ja 0 invert on tosi, joka sitten on -1 (kaikki bitit ylhäällä). Myös kaikki muut arvot kuin 0 voidaan tulkita tosi arvoiksi.
Usein on esitelty myös sana endif, jota voi käyttää then sanan tilalla. Forthissa then tarkoittaa nyt kun ollaan tämä käsitelty niin jatketaan sitten tästä. Siksi endif kuvaa paremmin if-rakenteen lopetusta.
[size=150]Silmukat[/size]
Ikikieriön saa aikaan määrittelemällä sanan jossa on BEGIN ja AGAIN esimerkiksi : ikikierio ( – ) 1 begin 1 + dup . cr again ; tulostaisi numeroita päättymättömästi kasvaen ja ylivuotaen.
Koska moinen olisi hieman pöljää lähes aina on olemassa myös BEGIN koodia totuusarvo UNTIL. Esimerkkinä
: laske_alas ( alku -- ) BEGIN 1 - dup dup . cr 0= UNTIL drop ;
\ Viimeinen drop pudottaa laskussa käytetyn numeron pois, joka on tapauksessamme 0
10 laske_alas \ Vastaus: 9
\ Vastaus: 8
\ Vastaus: 7
\ Vastaus: 6
\ Vastaus: 5
\ Vastaus: 4
\ Vastaus: 3
\ Vastaus: 2
\ Vastaus: 1
\ Vastaus: 0
\ Vastaus: ok
Silmukkaa ajetaan siis kunnes totuusarvo on tosi.
BEGIN koodi1 totuusarvo WHILE koodi 2 REPEAT silmukka ajaa koodi1 josta tulee totuusarvo ja koodi2 ajetaan mikäli totuusarvo oli totta, jonka jälkeen palataan koodi1 alkuun. Mikäli totuusarvo olikin epätosi, jatketaan REPEAT jälkeisestä sanasta.
DO koodia LOOP on vähän kuin for rakenne C:ssä. DO ( raja alku – ) aloittaa silmukan ja koodia suoritetaan LOOP ( – ) sanaan asti. LOOP sanassa indeksiä korotetaan yhdellä ja jos se on yhtä suuri kuin raja, silmukasta poistutaan.
I on erityinen muuttuja. Se sijaitsee toisaalla ja paikassa, johon en tule tässä puuttumaan. Paikka on return stack. I pitää sisällään indeksin, jota silmukka iteroi.
: laskettu_silmukka do i . loop ; \ Vastaus: ok
10 5 laskettu_silmukka \ Vastaus: 5 6 7 8 9 ok
[size=150]Muuttujat[/size]
Joskus on vain kiva käyttää muuttujia ja vakioita.
Muuttujia voi käsitellä seuraavalla tavalla
\ luodaan muuttuja
variable muuttuja
\ tallennetaan pinosta muuttujaan arvo !-sanalla. Lausutaan store
10 muuttuja !
\ haetaan muuttujan arvo pinoon @-sanalla. Lausutaan fetch
muuttuja @
Vakioita luodaan miltei samalla tavalla. Siihen eteen vain laitetaan eteen haluttu arvo.
\ Luodaan
100 constant sentit_metrissa
\ Laitetaan pinoon ja tulostetaan pois
sentit_metrissa cr .
\ Vastaus: 100 ok
[size=150]Standardi ja toteutukset[/size]
Forthista on olemassa standardi. ANS FORTH vuodelta 1994 ja päivitettyä versiota ollaan tekemässä. Standardia voi lukea http://www.taygeta.com/forth/dpans.html ja valita itselleen sopivan Forth toteuksen http://www.forth.org/compilers.html
Tässä artikkelissa on käytetty gforthia esimerkkien tekemiseen. Sivulta huomattaneen helposti, että useimmat toteutukset ovat tarkoitettu mikrokontrollereihin. Lisäksi paljastettakoon, että monet toteutuksista on tehty assemblerilla.
[size=150]AmForth[/size]
AmForth on AVR mikrokontrollereille tarkoitettu Forth toteutus. http://amforth.sourceforge.net/ Se vaatii vähän yli 8 kiloa flashia, eli vähintään atmega168 tai atmega328. Itse tungin sen atmega128 järjestelmään.
Käänsin sen AVR studio 4 avulla, koska en saanut Avralla (vaatii git version) toimivaa binääriä aikaiseksi.
Resepti:
- Lataa AVR studio 4. Linkit http://i.amniels.com/avr-studio-4-and-5-download-links
- Asenna WinAVR
- Lataa AmForth ja pura lähdekoodi jonnekin välilyönnittömään paikkaan. (Ei Documents and Settings kansion alle vaan esim f:\amforth)
- Kopioi Amforth\appl\template hakemisto appl kansion alle esimerkiksi mun_forth kansioksi.
- Avaa AVR studio.
- Luo assembleri v2 projekti aseta kontrolleri ja ohjelmointilaite kohdilleen. Ja sano, ettet tarvitse uutta tiedostoa.
- Avaa project->assembler options ja Lisää hakemisto amforth\core additional include pathiin
- Tuo projektiin template.asm
- Avaa template.asm tiedostoa.
- Muuta .include “device.asm” muotoon .include “devices/atmega128/device.asm”
- Jos käytössä on ATmega128, lisää edellisen perään .equ MCUSR = MCUCSR
- Arvo fuset kohdilleen. Lähinnä kellotaajuus ja bootloader sizen pitää olla NRWW flashin kokoinen.
- Assemble
- Ja flashaa.
Tämän jälkeen vain sarjakaapeli kiinni, terminaali 9600 8n1 ei kättelyä asetuksin auki.
Virrat päälle ja saat tervehdykseksi:
amforth 4.9 ATmega128
tai jotain vastaavaa. Tästä liittymästä voisi aivan varmasti käyttää, ja olen käyttänytkin AmForthia. Se nyt on vain herkkä backspacen käytölle ja muutenkin herkkä.
Siksi tarvitaan AmForth-shell Tämä on python skripti ja sitä varten tarvitaan python. Windows käyttäjät ovat tässä omillaan ja Linux käyttäjillä se todennäköisesti on. Oman distribuution paketista vain asentamaan.
AmForthin tools hakemistossa on kyseinen ohjelma.
$ python2 ./amforth-shell.py -p /dev/ttyUSB0 -s 9600
|I=Entering amforth interactive interpreter
|I=Updating Controller Type
|I=successfully loaded controller definitions for atmega128
|I=Updating host files
|I= Reading .
(ATmega128)>
Ja nyt voidaan tehdä esimerkiksi seuraava temppu:
(ATmega128)> hex PINA @ PINB @ PINC @ PIND @ . . . .
BC FB FF BF ok
(ATmega128)>
Ja komentamalla words ei löydetäkään mainittuja PINA jne vakioita. Rekisterien muuttaminen osoitteiksi tapahtui sujuvasti amforth-shellin sisällä.
Hyviä apureita, joita kannattaa ajaa järjestelmään ovat bitnames.frt, sekä markerin lisääminen, joka vaatii uudelleen kääntämisen ja flashauksen. http://amforth.sourceforge.net/recipes/undoing-definitions.html
Niin ja ominaisuus. Vaikka virta katkaistaan mikrokontrollerista, sanat eivät katoa. Ne ovat kirjoitettuna flashille.
Kannattaa kuitenkin tutustua huolella tuohon vähäiseen dokumentaatioon, mikä on AmForthin kotisivuilla ja ehkä myös gForthin dokumentaatioon noin yleisesti. Se on hyvin dokumentoitu ympäristö, vaikka tekeekin joitain asioita mielestäni väärin. Antaa hyvän kuvan kieleen ja millaisia sanoja kielestä voi löytyä.
Kysymyksiin yritän vastata ja ongelmiin ohjata helpotusta.