Moc jsem ted kdyz jsem byl doma (v pokoji) neprogramoval. Jen jsem se v praci pri myti nadobi (vanoce a novy rok jsou hrozne) zamyslel nad tim pridanim DUP a DROP mezi tokenova pravidla.
Strasne me to pripomina fyziku, kde do nekterych kvantovych jevu vstupuji virtualni castice. Par castice a anticastice. Neco udelaji a pak zaniknou, pokud se neco nestane a nezacnou byt realne.
To bych pak mohl nazvat ty tokeny __TOKEN_DUP a __TOKEN_DROP virtualnimi tokeny... .)
Token __TOKEN_DUP se vaze k "realnemu" __TOKEN_STORE a vznika __TOKEN_DUP_STORE
a pak se na frontu jeste prida virtualni __TOKEN_DROP, ktery pokud se na nic nenavaze v
(druhem pruchodu) tokenovych pravidlech* tak bude nakonec realny, jinak se spoji s nasledujicim "realnym" __TOKEN_PUSHS do __TOKEN_DROP_PUSHS a samostane zanikne.
M*dat! Ctu to ted po sobe a moc smyslu to nedava i kdyz jsem myslel ze to pisi jednoduse. Asi prilis dlouha souveti, nebo je lepsi po sobe nic necist? .)
Ok zeditovano a ted jeste jinak:
Pridavam token __TOKEN_PUSHS.
V tokenovych pravidlech hledam zda se nepoji s necim pred nim. Uz pri pridani, ale jen proto abych kdyz zjistim ze pred nim bylo __TOKEN_PUSH_STORE tak to __TOKEN_PUSHS_STORE zmenim na __TOKEN_DUP_PUSHS_STORE a jeste za to hodim __TOKEN_DROP a az pak pridam do fronty tokenu __TOKEN_PUSHS s kterym nic nedelam.*Vysvetleni k tem pravidlum: Proste mam pravdila ktera se vytvareji hned kdyz na frontu se prida novy token.
Vetsinou se to jen koukne co bylo pred nim (ted se uz umi koukat v podstate do neomezene hloubky) a bud se to spoji nebo se vytvori ulozi novy token. K tomu jsou ruzna pomocna makra pro ulehceni prace, odkazujici se relativne k poslednimu ulozenemu makru. Vcetne smazani posledniho makra.
Ve chvili kdy se zavola makro ktere z te fronty tokenu zacne generovat nazvy maker, ktere obsahuji uz samostatny kod tak se udela nova promenna (makro), ktera zkopiruje ukazatel posledniho makra a ukazatel se vynuluje (protoze pak mohu zase pouzit vsechny pomocne makra) a projdou se ty makra jeste jednou. Jen uz nemuzu mazat makra, ani pridavat nova. Misto mazani jde jen udelat prazne makro.
Hlavni vyhoda druheho pruchodu je, ze se tam mohou aktivovat pravidla mensi priority. Nekdy se stane ze se proste na nejakou kombinaci tokenu da provest vice pravidel a vytvorit jine komba slov. Ale nektere jsou mnohem vice efektivni. Vetsinou je to tak, ze za daty (PUSHS) je nejake slovo ktere je pouziva jako parametry a to vyrazne zlepsi kod. Pokud to slovo necha nejaka data, protoze jich nepotrebuje tolik, nebo za PUSHS nic do kombinace neni, tak stale se dokaze PUSHS navazat na slovo co bylo pred nim. Jako DROP, DUP atd. A mit to vse v v pravidlech kdy se token pridava tak to nasobne zvysuje pocet pravidel. Kombinace spojeni s PUSHS pred tokenem a kombinace spojeni PUSHS po tokenu.
Cely je to delany aby s co nejmene prace jsem udelal nejlepsi vysledek. A proste jsem jen pridaval dalsi funkcionalitu. V cecku bych to delal jinak, pomaleji ale snadneji na pochopeni a bez rizik vedlejsich ucinku.
Tak a ted proc jsem to znovu vysvetloval.
To STORE -> DUP_STORE + DROP se da udelat i v tech tokenovych pravidlech na konci.
Kdyz najde ze za STORE je PUSHS tak to muze zmenit na DUP_STORE a DROP_PUSHS. Pocet tokenu zustane stejny. Zadne "virtualni" tokeny nevnikaji. K prvnimu tokenu neco pridam a k druhemu pridam opak toho prvniho. V relanem kodu u obou jen neco umazu. A vysledne tokeny jsou pak "neutralni" k pohybu zasobniku.
Pak mi doslo ze, ale ty "virtualni" tokeny jsou takovy pekny pojivo a pokud najdu dalsi slova co nejsou "neutralni" k pohybu zasobniku tak si zase nasobne usetrim pocet pravidel.
Pro stranu X+PUSHS jsem nasel HSTORE a CSTORE, co je to same co STORE jen s H nebo L registrem misto HL. A pak EMIT, co vezme 8 bitu z TOS a vytiskne ho. Dale TYPE_I, co vemze TOS a interpretuje ho jako ukazatel na retezec, ktery je ukoncen tisknutelnym znakem s nastavenym 7. bitem na true.
Pro stranu na ktere je DROP+PUSHS jsem jeste nehledal, ale staci jedno slovo DROP+neco a musel bych zdojnasobit pocet pravidel psat to jen v pravidlech "druheho" radu.
Pak jsem udelal nejake nove chyby... .) protoze jsem nedomyslel vse do dusledku.
U slova EMIT jsem pro snadnost rovnou vytvoril dva tokeny __TOKEN_DUP_EMIT a __TOKEN_DROP. Abych nemusel delat zadna tokenova pravidla. __ASM_TOKEN_EMIT jsem nemazal, protoze ho neco muze volat. Fungovalo to podle ocekavani
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'EMIT'
ld A, L ; 1:4 emit Pollutes: AF, AF', DE', BC'
rst 0x10 ; 1:11 emit with 48K ROM in, this will print char in A
ex DE, HL ; 1:4 emit
pop DE ; 1:10 emit ( a -- )
; seconds: 0 ;[ 4:29]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'EMIT PUSH(200)'
ld A, L ; 1:4 emit Pollutes: AF, AF', DE', BC'
rst 0x10 ; 1:11 emit with 48K ROM in, this will print char in A
ld HL, 200 ; 3:10 emit 200
; seconds: 0 ;[ 5:25]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$
Jen jsem uplne zapomel ze __TOKEN_EMIT muze mit a taky ma vlastni pravidla. Ze se snazi navazat s DUP a PUSH do DUP_EMIT a PUSH_EMIT.
Jenze se uz nenavaze, protoze __TOKEN_EMIT nevznika, vznika jen __TOKEN_DUP_EMIT nasledovany tokenem __TOKEN_DROP.
Takze to chce zrusit vznik dvou tokenu a pridat pravidlo v tokenech a nebo upravit pravidla v tokenech.
Vypada to ze druha varianta je asi spravne...
Protoze i to pravidlo s PUSH_STORE se aktivuje jen pokud vkladam PUSHS a pred nim je PUSH_STORE, tak se to zmeni na DUP_PUSH_STORE, prida DROP a teprve pak ulozi samostatne PUSHS. Ktere se bud cele navaze na pristi token, nebo v druhem pruchodu spoji s DROP.
Pokud teda najdu slovo, co dokaze efektivne zrusit DROP, tak bych musel taky zdvojnasobit pocet pravidel pro kazde slovo ktere konci jako "drop".
Asi bych mel ted vic myslet a hledat nez neco zacnu... hmm... .)) Nebo nedomyslet a pockat jestli me zase neco nedojde casem az me zacne nekde tlacit bota. .)))
Mozna je problem s tim ze ty slova jako PUSH_STORE a EMIT proste nejsou pro moji implementaci navrzena dobre a ja bych spis potreboval slova, ktera nenici vstup, takze jsou "neutralni" na zasobniku a slova jako PUSH_STORE a EMIT rozdelit na DUP_STORE a DUP_EMIT a DROP. Pro me jsou STORE a EMIT jakoby spatne navrzena kombo slova a pak vysledek neni efektivni. Nejsou to nedelitelne celky. A mel jsem se na to tak divat uz od pocatku. Ale koho by to napadlo.
To znamena ze bych mel jeste pridat kombinace slov co nici jak TOS tak NOS. Presneji co maji pohyb na zasobniku "-2" a pak slova co pridaji aspon "+2". Jako STORE + PUSHS --> _2DUP STORE _2DROP PUSHS
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'STORE PUSH(200,300)'
;[5:40] ! ( x addr -- )
ld (HL),E ; 1:7 !
inc HL ; 1:6 !
ld (HL),D ; 1:7 !
pop HL ; 1:10 !
pop DE ; 1:10 !
;[8:42] 200 300 ( -- 200 300 )
push DE ; 1:11 200 300
push HL ; 1:11 200 300
ld DE, 0x00C8 ; 3:10 200 300
ld HL, 0x012C ; 3:10 200 300
; seconds: 0 ;[13:82]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2DUP STORE _2DROP PUSH(200,300)'
;[4:26] 2dup ! _2dup_store ( x addr -- x addr )
ld (HL),E ; 1:7 2dup ! _2dup_store
inc HL ; 1:6 2dup ! _2dup_store
ld (HL),D ; 1:7 2dup ! _2dup_store
dec HL ; 1:6 2dup ! _2dup_store
;[6:20] 2drop 200 300 ( -- 200 300 )
ld DE, 0x00C8 ; 3:10 2drop 200 300
ld HL, 0x012C ; 3:10 2drop 200 300
; seconds: 0 ;[10:46]
Hmm... tady _2DUP STORE se snazi nezmenit TOS a vraci ho pomoci "dec HL" do puvodni hodnoty.
Mozna bych mel vytvorit... jine propojeni co ma univerzalni jmeno jako _2DROP ale konkretni kod... Ne! Proste jen rozdelit puvodni kod STORE na SKORO_2DUP_STORE (STACK_NEUTRAL_STORE) a 2DROP. Chce to nejaky rozumny nazev. Dulezity je ten pohyb zasobniku.
Nejak me to nemysli... nebo je to na me uz moc komplikovane.
.....Aaaa tohle bude jeste zajimave. Nic koncim se spamem, puvodne jsem nechtel nakonec ani tohle cele psat. .)))
PS: Pekne ze i kdyz nasleduje jedine PUSH tak se to stale pekne spoji kdyz tam pridame ty "virtualni" tokeny.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'STORE PUSH(300)'
;[5:40] ! ( x addr -- )
ld (HL),E ; 1:7 !
inc HL ; 1:6 !
ld (HL),D ; 1:7 !
pop HL ; 1:10 !
pop DE ; 1:10 !
push DE ; 1:11 300
ex DE, HL ; 1:4 300
ld HL, 300 ; 3:10 300
; seconds: 0 ;[10:65]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2DUP STORE _2DROP PUSH(300)'
;[4:26] 2dup ! _2dup_store ( x addr -- x addr )
ld (HL),E ; 1:7 2dup ! _2dup_store
inc HL ; 1:6 2dup ! _2dup_store
ld (HL),D ; 1:7 2dup ! _2dup_store
dec HL ; 1:6 2dup ! _2dup_store
pop DE ; 1:10 2drop 300
ld HL, 300 ; 3:10 2drop 300
; seconds: 0 ;[ 8:46]
PPS: Jinak jeste k tem tokenovym pravidlum. DUP + EMIT je snazsi delat (naleza se v case co se pridava EMIT) nez DUP + DUP_EMIT + DROP (nalezne to az DROP). Musim se divat o hloubku vice, ale zase tak dramaticky rozdil to neni.