Vojče,
To mu dođe kao rasprava o tome da li je bolja "Zvezda" ili "Partizan". Oba načina pisanja imaju svoje mane i prednosti, tj. prednosti nekog od njih su vezane za problematiku koja se rešava.
Za razliku od C, kvalitet napisanog u Forth daleko više zavisi od veštine programera i njegove dovitljivosti. Kod C je tu manja razlika.
Kod sabiranja dva broja u C, od arhitekture MCU i kompajlera zavisi da li će biti optimizovan bliže ili dalje brzini ASM. Kod Forth je to tik iznad ASM sa vrlo poznatom brzinom događaja. Ne tvrdim da se sabiranje dva broja ne može brže izvršiti u C nego u forth, posebno na nepredisponiranoj arhitekturi (jer se najčešće kod običnih MCU za Forth stack koristi i pravi stack, ali takođe i RAM), ali na žalost, programiranje se (kao što odlično znaš i sam) ne sastoji samo od sabiranja dva broja. Uostalom, u oba načina pisanja (u C jeziku i u Forth metajeziku) mogu se kritične stvari napisati direktno u ASM, te se tu ne može dati prednost ni jednom od njih. Jednostavno na taj način će se dobiti isto.
Čim se odmakne malo dalje od led-blink, gde stvari postaju složenije, uz veću veštinu programera, stvari u Forth mogu postati dosta brže i moćnije u određenim segmentima programiranja.
Pre nego što je Mlađa napravio pravi stack procesor Frog1 (mislim da ima sada već Frog4 ili možda Frog5, pitaću ga), radili smo sa Philips LPC2136 ARM7 u koji je bio implementiran Forth. Čim problem bude samo malo složeniji od najprostijih operacija, Forth je (sa vrlo veštim Mlađom u pozadini) pokazivao popriličnu moć u odnosu na C.
Nisam toliko duboko u tome da bih eksplicitno tvrdio nešto oko mikro detalja koji čine te prednosti, ali mislim da velika snaga Forth, osim interaktivnog rada koji omogućava neuporedivo brži i direktniji - trenutni test koda, počiva na maltene neograničenom broju i magnitudi povratnih vrednosti iz jedne REČI (nalik funkciji u C, za one koji nisu radili sa Forth, ne za tebe jer si radio u njemu).
C može imati samo jednu povratnu vrednost, što ga malo linearizuje i oslabljuje mogućnost veštih prečica u pisanju.
Postaviću ovde jedno parčence Mlađinog koda, pisanog u Forth, koji je bio implementiran na ARM7 (emulirana stack mašina), gde se na primer neki korisnički meni rešava sa tako elegantnim budućim korišćenjem, na nekoj mašini slične namene, da ti pamet stane!
U C-u bi bila potrebna opaka "kobasica" koda za tako efikasan konačni način korišćenja, ili pozadinske biblioteke sa gomilčinom funkcija koje "pojedu" vrlo masivan memorijski prostor.
A znam da je ta vrlo složena mašina napisana cela u 10,5 kilobajta svega, sa sve tih jako udobnih menija. Pokrenuli smo je 2007. i naravno da znam koliko je resursa potrošeno.
Evo jednog komada Mlađinog koda u Forth, pa ću naknadno objasniti šta to radi.
Ovo je neki korisnički meni zadavanja parametara, gde se kao tastatura koristi pet tastera. Kao skrol tasteri se koriste "gore" i "dole", dok kao + i - tasteri "desno" i "levo" i jedan multifunkcionalni u sredini, nazovimo ga "srednji". Tim srednjim se ulazi u parmetre, potom istim napušta i automatski memoriše.
Struktura drži: parametre i njihove lokacije na osnovu teksta, up-down limite, smerove tastera, stil ispisivanja cifara (pozicija zapete i float - no float) .
Ono što je iza nekih linija koda, kao < /neki_tekst > su komentari gde je zapisano neko poslednje stanje auto tjuninga višestrukog PID za termoregulaciju na 5 grejnih zona.
Ono što briljira je da kada je potrebno napisati za neku drugu mašinu set parametara, dovoljno je napisati potrebnim redom i potrebnu količinu ovih < item text" tekst, broj, broj, tekst"> i automatski će biti definisano:
-potreban broj memorijskih lokacija,
-potrebnih veličina,
-njihov redosled,
-float.point ili ne,
-stil ispisivanja,
-down_limit i up_limit tih vrednosti,
-tekst koji ispisuje jedinice u kojima se izražava broj,
- sva potrebna povezanost sa automatskim memorisanjem i usisavanjem parametara iz EEPROM,
-sva povezanost sa tasterima koji inkrementuju ili dekrementuju konkretnu vrednost,
-sva povezanost sa displejem,
- i tako dalje i tako dalje...
Pokušaj tako elegantno u C.
Naravno, Mlađa je jedan, ali moraš priznati da će se to veoma teško napraviti u 10,5 KB koda u C.
Pri čemu treba da znaš da je u toj količini memorije cela mašina sa 4 merne letve, 5 PID regulatora, 10 ADC kanala, 8 servoventila, oko 30-tak diskretnih ventila i oko 15-tak diskretnih ulaza.
Kompletan kontrolni algoritam čitave mašine (koja vrlo složeno radi) izgleda ovako (u celih 356 linija koda):
Kompaktnost je savršena i za neku drugu sličnu mašinu se veoma malo toga menja.
Tako to izgleda kada se piše u Forth i kada to radi Mlađa (2007. a može se zamisliti šta sada radi jer i dalje koristi Forth).
Pozdrav Vojče
P.S.
Znam da se Mlađa neće ljutiti što sam postavio deo koda koji je u njegovom intelektualnom vlasništvu. Razumeće da je u edukativne svrhe.
To mu dođe kao rasprava o tome da li je bolja "Zvezda" ili "Partizan". Oba načina pisanja imaju svoje mane i prednosti, tj. prednosti nekog od njih su vezane za problematiku koja se rešava.
Za razliku od C, kvalitet napisanog u Forth daleko više zavisi od veštine programera i njegove dovitljivosti. Kod C je tu manja razlika.
Kod sabiranja dva broja u C, od arhitekture MCU i kompajlera zavisi da li će biti optimizovan bliže ili dalje brzini ASM. Kod Forth je to tik iznad ASM sa vrlo poznatom brzinom događaja. Ne tvrdim da se sabiranje dva broja ne može brže izvršiti u C nego u forth, posebno na nepredisponiranoj arhitekturi (jer se najčešće kod običnih MCU za Forth stack koristi i pravi stack, ali takođe i RAM), ali na žalost, programiranje se (kao što odlično znaš i sam) ne sastoji samo od sabiranja dva broja. Uostalom, u oba načina pisanja (u C jeziku i u Forth metajeziku) mogu se kritične stvari napisati direktno u ASM, te se tu ne može dati prednost ni jednom od njih. Jednostavno na taj način će se dobiti isto.
Čim se odmakne malo dalje od led-blink, gde stvari postaju složenije, uz veću veštinu programera, stvari u Forth mogu postati dosta brže i moćnije u određenim segmentima programiranja.
Pre nego što je Mlađa napravio pravi stack procesor Frog1 (mislim da ima sada već Frog4 ili možda Frog5, pitaću ga), radili smo sa Philips LPC2136 ARM7 u koji je bio implementiran Forth. Čim problem bude samo malo složeniji od najprostijih operacija, Forth je (sa vrlo veštim Mlađom u pozadini) pokazivao popriličnu moć u odnosu na C.
Nisam toliko duboko u tome da bih eksplicitno tvrdio nešto oko mikro detalja koji čine te prednosti, ali mislim da velika snaga Forth, osim interaktivnog rada koji omogućava neuporedivo brži i direktniji - trenutni test koda, počiva na maltene neograničenom broju i magnitudi povratnih vrednosti iz jedne REČI (nalik funkciji u C, za one koji nisu radili sa Forth, ne za tebe jer si radio u njemu).
C može imati samo jednu povratnu vrednost, što ga malo linearizuje i oslabljuje mogućnost veštih prečica u pisanju.
Postaviću ovde jedno parčence Mlađinog koda, pisanog u Forth, koji je bio implementiran na ARM7 (emulirana stack mašina), gde se na primer neki korisnički meni rešava sa tako elegantnim budućim korišćenjem, na nekoj mašini slične namene, da ti pamet stane!
U C-u bi bila potrebna opaka "kobasica" koda za tako efikasan konačni način korišćenja, ili pozadinske biblioteke sa gomilčinom funkcija koje "pojedu" vrlo masivan memorijski prostor.
A znam da je ta vrlo složena mašina napisana cela u 10,5 kilobajta svega, sa sve tih jako udobnih menija. Pokrenuli smo je 2007. i naravno da znam koliko je resursa potrošeno.
Evo jednog komada Mlađinog koda u Forth, pa ću naknadno objasniti šta to radi.
Code:
parmenu[
item text" Temperatura 1,400,øC" \ 200
item text" K1,10.00" \ 21.12
item text" I1,1000.0" \ 124.4
item text" D1,100.0" \ 31.4
item text" Temperatura 2,400,øC" \ 195
item text" K2,10.00" \ 4.13
item text" I2,1000.0" \ 1304.9
item text" D2,100.0" \ 329.6
item text" Temperatura 3,400,øC" \ 192
item text" K3,10.00" \ 4.13
item text" I3,1000.0" \ 1304.9
item text" D3,100.0" \ 329.6
item text" Temperatura 4,400,øC" \ 190
item text" K4,10.00" \ 4.13
item text" I4,1000.0" \ 1304.9
item text" D4,100.0" \ 329.6
item text" Temperatura 5,400,øC" \ 187
item text" K5,10.00" \ 4.13
item text" I5,1000.0" \ 1304.9
item text" D5,100.0" \ 329.6
item text" Start auto-podesavanja PID-a,1" \ 0
item text" Kanal auto-podesavanja PID-a,3" \ 0
item text" Snaga pri auto-podesavanju,100,%" \ 80
]parmenu tparams
Ovo je neki korisnički meni zadavanja parametara, gde se kao tastatura koristi pet tastera. Kao skrol tasteri se koriste "gore" i "dole", dok kao + i - tasteri "desno" i "levo" i jedan multifunkcionalni u sredini, nazovimo ga "srednji". Tim srednjim se ulazi u parmetre, potom istim napušta i automatski memoriše.
Struktura drži: parametre i njihove lokacije na osnovu teksta, up-down limite, smerove tastera, stil ispisivanja cifara (pozicija zapete i float - no float) .
Ono što je iza nekih linija koda, kao < /neki_tekst > su komentari gde je zapisano neko poslednje stanje auto tjuninga višestrukog PID za termoregulaciju na 5 grejnih zona.
Ono što briljira je da kada je potrebno napisati za neku drugu mašinu set parametara, dovoljno je napisati potrebnim redom i potrebnu količinu ovih < item text" tekst, broj, broj, tekst"> i automatski će biti definisano:
-potreban broj memorijskih lokacija,
-potrebnih veličina,
-njihov redosled,
-float.point ili ne,
-stil ispisivanja,
-down_limit i up_limit tih vrednosti,
-tekst koji ispisuje jedinice u kojima se izražava broj,
- sva potrebna povezanost sa automatskim memorisanjem i usisavanjem parametara iz EEPROM,
-sva povezanost sa tasterima koji inkrementuju ili dekrementuju konkretnu vrednost,
-sva povezanost sa displejem,
- i tako dalje i tako dalje...
Pokušaj tako elegantno u C.
Naravno, Mlađa je jedan, ali moraš priznati da će se to veoma teško napraviti u 10,5 KB koda u C.
Pri čemu treba da znaš da je u toj količini memorije cela mašina sa 4 merne letve, 5 PID regulatora, 10 ADC kanala, 8 servoventila, oko 30-tak diskretnih ventila i oko 15-tak diskretnih ulaza.
Kompletan kontrolni algoritam čitave mašine (koja vrlo složeno radi) izgleda ovako (u celih 356 linija koda):
Code:
\ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
\ º Kontrolni algoritam za brizgaljku tipa Roveta M.Veselic 13Mar07 º
\ ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
\ Uredjaj montiran 27mar07
\
\ ÉÍÍÍÍÍÍÍÍÍÍÍ»
\ º Parametri º
\ ÈÍÍÍÍÍÍÍÍÍÍͼ
parmenu[
item text" Vreme odlaganja briz.,30.0,sek" \ .5
item text" Pritisak brizganja,100,%" \ 80
item text" Vreme ekstrudiranja,100,sek" \ 0
item text" Brzina brizganja 1,100,%" \ 70
item text" Pozicija brizganja 2,320,mm" \ 140
item text" Brzina brizganja 2,100,%" \ 70
item text" Pozicija brizganja 3,320,mm" \ 120
item text" Brzina brizganja 3,100,%" \ 70
item text" Sigurnosno vreme brizganja,100,sek" \ 20
item text" Pozicija naknadnog p.,320,mm" \ 110
item text" Naknadni pritisak,100,%" \ 50
item text" Vreme naknadnog p.,100,sek" \ 3
]parmenu par-briz
parmenu[
item text" Pozicija doze,320,mm" \ 160
item text" Brzina doziranja,60,%" \ 60
item text" Pritisak doziranja,100,%" \ 20
item text" Stojeci pritisak,100,%" \ 0
item text" Pozicija vakuuma,320,mm" \ 175
item text" Pritisak vakuuma,100,%" \ 50
item text" Sigurnosno vreme doziranja,300,sek" \ 100
]parmenu par-doze
parmenu[
item text" Vreme odvajanja agregata,1.0,sek" \ .5
item text" Pritisak odvajanja agregata,50,%" \ 15
]parmenu par-agr-naz
parmenu[
item text" Pritisak prilazenja agregata,50,%" \ 2
]parmenu par-agr-nap
parmenu[
item text" Upotreba: 0=ne 1=da,1"
item text" Pritisak levih kernova,100,%"
item text" Brzina levih kernova,100,%"
item text" Sklapanje: 0=pre 1=posle zatv.,1"
item text" Rasklapanje: 0=pre 1=posle otv.,1"
]parmenu par-ker-left
parmenu[
item text" Upotreba: 0=ne 1=da,1"
item text" Pritisak desnih kernova,100,%"
item text" Brzina desnih kernova,100,%"
item text" Sklapanje: 0=pre 1=posle zatv.,1"
item text" Rasklapanje: 0=pre 1=posle otv.,1"
]parmenu par-ker-right
parmenu[
item text" Pozicija izb. napred,300,mm" \ 180
item text" Pritisak izb. napred,100,%" \ 2
item text" Broj izbijanja,5" \ 2
]parmenu par-izb-right
parmenu[
item text" Pozicija izb. nazad,300,mm" \ 100
item text" Pritisak izb. nazad,100,%" \ 10
item text" Vreme vazduha 2,10,sek" \ 2
item text" Sigurnosno vreme izbijanja,100,sek" \ 10
]parmenu par-izb-left
parmenu[
item text" Pritisak odbravljivanja,100,%" \ 50
item text" Brzina otvaranja 1,50,%" \ 27
item text" Pozicija otvaranja 2,750" \ 200
item text" Brzina otvaranja 2,50,%" \ 35
item text" Pozicija otvaranja 3,750" \ 500
item text" Brzina otvaranja 3,50,%" \ 23
item text" Pozicija max otvoren,750" \ 600
item text" Sigurnosno vreme otvaranja,100,sek" \ 15
item text" Vreme pauze,10,sek" \ 2
item text" Vreme hladjenja,300,sek" \ 10
item text" Br. ciklusa do podmazivanja,1000" \ 10
]parmenu par-alat-left
parmenu[
item text" Pritisak hoda alata,100,%" \ 35
item text" Brzina zatvaranja 1,50,%" \ 25
item text" Pozicija zatvaranja 2,750" \ 450
item text" Brzina zatvaranja 2,50,%" \ 30
item text" Pozicija zatvaranja 3,750" \ 250
item text" Brzina zatvaranja 3,50,%" \ 22
item text" Sigurnosno vreme zatvaranja,100,sek" \ 15
item text" Pozicija osiguranja,750" \ 200
item text" Pritisak osiguranja,50,%" \ 25
item text" Brzina osiguranja,50,%" \ 24
item text" Sigurnosno vreme osiguranja,100,sek" \ 10
item text" Pozicija bravljenja,750" \ 125
item text" Pritisak bravljenja,100,%" \ 60
item text" Brzina bravljenja,50,%" \ 25
item text" Pozicija zabravljen,100" \ 28
]parmenu par-alat-right
parmenu[
item text" Pritisak podesavanja alata,100,%" \ 50
item text" Brzina podesavanja alata,50,%" \ 20
item text" Pritisak podesavanja sneke,100,%" \ 80
item text" Brzina podesavanja sneke,100,%" \ 70
item text" Pritisak podesavanja izb.,50,%" \ 20
]parmenu par-pod
parmenu[
item text" Temperatura 1,400,øC" \ 200
item text" K1,10.00" \ 21.12
item text" I1,1000.0" \ 124.4
item text" D1,100.0" \ 31.4
item text" Temperatura 2,400,øC" \ 195
item text" K2,10.00" \ 4.13
item text" I2,1000.0" \ 1304.9
item text" D2,100.0" \ 329.6
item text" Temperatura 3,400,øC" \ 192
item text" K3,10.00" \ 4.13
item text" I3,1000.0" \ 1304.9
item text" D3,100.0" \ 329.6
item text" Temperatura 4,400,øC" \ 190
item text" K4,10.00" \ 4.13
item text" I4,1000.0" \ 1304.9
item text" D4,100.0" \ 329.6
item text" Temperatura 5,400,øC" \ 187
item text" K5,10.00" \ 4.13
item text" I5,1000.0" \ 1304.9
item text" D5,100.0" \ 329.6
item text" Start auto-podesavanja PID-a,1" \ 0
item text" Kanal auto-podesavanja PID-a,3" \ 0
item text" Snaga pri auto-podesavanju,100,%" \ 80
]parmenu tparams
menu[
action par-briz text" <-sneka/brizganje ->"
action par-doze text" <-sneka/doziranje ->"
]menu m-sneke
menu[
action par-agr-nap text" <-agregat/napred ->"
action par-agr-naz text" <-agregat/nazad ->"
]menu m-agreg
menu[
action par-ker-left text" <-kern/levi ->"
action par-ker-right text" <-kern/desni ->"
]menu m-kerna
menu[
action par-izb-right text" <-izbijaci/napred ->"
action par-izb-left text" <-izbijaci/nazad ->"
]menu m-izbij
menu[
action par-alat-right text" <-alat/zatvaranje ->"
action par-alat-left text" <-alat/otvaranje ->"
]menu m-alata
menu[
action m-sneke text" <-Param. sneke ->"
action m-agreg text" <-Param. agregata ->"
action m-kerna text" <-Param. kernova ->"
action m-izbij text" <-Param. izbijaca ->"
action m-alata text" <-Param. alata ->"
action par-pod text" <-Param. meh. pod. ->"
]menu par-menu
endmenu[
action mp-korpa text" <-L Korpa D->"
action mp-alat text" <-L Hod alata D->"
action mp-brav text" <-L Bravljenje D->"
action mp-agr text" <-L Hod agregata D->"
action mp-b/d text" <-Brizgaj Doziraj->"
action mp-vak text" Vakuum->"
action mp-span text" Dozvola spanovanja->"
action mp-cp text" Podmazi->"
action mp-grej text" <-Is Grejanje Uk->"
action mp-vazd text" Vazduh->"
action mp-izb text" <-L Hod izbijaca D->"
]endmenu mpod
endmenu[
action mp-korpa text" <-L Korpa D->"
action rr-alat text" <-L Hod alata D->"
action rr-agr text" <-L Hod agreg. D->"
action rr-b/d text" <-Brizgaj Doziraj->"
action rr-izb text" Izbij->"
]endmenu mrucno
\ ---------------------------------------------------- Auto RAD
variable parent-adr variable brojkom variable cbroj
: zatvori-korpu
int? if inputs then
auto-rad @ korpa? and if exit then
0 #6 lcdxy s" Korpa!->" lcdtype
begin
pause
esc-key? if gesc throw then
right-key?
until
1 korpa outputs
['] timeout #10 [s] s-tmr
begin
pause int? if inputs then
esc-key? if gesc throw then
timeout? if gkorp throw then
korpa?
until p-tmr
#6 lcdclrn
;
: prikazikom
#0 #5 lcdxy s" Br.kom.=" lcdtype brojkom @ 76h lcd.
;
: izbrojkom
brojkom @ #100000 >= if 0 brojkom ! else 1 brojkom +! prikazikom then
;
: ohladi
['] timeout vr.hladj @ [s] s-tmr
begin
pause
esc-key? if gesc throw then
timeout?
until p-tmr
;
: izbijaj
n.izb @ 0= if exit then
n.izb @ 0 do izbij loop
;
: pauziraj
pauto-rad @ if exit then
['] timeout vr.pauze @ [s] s-tmr
begin
pause
esc-key? if gesc throw then
timeout?
until p-tmr
;
: podmazi
cbroj @ br.cp @ < if 1 cbroj +! exit then
0 cbroj ! 1 cpodmazi outputs
['] timeout #10 [s] s-tmr
begin
pause int? if inputs then
esc-key? if gesc throw then
timeout? if gcp throw then
ppodmaz?
until p-tmr
['] timeout #5 [s] s-tmr
begin
esc-key? if gesc throw then
timeout?
until p-tmr
0 cpodmazi outputs
;
: auto-seq ( -- )
zatvori-korpu
alat-pos po.motv.al @ < if galat throw then
prikazikom
right-alat
left-agr
#1000 ms
rrbriz
#500 ms
rrdozi
right-agr
ohladi
left-alat
pauto-rad @ if 0 korpa outputs then
izbijaj
izbrojkom
pauziraj
podmazi
;
: disp-pa ( -- )
menuclr #0 #7 lcdxy s" Poluautomatski rad" lcdtype
;
: disp-a ( -- )
menuclr #0 #7 lcdxy s" Automatski rad" lcdtype
;
: pauto ( key parent-adress -- )
nip parent-adr ! true pauto-rad !
disp-pa wreleased #5 lcdclrn
begin
['] auto-seq catch do-errors pauto-rad @ not
until
parent-adr @ menu-repaint
;
: auto ( key parent-adress -- )
nip parent-adr ! true auto-rad !
disp-a wreleased #5 lcdclrn
begin
['] auto-seq catch do-errors auto-rad @ not
until
parent-adr @ menu-repaint
;
menu[
action par-menu text" Parametri masine ->"
action tparams text" Parametri t. reg. ->"
action mpod text" Mehanicka podes. ->"
action mrucno text" Rucni rad ->"
action pauto text" Poluauto. rad ->"
action auto text" Automatski rad ->"
]menu menu
task ui
: startui
0 0 menu restore-params spbinit outputs inputs pwminit 0 pwm1 0 pwm2 0 pwm3 0 pwm4
ui start: begin kp dup nokey <> if 0 menu else drop then again
;
\ -------------------------------------------------------------------------------- APID
variable at-active variable oldtb
: ats ( -- )
at-active @ not if true at-active ! pd @ ptemp pautoch @ atinit mpwminit then
;
: atp ( -- )
at-active @ if false at-active ! atcls then
;
: pidinit ( -- )
ptemp par> pautop @ 0<> if ats else atp then
;
: do-at ( -- )
newch @ auto-ch @ =
if newch @ results f@ auto-tune 0<>
if false at-active ! atcls 0 pautop ! then newch @ pwmouts !
then
;
: newsample? ( -- t|f )
newres @ if newch @ channels < if false newres ! true then
else false
then
;
: report ( -- )
oldtb @ #8 = 10tb @ 9 = and if pidinit check-h then
10tb @ oldtb !
;
task pid
: startpid ( -- )
pid start:
decimal pidinit 4 places !
begin
negrej @ not if
newsample? if at-active @ if do-at else pidctr then then
report
else mpwminit then
pause
again
;
: run startad startui startpid startpots ;
\ ' run turnkey
run
Kompaktnost je savršena i za neku drugu sličnu mašinu se veoma malo toga menja.
Tako to izgleda kada se piše u Forth i kada to radi Mlađa (2007. a može se zamisliti šta sada radi jer i dalje koristi Forth).
Pozdrav Vojče
P.S.
Znam da se Mlađa neće ljutiti što sam postavio deo koda koji je u njegovom intelektualnom vlasništvu. Razumeće da je u edukativne svrhe.