Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Forth, za one sa razlčitim rasporedom vijuga...
#13
Programski jezik Forth -- D R U G I   D E O -- Kontrolne strukture

2.1 Stanje sistema

Forth sistem moze biti ili u stanju interpretiranja ili u stanju kompajliranja. Tekst interpreter ce pozvati kompajler kada naidje na : a kompajler zavrsava definiciju kada naidje na ;
Algoritam tekst interpretera izgleda ovako:
Uzmi jednu rec iz tekstualnog bafera. Proveri da li je u recniku, ako jeste izvrsi je ako je aktivno stanje interpretiranja, kompajliraj ako je aktivan kompajler. Ako tekst nije u recniku onda probaj da je konvertujes u broj.
Ako je konverzija uspesna stavi broj na stek a ako nije prijavi gresku: nedefinisana rec.
Kako sto se vidi tekstualni interpreter je vrlo jednostavan. Ulazni token ( komad teksta delimitiran space-ovima ) moze biti broj ili vec definisana rec. Ostalo je greska.
Kada je interpreter aktivan tekst se parsuje i izvrsava i potom odbacuje. U toku ovog izvrsavanja moguce je takodje i generisati kod kao bocni efekat kao u slucaju definicije varijabli ili konstanti.

Primer:
: invert ( n1 -- n2 )
-1 xor ;


Tekst interpreter pocinje tako sto potrazi adresu : u recniku i izvrsi je. Efekat : je da pokrene kompajler i da definise novu rec "invert" i da kompajlira sve ostale reci koje dolaze u trenutnu definiciju.
Dakle -1 ce biti kompajliran kao "stavi -1 na stek" dok ce xor biti kompajliran kao poziv i potom ; koji ce zaustaviti kompajler, finalizovati definiciju i vratiti sistem u stanje interpretiranja.
Tekst u zagradama je komentar! Zove se stek slika. Pokazkuje stanje steka pre -- i posle izvrsavanja reci. U ovom slucaju rec konzumira jedan element n1 i vraca jedan element n2. Ako ima vise elemenata kao ulaz ili izlaz na steku element koji je skroz desno je vrh steka.

2.2 Specijalne reci

Rec kao : ili variable su definisuce reci. One su uvek napred parsirajuce i definisu nesto u recniku. Dakle za takve reci potreban je uvek tekst koji sledi kao u gorenjem primeru ": invert" su neodvojiva celina.
U slucaju da se naidje na terminator linije (CRLF) odmah iza definisuce reci sistem baca izuzetak. Sve definisuce reci sa napravljene pomocu najosnovnije definisuce reci koja se zove create.
Create pravi novi unos u recnik. Recnik je simbol tebela koji interpreter pretrazuje za svaki token.

Immediate reci se uvek izvrsavaju cak i u modu kompajliranja. U prethondom primeru to je rec ;. Ova rec mora da se izvrsi da bi stopirala kompajler ali takodje ova rec nesto novo kompajlira da bi se zavrsila definicija.
Sta ova rec kompajlira u potpunosti zavisi od toga kako je Forth sistem napravljen.
Sve kontrolne strukture u jeziku Forth su immediate reci koje nesto kompajliraju u memoriju ali takodje se i izvrsavaju i menjaju trenutno stanje sistema.

2.3 if/then if/else/then

Sve kontrolne strukture zahtevaju stanje kompajliranja jer generisu kod. Nije moguce izvrsiti if u stanju interpretiranja i sistem ce baciti izuzetak ako korisnik to pokusa.
U skladu sa postfix notacijom za ovu kontrolnu strukturu prvo je potrebno generisati uslov pre pozivanja reci if. Primer:

variable count

: count-- ( -- )
counter @ 0> if 1 counter +! then ;


count-- ce umanjiti varijablu count za jedan kada god je pozovemo u slucaju da je veca od nule. Ovde izraz "counter @ 0>" ostavlja na vrhu steka true ili false koga konzumira if i zavisno od toga ili izvrsava telo strukture do then ili preskace izvrsavanje tela i samo skace na then.
Sada ovaj primer mozemo unaprediti tako sto cemo napraviti indikator da smo dosli do nule tako da ostatak sistema moze nesto da uradi:

variable count
variable finished


: count-- ( -- )
counter @ 0> if 1 counter +! else true finished ! then ;


Sada je jasno gde se nalazi kod za else blok. Then dakle uvek zavrsava if kontrolnu strukturu i moze se prevoditi "uslov if istinita akcija else neistinita akcija then nastavi dalje".

2.4 begin/until

Ovakva vrsta uslovne petlje je vrlo cesto koriscena. begin oznacava njen pocetak a until zahteva true/false flag na steku pre pozivanja:
Primer:

: ms ( n -- )
begin
ms_delay 1- dup
0= until drop;


dup - gura kopiju prvog elementa vrh na steka. To znaci da su sada prva dva elementa ista. Drop je radi obrunto, skida sa steka jedan element i odbacuje ga.
Ovde ms_delay predstavlja kasnjenje od jedne milisekunde a rec ms prihvata jedan parametar na steku i zove kasnjenje odgovarajuci broj puta. Naravno ovaj kod je suvise naivan jer ne pokriva slucaj 0 ms. Kako bi sam resio ovaj problem?

2.5 begin/while/repeat

Ova kontrolna stuktura je slicna kao begin\until sa razlikom da se uslov prihvata ranije tj pre nogo sto se telo petlje izvrsi. Na ovaj nacin izbegava se problem od 0 ms.
Primer:

: ms ( n -- )
begin
dup
while
ms_delay 1-
repeat drop ;

Ako je parametar 0 while ce ga skinuti sa steka i preneti izvrsavanje iza repeat a u usprotnom ako je parametar razlicit od nule while blok ce bit izvrsen.
Odmah je jasno da sve kontrolne reci koje odlucuju kako se se izvrsiti kontolna struktura uzimaju parametar sa steka ( if, until, while ...) zato je vecini potreban dup ispred njih. drop je tu da ispostuje stek sliku i da ostavi stek bez prosledjenog parametra.

2.6 do/loop

Ovo kontolna stuktura je vrlo slicna for petlji u drugim jezicima. Zahteva parametre za opseg na steku pre do dela, primer:

: test ( -- )
10 0 do i . loop ;


Rezultat izvrsavanja ove definicija je: 0 1 2 3 4 5 6 7 8 9. do konzumira 10 i 0 i koristi ih za brojanje. Trenutni indeks se moze staviti na stek pomocu reci "i".
Kao sto se vidi opseg je [0,10) kao i u drugim jezicima. Da bi se izaslo iz do/loop petlje pre vremena MORA se koristiti rec "leave". Leave pocisti okruzenje koje je podeseno za brzo izvrsavanje loop petlje. U slucaju da se to ne obavi sistem moze da padne!
Drugi nacin da se napusti petlja je: "unloop exit". Ova fraza omogucava da se odmah izadje iz definicije bez da se nastavlja izvrsavanje od loop. Exit se ponasa slicno kao return u drugim jezicima.

Primer:
: test ( -- )
10 0 do i . i 5 = if leave then loop ;

Test sada stampa brojeve od 0 do 5.
Postoji jos varijacija na temu vezanih za do/loop kao sto su: ?do/loop ili do/+loop koaje prepustam citaocu da istrazi.
Kraj drugog dela.

Nadam se da je nekom ovo interesantno i korisno. Ako ne, kazite ljudi, da ne trosim tastaturu Smile

Pozdrav,
M.
Reply


Messages In This Thread
RE: Forth, za one sa razlčitim rasporedom vijuga... - by mveselic - 08-10-2015, 03:03 PM

Forum Jump:


Users browsing this thread: 2 Guest(s)