OldComp.cz

Komunitní diskuzní fórum pro fanoušky historických počítačů


Právě je 27.04.2024, 08:58

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 598 ]  Přejít na stránku Předchozí  1 ... 34, 35, 36, 37, 38, 39, 40  Další
Autor Zpráva
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 21.07.2023, 02:44 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Dodelal jsem slovo ROLL. Je to neco jako PICK, ale ktere kopiruje hodnotu ze zasobniku

0 pick je to same co dup ( a -- a a )
1 pick je to same co over ( b a -- b a b )
2 pick je to same co eee.. 2over nip ( c b a -- c b a c )
3 pick je to same co 2over drop ( d c b a -- d c b a d )
atd.

ROLL ale misto kopirovani tu hodnotu presune. Takze to ma za nasledek, ze se musi posunout o jedna vsechny hodnoty na zasobniku. Tomu se nelze vyhnout, jedine snad ze kazda polozka na zasobniku by byla pres ukazatel na predchozi a nasledujici (nebo nejaky xor obou), ale to by znamenalo minimalne dvojnasobnou velikost zasobniku.

0 roll je presun posledni polozky na posledni misto.. takze to nedela nic. ( a -- a )
1 roll je to same co swap ( b a -- a b )
2 roll je to same co rot ( c b a -- b a c )
3 roll je to same co eee.. -rot 2swap swap (asi) ( d c b a -- c b a d )
atd.

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_2_ROLL'
    ex   DE, HL         ; 1:4       2 roll   ( c b a -- b a c )
    ex  (SP),HL         ; 1:19      2 roll
; seconds: 0           ;[ 2:23]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_3_ROLL'
                        ;[6:52]     3 roll   ( d c b a -- c b a d )
    ex   DE, HL         ; 1:4       3 roll   d c a b
    ld    B, H          ; 1:4       3 roll
    ld    C, L          ; 1:4       3 roll
    pop  HL             ; 1:10      3 roll   . d a c
    ex   (SP),HL        ; 1:19      3 roll   . c a d
    push BC             ; 1:11      3 roll   c b a d
; seconds: 0           ;[ 6:52]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_4_ROLL'
                        ;[8:73]     4 roll   ( e d c b a -- d c b a e )
    ex   DE, HL         ; 1:4       4 roll   e d c a b
    ld    B, H          ; 1:4       4 roll
    ld    C, L          ; 1:4       4 roll
    pop  AF             ; 1:10      4 roll   . e d a b
    pop  HL             ; 1:10      4 roll   . . e a d
    ex   (SP),HL        ; 1:19      4 roll   . . d a e
    push AF             ; 1:11      4 roll   . d c a e
    push BC             ; 1:11      4 roll   d c b a e
; seconds: 0           ;[ 8:73]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_5_ROLL'
                       ;[12:102]    5 roll   ( f e d c b a -- e d c b a f )
    ex   DE, HL         ; 1:4       5 roll   f e d c a b
    ld    B, H          ; 1:4       5 roll
    ld    C, L          ; 1:4       5 roll
    pop  AF             ; 1:10      5 roll   . f e d a b  AF = c
    ex   AF, AF'        ; 1:4       5 roll
    pop  AF             ; 1:10      5 roll   . . f e a b  AF'= d
    pop  HL             ; 1:10      5 roll   . . . f a e
    ex   (SP),HL        ; 1:19      5 roll   . . . e a f
    push AF             ; 1:11      5 roll   . . e d a f
    ex   AF, AF'        ; 1:4       5 roll
    push AF             ; 1:11      5 roll   . e d c a f
    push BC             ; 1:11      5 roll   e d c b a f
; seconds: 0           ;[12:102]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh '_6_ROLL'
                       ;[16:131]    6 roll   ( g f e d c b a -- f e d c b a g )
    ex   DE, HL         ; 1:4       6 roll   g f e d c a b
    ld    B, H          ; 1:4       6 roll
    ld    C, L          ; 1:4       6 roll
    exx                 ; 1:4       6 roll
    pop  AF             ; 1:10      6 roll   . g f e d  AF = c
    pop  BC             ; 1:10      6 roll   . . g f e  BC'= d
    pop  DE             ; 1:10      6 roll   . . . g f  DE'= e
    exx                 ; 1:4       6 roll
    pop  HL             ; 1:10      6 roll   . . . . g a f
    ex   (SP),HL        ; 1:19      6 roll   . . . . f a g
    exx                 ; 1:4       6 roll
    push DE             ; 1:11      6 roll   . . . f e
    push BC             ; 1:11      6 roll   . . f e d
    push AF             ; 1:11      6 roll   . f e d c
    exx                 ; 1:4       6 roll
    push BC             ; 1:11      6 roll   f e d c b a g
; seconds: 0           ;[16:131]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(7) ROLL'
                       ;[22:421]    7 roll   ( x7 x6 .. x0 -- x6 .. x0 x7 )
    push DE             ; 1:11      7 roll
    push HL             ; 1:11      7 roll
    ld   HL, 0x000E     ; 3:10      7 roll
    add  HL, SP         ; 1:11      7 roll   HL = x7 addr
    ld    E, L          ; 1:4       7 roll
    ld    D, H          ; 1:4       7 roll   DE = x7 addr
    dec  DE             ; 1:6       7 roll
    ld    C,(HL)        ; 1:7       7 roll
    inc  HL             ; 1:6       7 roll
    ld    B,(HL)        ; 1:7       7 roll
    push BC             ; 1:11      7 roll
    ld   BC, 0x000E     ; 3:10      7 roll
    ex   DE, HL         ; 1:4       7 roll
    lddr                ; 2:289     7 roll   (DE--) = (HL--)
    pop  HL             ; 1:10      7 roll
    pop  DE             ; 1:10      7 roll
    pop  AF             ; 1:10      7 roll
; seconds: 0           ;[22:421]

Od 7 roll a vice je to uz delane pomalu pres SP.

Pokud se to vola z TOS (HL) je to pres jeste pomalejsi fci (tady jsem resil zatim jen funkcnost)
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'ROLL'
    call _ROLL          ; 3:17      roll   ( xu xu-1 .. x1 x0 u -- xu-1 .. x1 x0 xu )
    ex   DE, HL         ; 1:4       roll
    pop  DE             ; 1:10      roll
;==============================================================================
; ( xu xu-1 .. x1 x0 u -- xu-1 .. x1 x0 xu ? )
;  In: HL = u
; Out: HL = garbage
;      DE = xu
_ROLL:               ;[27:188+u*42] _roll   ( x3 x2 x1 x0 u -- x2 x1 x0 x3 ? )
    ld    A, L          ; 1:4       _roll
    or    H             ; 1:4       _roll
    ret   z             ; 1:5/11    _roll   u = 0?   
    pop  BC             ; 1:10      _roll   ret
    push DE             ; 1:11      _roll   .. x2 x1 x0 x0 u
    push BC             ; 1:11      _roll   .. x2 x1 x0 ret x0 u
    inc  HL             ; 1:6       _roll   u++
    add  HL, HL         ; 1:11      _roll   .. x2 x1 x0 ret x0 2*u+2
    ld    C, L          ; 1:4       _roll
    ld    B, H          ; 1:4       _roll   BC = 2*u+2
    add  HL, SP         ; 1:11      _roll   HL = addr xu-1
    ld    E,(HL)        ; 1:7       _roll
    inc  HL             ; 1:6       _roll
    ld    D,(HL)        ; 1:7       _roll   BC = xu
    push DE             ; 1:11      _roll   .. x2 x1 x0 ret xu xu ?
    ld    E, L          ; 1:4       _roll
    ld    D, H          ; 1:4       _roll
    dec  DE             ; 1:6       _roll
    dec  DE             ; 1:6       _roll
    ex   DE, HL         ; 1:4       _roll
    lddr                ; 2:u*42-5  _roll   (DE--) = (HL--)
    pop  DE             ; 1:10      _roll   .. x1 x0 ret ret xu ?
    pop  HL             ; 1:10      _roll   .. x1 x0 ret xu ret
    ret                 ; 1:10      _roll
; seconds: 0           ;[28:197]


Jak je videt, cim vetsi hloubka tim horsi a pomalejsi kod. Takze pokud mame neco jako

.... 0x333 0x222 0x111 0x000 2 roll tak je nesmysl volat _2_ROLL kdyz vime ze treti polozka na zasobniku je 0x222.

Takze jsem tohle upravil v tokenovych pravidlech.

Pokud ale budeme volat

... 0x333 0x222 0x111 0x000 4 roll

tam chceme co bylo v TOS (HL) nez se tam vlozila 0x333. A je skoda pak volat komplikovanou "4 roll"

takze tokonove pravidla se to budou snazit zmenit na:

0x333 swao 0x222 swap 0x111 swap 0x000 swap

Pri jeste vetsi hloubce nezname

... 0x333 0x222 0x111 0x000 5 roll

se provede pred 0x333 "1 roll" coz je swap

swap 0x333 swap 0x222 swap 0x111 swap 0x000 swap

Pri jeste vetsi hloubce

... 0x333 0x222 0x111 0x000 5 roll

se provede prvne "2 roll" coz je over

over 0x333 swap 0x222 swap 0x111 swap 0x000 swap

atd.

Tech znamych polozek muze byt max 7 myslim a pred tim 4 roll nejvic.

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x333,0x222,0x111,0x000,4) ROLL'
    push DE             ; 1:11      0x333 0x222 0x111 0x000 4 roll   ( x -- 0x333 0x222 0x111 0x000 x )
    ld   DE, 0x333      ; 3:10      0x333 0x222 0x111 0x000 4 roll
    push DE             ; 1:11      0x333 0x222 0x111 0x000 4 roll
    ld   DE, 0x0222     ; 3:10      0x333 0x222 0x111 0x000 4 roll
    push DE             ; 1:11      0x333 0x222 0x111 0x000 4 roll
    ld   DE, 0x0111     ; 3:10      0x333 0x222 0x111 0x000 4 roll
    push DE             ; 1:11      0x333 0x222 0x111 0x000 4 roll
    dec   D             ; 1:4       0x333 0x222 0x111 0x000 4 roll
    ld    E, D          ; 1:4       0x333 0x222 0x111 0x000 4 roll   E = D = 0x00
; seconds: 1           ;[15:82]

dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x222,0x111,0x000,2) ROLL'
    push DE             ; 1:11      0x222 0x111 0x000 2 roll   ( -- 0x111 0x000 0x222 )  # HL DE DE
    push HL             ; 1:11      0x222 0x111 0x000 2 roll
    ld   HL, 0x0111     ; 3:10      0x222 0x111 0x000 2 roll
    push HL             ; 1:11      0x222 0x111 0x000 2 roll
    ld   DE, 0x0000     ; 3:10      0x222 0x111 0x000 2 roll
    add  HL, HL         ; 1:11      0x222 0x111 0x000 2 roll   0x222 = 2*0x111
; seconds: 1           ;[10:64]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0x444,0x333,0x222,0x111,0x000,5) ROLL'
    push DE             ; 1:11      0x444 0x333 0x222 0x111 0x000 5 roll
    ld   DE, 0x0444     ; 3:10      0x444 0x333 0x222 0x111 0x000 5 roll   ( x0 -- 0x444 0x333 0x222 0x111 0x000 x0 )
    push DE             ; 1:11      0x444 0x333 0x222 0x111 0x000 5 roll
    ld   DE, 0x0333     ; 3:10      0x444 0x333 0x222 0x111 0x000 5 roll
    push DE             ; 1:11      0x444 0x333 0x222 0x111 0x000 5 roll
    ld   DE, 0x0222     ; 3:10      0x444 0x333 0x222 0x111 0x000 5 roll
    push DE             ; 1:11      0x444 0x333 0x222 0x111 0x000 5 roll
    ld   DE, 0x0111     ; 3:10      0x444 0x333 0x222 0x111 0x000 5 roll
    push DE             ; 1:11      0x444 0x333 0x222 0x111 0x000 5 roll
    dec   D             ; 1:4       0x444 0x333 0x222 0x111 0x000 5 roll
    ld    E, D          ; 1:4       0x444 0x333 0x222 0x111 0x000 5 roll   E = D = 0x00
; seconds: 0           ;[19:103]

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 21.07.2023, 03:01 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Ted pracuji na tom abych pochopil co dela slovo

[']

V popisu je
Citace:
[']
bracket-tick
CORE
Interpretation:
Interpretation semantics for this word are undefined.
Compilation:
( "<spaces>name" -- )
Skip leading space delimiters. Parse name delimited by a space. Find name. Append the run-time semantics given below to the current definition.

An ambiguous condition exists if name is not found.

Run-time:
( -- xt )
Place name's execution token xt on the stack. The execution token returned by the compiled phrase "['] X" is the same value returned by "' X" outside of compilation state.

See:
3.4.1 Parsing, 6.1.1550 FIND, A.6.1.0070 ' A.6.1.2033 POSTPONE, A.6.1.2510 ['].
Rationale:
Typical use: : X ... ['] name ... ;
See: A.6.1.1550 FIND.

Testing:
T{ : GT2 ['] GT1 ; IMMEDIATE -> }T
T{ GT2 EXECUTE -> 123 }T

Popisek jsem vubec nepochopil a ani testovani nepomaha kdyz tam chybi definice GT1...

Nastesti jsem oklikou narazil na slovo '. Ktere kdyz napisete pred jmenem fce slova tak misto aby to slovo provedlo tak vrati adresu te fce, takze to pak jde zavolat pres execute

: pozdrav ." hi" cr ;

hi

je pak to same co

' hi exexute

Pro me to znamena ze prvni "hi" se prevadi na CALL(hi) a druhe " ' hi" na PUSH(hi).

Aby to bylo komplikovanejsi tak kdyz vytvarim "label" pomoci CREATE

create abc

a pak napisi

abc

tak to na zasobnik vlozi adresu toho labelu takze pro me je to PUSH(abc).

Ale ono jde napsat i

' abc

a to vraci... neco jineho... myslim ze to vraci adresu toho retezce abc co musi mit forth nekde ulozeny, nebo adresu ve slovniku. Nevim...

' abc >BODY

ale udela to same co pouhe "abc".

' hi >BODY zase vraci neznamou adresu pro me...

V popisku je
Citace:
'
tick
CORE
( "<spaces>name" -- xt )
Skip leading space delimiters. Parse name delimited by a space. Find name and return xt, the execution token for name. An ambiguous condition exists if name is not found. When interpreting, ' xyz EXECUTE is equivalent to xyz.

See:
A.3.4.3.2 Interpretation semantics, A.6.1.1550 FIND.
Rationale:
Typical use: ... ' name.
Many Forth systems use a state-smart tick. Many do not. Forth-2012 follows the usage of Forth 94.

Testing:
T{ : GT1 123 ; -> }T
T{ ' GT1 EXECUTE -> 123 }T


Takze tady je to GT1! A ty zavorky [] jsou jen pro to, ze s nema to plati jen v definici fce a bez nich na prikazovem radku. Neco jako char a [char]. Pro me to nema zadny vyznam rozlisovat.

Takze ' je asi neco jako & v jazyce C.
Zvlastni ze jsem zatim nikde nenasel na tohle tema vic informaci.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 21.07.2023, 04:00 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Opravil jsem ROLL. Pouzil jsem metodu co byla ve fci, ze BC drzi hodnotu co se pricita k SP. Stejna rychlost ale o bajt kratsi.

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(7) ROLL'
                       ;[22:421]    7 roll   ( x7 x6 .. x0 -- x6 .. x0 x7 )
    push DE             ; 1:11      7 roll
    push HL             ; 1:11      7 roll
    ld   HL, 0x000E     ; 3:10      7 roll
    add  HL, SP         ; 1:11      7 roll   HL = x7 addr
    ld    E, L          ; 1:4       7 roll
    ld    D, H          ; 1:4       7 roll   DE = x7 addr
    dec  DE             ; 1:6       7 roll
    ld    C,(HL)        ; 1:7       7 roll
    inc  HL             ; 1:6       7 roll
    ld    B,(HL)        ; 1:7       7 roll
    push BC             ; 1:11      7 roll
    ld   BC, 0x000E     ; 3:10      7 roll
    ex   DE, HL         ; 1:4       7 roll
    lddr                ; 2:289     7 roll   (DE--) = (HL--)
    pop  HL             ; 1:10      7 roll
    pop  DE             ; 1:10      7 roll
    pop  AF             ; 1:10      7 roll
; seconds: 1           ;[22:421]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(7) ROLL'
                       ;[21:421]    7 roll   ( x7 x6 .. x0 -- x6 .. x0 x7 )
    push DE             ; 1:11      7 roll
    push HL             ; 1:11      7 roll
    ld   HL, 0x000E     ; 3:10      7 roll   2*7
    ld    C, L          ; 1:4       7 roll
    ld    B, H          ; 1:4       7 roll   BC = 2*7
    add  HL, SP         ; 1:11      7 roll   HL = &x7 = lo_addr(x7)
    ld    E,(HL)        ; 1:7       7 roll
    inc  HL             ; 1:6       7 roll
    ld    D,(HL)        ; 1:7       7 roll
    push DE             ; 1:11      7 roll
    ld    E, L          ; 1:4       7 roll
    ld    D, H          ; 1:4       7 roll   DE = (char) (&x7)++ = hi_addr(x7)
    dec  HL             ; 1:6       7 roll
    dec  HL             ; 1:6       7 roll
    lddr                ; 2:289     7 roll   (DE--) = (HL--)
    pop  HL             ; 1:10      7 roll
    pop  DE             ; 1:10      7 roll
    pop  AF             ; 1:10      7 roll
; seconds: 0           ;[21:421]

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 21.07.2023, 09:02 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3675
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 798 times
_dworkin píše:
Ted jsem nasel slovo "ms ( u -- )" pro cekani v mikrosekundach. 20 ms je jedno "halt". Tak to nevim jak tohle udelat bez deleni 20 a i pak nevim jak udelat ten zbytek... cekaci smycka bude totiz rozdilna kdyz pobezi pod 0x8000 a nebo nad... mozna nejake if ( $ > 0x8000) pri kompilaci?
A pri kratkych casoch, radovo jednotky milisekund, tiez treba rozlisovat kedy presne vzhladom na prerusenie taka slucka bezi, pretoze napriklad v hornej a spodnej casti BORDERu je videoramka rovnako rychla ako rychla ramka. Iba v case zobrazovania PAPERu je vyrazne spomalena.

A dalej treba aj nieco ako if (computer = DidaktikM or computer = DidaktikKompakt) pretoze tam je spomalena uplne cela ramka, ale menej nez videoramka na normalnom ZX, to spomalenie je priemerne na urovni cca 3.4 MHz. A este k tomu instrukcie tam maju ine pocty taktov :lol:
A to uz nepisem o tom ze videoramka je vzhladom na iny sposob vycitavania videodat na 16/48/128/+2 spomalena inym sposobom ako na +2A/+3 (nieco bezi rychlejsie, nieco pomalsie, v zavislosti od toho ako sa zrovna strafis do vycitavania videodat).
_dworkin píše:
To by ale zase muselo bezet s "di" a tim behem cekani ani necist klavesnici...
Preco by si nemohol citat klavesnicu v DI ?!?! Ved normalne v tele slucky bude napr.
Kód:
xor a
in a,(#FE)
or #E0
inc a
a ak nebude zero, tak bola stlacena nejaka klavesa a zo slucky mozes vyskocit.
_dworkin píše:
PPS: Dalsi otazka je zda maji milisekundy smysl...
Zmysel urcite maju, ale vzhladom na rozne rychlosti vykonavania programu na roznych klonoch a na to ze ZX nema nejaky citac typu 8253 je obecna realizacia niecoho takeho velmi narocna a preto by som to z cisto praktickych dovodov zavrhol a nechal len rozlisenie 20 ms od prerusenia, ktore je vsade a vzdy cca tych 20 ms bez ohladu na spomalenie ramky, CPU clock a pod.
_dworkin píše:
Takze jedine nejaky reakcni cas pri cteni klavesnice?
Editovacie rutinky v romke (ked pises basic program alebo zadavas data do INPUTu) a tak isto aj prikaz PAUSE citaju klavesnicu vyhradne iba z prerusenia. A teraz nasleduje cisto prakticka otazka: Zda sa ti ich odozva na stlacenie klavesy pomala ? (samozrejme nemyslim pripad prilis dlheho riadku, kde dlho trva samotny vypis riadku). Podla mna je svizna, a ked na klavesnicu zareagujes do 20 ms, tak z pohladu bezneho cloveka a jeho reakcneho casu je to proste okamzite. Takze ja by som sa uplne uspokojil s 20 ms a casovanim z prerusenia.
_dworkin píše:
ROLL ale misto kopirovani tu hodnotu presune. Takze to ma za nasledek, ze se musi posunout o jedna vsechny hodnoty na zasobniku. Tomu se nelze vyhnout, jedine snad ze kazda polozka na zasobniku by byla pres ukazatel na predchozi a nasledujici (nebo nejaky xor obou), ale to by znamenalo minimalne dvojnasobnou velikost zasobniku.
Toto sa bezne riesi tak, ze zasobnik je ako pole, ktore zacina na jeho vrchole. T.j. hodnota na vrchole ma index 0, hodnota pod vrcholom index 1 ... a potom k lubovolnej hodnote pristupujes podla jej indexu. Samozrejme ked na zasobnik nieco pribudne alebo ubudne, tak sa indexy prislusne pomenia. Ale s tym sa pocita. Presne takto funguje napriklad aj matematicky koprocesor x87.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 21.07.2023, 14:12 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Casovani jsem zatim vzdal. Zrovna ted resim pri nalezeni "ms" v tom prevodnim awk-ovem programu tak ze to proste nahradim za

"PUSH(20) UDIV WAIT"

Pokud teda pred tim lezi nejaka hodnota tak bude v kodu neco jako

"PUSH(1000) PUSH(20) UDIV WAIT"

cast "PUSH(1000) PUSH(20) UDIV" me odchytnou pravidla pro tokeny a zmeni na PUSH(50).

Nasledne WAIT najde pred sebou to PUSH(50) a zmeni se na PUSH_WAIT(50) a to pri delani kodu zjisti ze 50 je mensi jak 257 takze pouzije smycku pres B.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(1000) PUSH(20) UDIV WAIT'
    ei                  ; 1:4       1000 20 u/ wait   ( -- )
    ld    B, 0x32       ; 2:7       1000 20 u/ wait   50x
    halt                ; 1:70000   1000 20 u/ wait   0 .. 0.02 seconds
    djnz $-1            ; 2:8/13    1000 20 u/ wait
; seconds: 41          ;[ 6:70019]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(abc) PUSH(20) UDIV WAIT'
    ei                  ; 1:4       abc 20 u/ wait   ( time -- )
    ld   BC, +(abc)/20  ; 3:10      abc 20 u/ wait
    halt                ; 1:70000   abc 20 u/ wait   0 .. 0.02 seconds
    ld    A, C          ; 1:4       abc 20 u/ wait
    or    B             ; 1:4       abc 20 u/ wait
    dec  BC             ; 1:6       abc 20 u/ wait
    jr   nz, $-4        ; 2:8/13    abc 20 u/ wait
; seconds: 1           ;[10:70036]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$

Takze co je pod 0.02 uplne zanedbavam.
To je trosku v rozporu s "ms", ktere ma v definici
Citace:
ms ( u -- )
Wait at least u milliseconds.

A "least" me to preklada na "ALESPOŇ".
Ale to nedodrzuji ani u tech nasobku 20. Protoze v kodu mam pri 0 jedno halt a to muze trvat 0 az 0.02 sekundy. Az kazde dalsi bude trvat 0.02. Proste to zaokrouhluji jakoby dolu.

S tim ctenim klavesnice jsem narazel na to, ze pokud vypnu preruseni a budu cekat vterinu tak se mi nebude testovat klavesnice pokud si to neotestuji sam (a to jak vidis v tom ukazkovem kodu wait nedelam, protoze zatim nemusim). Coz by bylo rozdilne chovani oproti "normalu".

Citace:
Toto sa bezne riesi tak, ze zasobnik je ako pole, ktore zacina na jeho vrchole. T.j. hodnota na vrchole ma index 0, hodnota pod vrcholom index 1 ... a potom k lubovolnej hodnote pristupujes podla jej indexu. Samozrejme ked na zasobnik nieco pribudne alebo ubudne, tak sa indexy prislusne pomenia. Ale s tym sa pocita. Presne takto funguje napriklad aj matematicky koprocesor x87.


Nejsem si uplne jisty co si chtel rici.
Z popisku to vypada jako by si se snazil rici ze pokud dokazi relativne indexovat zasobnik od nuly tak to roll nepotrebuji.
Z popisu toho koprocesoru tusim ale uz si to nepamatuji ze to ROLL kde posledni hodnota muze byt prvni se muze resit i tim ze mam nejak vhodne resenou velikost zasobniku na nasobek 2 a pak bych to mohl udelat jen pomoci zmeny "pocatku" nebo TOS adresy.

x = index TOS = moje volba prvni polozky = skutecny index v realnem poli

nejak jako TOS = fyzicka_adresa + 2*x.
NOS = fyzicka_adresa + ((2(x+1)) & 0x000F)
atd.

Jestli minis tohle tak to nebude fungovat protoze ROLL dela neco jineho.

Pokud muj zasobnik vypada takto (TOS je vpravo)

10 9 8 7 6 5 4 3 2 1 0

a ja udelam "3 roll" tak pak vypada fyzicky takto

10 9 8 7 6 5 4 2 1 0 3

proste to ROLL nemeni jen posledni polozku (ale jakoukoliv mu zadam) a me kruhovy buffer nepomuze. Vyjmutim 3 mezi 4 a 2 vznikne mezera a ta se musela zacelit prekopirovanim "2 1 0".

Pokud si chtel rici ze mam pole indexu a jen ty menim, tak si nepomuzu uz vubec protoze pak musim tu praci s kopirovanim provest taky a zabira to 2x tolik mista. A pristup je pomalejsi nez bez pole indexu.
Je ale fakt ze pomalejsi o konstantu na rozdil od pole kde kazda dalsi polozka ma ukazatel na sousedni, kde se to musi projit cele. Na druhou stranu ve Forth kodu bezne pristupuje jen k TOS a NOS.

Proste nevim co si me radil. .)

PS: Proc tu vlastne lezu. Asi jsem narazil na dalsi stopu co dela pro me stale nezname slova [ ].
V popisku je, ze co je uvnitr se ma vykonat hned, ale smysl me unikal.
Ted jsem ale narazil na text kde pisi ze kdyz delam nejake slovo/fci (pouziva se asi spravne vyhradne termin LITERAL) a mam tam neco jako

2 cells

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(2) CELLS'
    push DE             ; 1:11      2
    ex   DE, HL         ; 1:4       2
    ld   HL, 2          ; 3:10      2
    add  HL, HL         ; 1:11      cells
; seconds: 0           ;[ 6:36]


Tak program pocita uplne zbytecne pokazde 2*2 kdyz to muze udelat jen jednou a priste nahradit za 4.
A aby to udelal je dobre mit to []

[ 2 cells ] literal

Proc je tam to literal taky jeste uplne nechapu. Asi celou tu cast [ 2 cells ] ma udelat jako jedno slovo, a jeho vysledek se pak bude pouzivat? Misto toho 2 cells? Syntakticky cukr? Nevim proste vubec nic. .)

Ale aspon vim, ze bych si mel spravit to slovo CELLS
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(2) CELLS'
    push DE             ; 1:11      2 cells
    ex   DE, HL         ; 1:4       2 cells
    ld   HL, 4          ; 3:10      2 cells
; seconds: 1           ;[ 5:25]

Ted uz funguji optimalizace, misto CELLS = "_2MUL" jsem udelal CELLS = "PUSH(2) MUL" a tohle si uz tokenova pravidla najdou.

Protoze _2MUL je posledni faze optimalizace, kdy ostatni selhaly a nezname HL, tak to aspon zamenime na add hl,hl nez volat obecne nasobeni.

Stejny pripad jako je _3_ROLL jak jsem psal vcera. Pouzivat jen PUSH(3) ROLL. To se vnitrne prevede na PUSH_ROLL(3) a to si _3_ROLL zavola samo.

Bez testovani nic spravne nefunguje. .)

Predtim a ted se zaplym VERBOSE
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'VERBOSE(1) PUSH(2) CELLS'

   ...add token __TOKEN_PUSHS "2" --> 1 = __TOKEN_PUSHS "2"
   ...add token __TOKEN_2MUL "cells" --> 2 = __TOKEN_2MUL "cells"
   ...check all tokens
   ...second pass: 1 = __TOKEN_PUSHS "2"
   ...second pass: 2 = __TOKEN_2MUL "cells"
   ...check all tokens2
   ...third pass: 1 = __TOKEN_PUSHS 2
   ...third pass: 2 = __TOKEN_2MUL cells
   ...create __TOKEN_PUSHS 2
   ...create __TOKEN_2MUL cells
    push DE             ; 1:11      2
    ex   DE, HL         ; 1:4       2
    ld   HL, 2          ; 3:10      2
    add  HL, HL         ; 1:11      cells
; seconds: 0           ;[ 6:36]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'VERBOSE(1) PUSH(2) CELLS'

   ...add token __TOKEN_PUSHS "2" --> 1 = __TOKEN_PUSHS "2"
   ...add token __TOKEN_PUSHS "cells" --> 1 = __TOKEN_PUSHS "2 cells"
   ...add token __TOKEN_MUL "__dtto" --> 1 = __TOKEN_PUSHS "2 cells"
   ...check all tokens
   ...second pass: 1 = __TOKEN_PUSHS "2 cells"
   ...check all tokens2
   ...third pass: 1 = __TOKEN_PUSHS 2 cells
   ...create __TOKEN_PUSHS 2 cells
    push DE             ; 1:11      2 cells
    ex   DE, HL         ; 1:4       2 cells
    ld   HL, 4          ; 3:10      2 cells
; seconds: 1           ;[ 5:25]


PPS: Asi bych mel doplnit ve vypisu i parametry k tem tokenum nejenom info, aby to bylo citelnejsi. Jen musim poresit retezce a nebo pokud je tech parametru prilis mnoho...
Napriklad v tom druhem vypise to neustale tvrdi ze to uklada prvni token "1". Protoze poprve je to prvni token. Pak prida dalsi PUSHS a to se slouci s prvnim a jen prida dalsi parametr. Pak je MUL a zase prvni token a opet PUSHS, jen uz to misto PUSHS(2,2) ma jeden parametr 4. Tedy PUSHS(4). A pochopi to jen ten kdo vi co to vlastne dela...

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 22.07.2023, 17:05 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Neskutecny uspech!

Podarilo se me temer bez nutnosti menit kod zkompilovat conwoy.fth z RossetaCode.org!!!
Kód:
\ The fast wrapping requires dimensions that are powers of 2.
 1 5 lshift constant w \ 32
 1 4 lshift constant h \ 16

 : rows    w * 2* ;
 1 rows constant row
 h rows constant size
 
 create world size allot
 world   value old
 old w + value new
 
 variable gens
 : clear  world size erase     0 gens ! ;
 : age  new old to new to old  1 gens +! ;
 
 : col+  1+ ;
 : col-  1- dup w and + ; \ avoid borrow into row
 : row+  row + ;
 : row-  row - ;
 : wrap ( i -- i ) [ size w - 1- ] literal and ;
 : w@ ( i -- 0/1 ) wrap old + c@ ;
 : w! ( 0/1 i -- ) wrap old + c! ;
 
 : foreachrow ( xt -- )
   size 0 do  I over execute  row +loop drop ;
 
 : showrow ( i -- ) cr
   old + w over + swap do I c@ if [char] * else bl then emit loop ;
 : show  ['] showrow foreachrow  cr ." Generation " gens @ . ;
 
 : sum-neighbors ( i -- i n )
   dup  col- row- w@
   over      row- w@ +
   over col+ row- w@ +
   over col-      w@ +
   over col+      w@ +
   over col- row+ w@ +
   over      row+ w@ +
   over col+ row+ w@ + ;
 : gencell ( i -- )
   sum-neighbors  over old + c@
   or 3 = 1 and   swap new + c! ;
 : genrow ( i -- )
   w over + swap do I gencell loop ;
 : gen  ['] genrow foreachrow  age ;
 
 : life  begin gen 0 0 at-xy show key? until ;

 \ patterns
 char | constant '|'
 : pat ( i addr len -- )
   rot dup 2swap  over + swap do
     I c@ '|' = if drop row+ dup else
     I c@ bl  = 1+ over w!  col+ then
   loop 2drop ;
 
 : blinker s" ***" pat ;
 : toad s" ***| ***" pat ;
 : pentomino s" **| **| *" pat ;
 : pi s" **| **|**" pat ;
 : glider s"  *|  *|***" pat ;
 : pulsar s" *****|*   *" pat ;
 : ship s"  ****|*   *|    *|   *" pat ;
 : pentadecathalon s" **********" pat ;
 : clock s"  *|  **|**|  *" pat ;

 clear  0
 glider show
 gen show
 gen show
 gen show
 gen show


Jedina nutna zmena byla ze puvodne tam bylo
Kód:
 : rows    w * 2* ;
 1 rows constant row
 h rows constant size

Ale to pokud je hodnota v constant schovana za funkci (i kdyz ta je volana taky s konstantama) tak to selze, protoze se nedostane k te hodnote v dobe kompilace. Protoze emulaci chodu programu v dobe kompilace nedelam.
Stejne je tohle neskutecny troling od autora, protoze jedine co ta fce dela je ze vynasobi vstup hodnotou "2*w".
Takze jsem to zmenil na
Kód:
 w 2* constant rows
 1 rows * constant row
 h rows * constant size


Mel jsem i problemy s tim jak puvodne vyhodnocuji konstanty v M4, musel jsem opravit chyby, aby me to vracelo cislo a ne nejaky "h*w*2". Musel jsem predelat i 2* z _2MUL na PUSH(2) MUL. Dalsi chyba byla ze jsem nekdy zmenil chovani kdyz je vzorec cely v zavorce... ted uz je to automaticky ukazatel, pokud pred to nedam napr. "+". Tedy "+(vzorec)". Takze me selhavali tokenove pravidla jakmile jsem mel (_h)*(_w). Tohle jsem opravil jen castecne pro nasobeni a odcitani, protoze tech operaci je hodne a je moc komplexni...
Pak jsem mel problem jeste s vkladanim znaku. Napriklad ' '. To taky nici tokenova pravidla. Takze jsem predelaval cely PUSH tak ze kdyz narazi na znak, tedy neco uzavrene v jednoduchych uvozovkach tak to zameni za Ascii hodnotu a ten znak bude jen v popisku. Kupodivu taky hrozny problem... :D M4 nema zadny ORD(char). format({0x%02X},$1) na to nefunguje. Takze jsem musel volat bash a tam spustit printf "0x%02X" '{$1}
Nanestesti to neni tak jedoduche jak to vypada, protoze nektere znaky jsou v shellu specialni takze je musim resit jinak. Pak jsou dalsi specialni znaky co jsou v M4. Proste problemy jsou stale s: ( ) , { }
Prvni 3 znaky jdou jeste vyresit pres to ze se to obali do {}.

Napriklad ')' jako PUSH({')'}).

Posledni 2 jsou problem, to by vyresilo jen jinak nastavit quote v M4... Takze se to ted musi zadat jako cislo.

Spatne na testovani tohole je, ze v konzoli mam vstup ohraniceny prave znakem '. Takze kdyz to nahradim za " tak se to pak chova jinak. Protoze shell uvnitr "..." aktivuje nejake specialni znaky na rozdil od '...'.

Mimochodem \n to nastavuje na 0x0D protoze ZX to nema na 0x0A jako unix like systemy.

Diky temto zmenam se mi podarilo vyporadat se s tim trolenim forthu pri nastavovani obycejnych konstant a selhal jsem u literalu [, ] a literal. ['] jsem uz nejak nastavil a ty predchozi 3 jsem odmazal a spustil na webu v gfortu. Podle ocekavani zadna zmena v chovani programu. Takze je to asi fakt aspon v tomhle pripade kvuli optimalizaci chodu...

Hlavne ze v tom programu je
Kód:
 : col+  1+ ;
 : col-  1- dup w and + ; \ avoid borrow into row
 : row+  row + ;
 : row-  row - ;

Prvni fce udela jen "inc HL" a ja ji kvuli tomu musim slozite volat s osetrenim zasobniku abych vyjmul RET.
Posledni 2 prictou nebo odectou od TOS konstantu... OMG. To je cely vstup fce. Proste Forth ma jinou filozofii co je spravne...

Nanestesti jsem mel vetsi problemy jinde nez resit tohle. Program selhal na tom ze jmeno konstanty pro vysku je "h", coz je zaroven registr Z80 ja urcite vite. Takze jsem se opet spalil a musel predelavat fci v awku pro konverzi jmen na jmena pouzitelna v C. Uz jsem to mel v puvodnim skriptu a pak nejak zapomnel ze na zacatku proste vsude vrazim "_". Tohle vlastne resi i jmena zacinajici cislem...

Dalsi vec vyresena a podarilo se mi to konecne zkompilovat!
Jen to pak spadlo do basicu s chybou...

OMG debugovat kod se me fakt nechtelo...

Vsiml jsem si tam ale tohohle...
Kód:
 : showrow ( i -- ) cr
   old + w over + swap do I c@ if [char] * else bl then emit loop ;

Kód:
    ld    L,(HL)        ; 1:7       c@   ( addr -- char )
    ld    H, 0x00       ; 2:7       c@
    ld    A, H          ; 1:4       if
    or    L             ; 1:4       if
    ex   DE, HL         ; 1:4       if
    pop  DE             ; 1:10      if
    jp    z, else101    ; 3:10      if
    push DE             ; 1:11      char '*'
    ex   DE, HL         ; 1:4       char '*'
    ld   HL, 0x2A       ; 3:10      char '*'
    jp   endif101       ; 3:10      else
else101:                ;           else
    push DE             ; 1:11      char ' '
    ex   DE, HL         ; 1:4       char ' '
    ld   HL, 0x20       ; 3:10      char ' '
endif101:               ;           then

Vstup pro IF bere proste rovnou z pameti, zadny test protoze staci zjistit zda tam je nula nebo ne.
Tohle je proste bolest videt, takze jsem aspon pro tento jeden pripad udelal spojeni slov:
Kód:
    ld    L,(HL)        ; 1:7       c@   ( addr -- char )
    ld    H, 0x00       ; 2:7       c@
    ld    A, H          ; 1:4       if char '*' else char ' ' then   ( flag -- x )
    or    L             ; 1:4       if char '*' else char ' ' then
    ld   HL, 0x002A     ; 3:10      if char '*' else char ' ' then   true
    jr   nz, endif101   ; 2:7/12    if char '*' else char ' ' then
    ld   HL, 0x0020     ; 3:10      if char '*' else char ' ' then   false
endif101:               ;           if char '*' else char ' ' then

Je tam jeste test zda neni prvni ukazatel a druhy ne, pak se otoci poradi a z nz udela z.

Pak jsem si jeste vsimnul ze cast
Kód:
 create world size allot
 world   value old
 old w + value new

kde se nastavuje hodnota promenne "old" na adresu labelu "world" se vzapeti ta hodnota pouziva jako vstup pro dalsi promennou..
Bohuzel v asm je pak
Kód:
                        ;           create _world
                        ;           256 allot
  .warning __ASM_TOKEN_PUSH_VALUE(_world,_old): M4 does not know _world parameter value!
    ld   BC, _world     ; 3:10      _world value _old
    ld  (_old), BC      ; 4:20      _world value _old
    push DE             ; 1:11      (_old) 0x0010 +
    ex   DE, HL         ; 1:4       (_old) 0x0010 +
    ld   HL, (_old)     ; 3:16      (_old) 0x0010 +
    ld   BC, 0x0010     ; 3:10      (_old) 0x0010 +   ( x -- x+0x0010 )
    add  HL, BC         ; 1:11      (_old) 0x0010 +
                        ;           value _new
    ld  (_new), HL      ; 3:16      value _new
    pop  HL             ; 1:10      value _new
    ex   DE, HL         ; 1:4       value _new


Tady je videt ze si ty tokeny nepredavaji zadne informace a ten kod vypada jako co leze z C prekladace u ktereho jsem mel velke vyhrady...
Ted se me to vratilo a trolli me vlastni prekladac... .)

Takze... jsem debugoval a debugoval. Ten vstupni program je fakt hrozny protoze pouziva i EXECUTE. Takze vola ruzne fce podle toho co ma na zasobniku..
A nakonec jsem odhalil chybu, prohazovalo me to HL a DE a chyba byla neocekavane v tokenu "DO".
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/RossetaCode$ ../check_word.sh 'DO LOOP'
    ld  (idx101), HL    ; 3:16      do_101(m)   index  ( stop index -- )
    ld    A, E          ; 1:4       do_101(m)
    ld  (stp_lo101), A  ; 3:13      do_101(m)   lo stop
    ld    A, D          ; 1:4       do_101(m)
    ld  (stp_hi101), A  ; 3:13      do_101(m)   hi stop
    pop  DE             ; 1:10      do_101(m)
    pop  HL             ; 1:10      do_101(m)
do101:                  ;           do_101(m)
idx101 EQU $+1          ;[20:78/57] loop_101(m)
    ld   BC, 0x0000     ; 3:10      loop_101(m)   idx always points to a 16-bit index
    inc  BC             ; 1:6       loop_101(m)   index++
    ld  (idx101), BC    ; 4:20      loop_101(m)   save index
    ld    A, C          ; 1:4       loop_101(m)   lo new index
stp_lo101 EQU $+1       ;           loop_101(m)
    xor  0x00           ; 2:7       loop_101(m)   lo stop
    jp   nz, do101      ; 3:10      loop_101(m)
    ld    A, B          ; 1:4       loop_101(m)   hi new index
stp_hi101 EQU $+1       ;           loop_101(m)
    xor  0x00           ; 2:7       loop_101(m)   hi stop
    jp   nz, do101      ; 3:10      loop_101(m)
leave101:               ;           loop_101(m)
exit101:                ;           loop_101(m)
; seconds: 0           ;[33:148]

Jak urcite na prvni pohled hned vidite mel jsem prvne POP DE a ne POP HL.

Po tehle oprave konecne prisla ta chvile a uvidel jsem
Příloha:
conway.png
conway.png [ 2.77 KiB | Zobrazeno 1994 krát ]


Pro me je to fakt velky uspech, protoze tohle byl narocny vstup plny komplikovanych slov a zaludnosti. Neni to trivialni program. No... trosku je, ale chapete co chci rici.. .) Urcite je komplikovany dost na to, abych na prvni pohled nevidel co vlastne dela. A nevim to vlastne doted, protoze jsem se ho snazil zkompilovat a ne pochopit jak co konkretne dela.
Hodne se posunula pravdepodobnost ze jen vezmu kod z rosettacode.org a zkompiluji ho a mam vysledek.

PS: Vlastne jsem jeste editoval ve zdrojaku tu sirku, protoze tam bylo misto 32 cislo 64. Teda bylo tam diky forth trolingu jiny bitovy posun.
Kód:
 1 6 lshift constant w \ 64


PPS: A mel jse zase rozhaseny i retezce... chybelo me tam jedno obaleni {}, takze pak vystup v asm byl jen " db" a prazdny radek misto db "Hello"

PPPS: Jeste doporucuji se podivart na tuto vtipnou cast kodu:
Kód:
char | constant '|'

Autor definuje takto konstantu s nazvem '|' a to vcetne tech apostrofu. Aby ji pak mohl pouzivat jako vstup stejne jako by to psal v C-ecku. Jinak by musel misto toho vsude psat "char |" co dela to same. Literal "char" nacte retezec zacinajici a ukonceny mezerou a pouzije prvni znak z neho.
Nastesti mam v awku ten prevod napsany co nejlepe, ale nesmite se divit co za podivne nazvy pak z toho lezou
Kód:
CONSTANT(__SQ_VBAR_SQ,'|')


PPPPS: Opraveny kod co to zvladne bude na webu az po anglicke pulnoci, ale pochybuji ze to nekdo bude ted stahovat.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 24.07.2023, 19:59 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Nejak nedokazi prinutit regexp v M4 aby byl non-greedy (lazy)
Kód:
regexp({10 20 30 40},{\(^\|^.*\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20 30 40},{\(^\|^.*?\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20 30 40},{\(^\|^.*?\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20 30 40},{\(^\|^.*\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20 30 40},{\(^\|\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20 30 40},{\(^\|\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20 30 40},{\(^\|\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20 30 40},{\(^\|\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20},{\(^\|^.*\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20},{\(^\|^.*?\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20},{\(^\|^.*?\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20},{\(^\|^.*\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20},{\(^\|\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20},{\(^\|\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20},{\(^\|\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10 20},{\(^\|\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10},{\(^\|^.*\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10},{\(^\|^.*?\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10},{\(^\|^.*?\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10},{\(^\|^.*\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10},{\(^\|\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10},{\(^\|\s\)\([0-9]+\)\(\s.*$\|$\)},{1:\1  2:\2  3:\3})
regexp({10},{\(^\|\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})
regexp({10},{\(^\|\s\)\([0-9]+\)\(\s.*?$\|$\)},{1:\1  2:\2  3:\3})

ma vystup
Kód:
1:10 20 30   2:40  3:
1:10 20 30   2:40  3:
1:10 20 30   2:40  3:
1:10 20 30   2:40  3:
1:  2:10  3: 20 30 40
1:  2:10  3: 20 30 40
1:  2:10  3: 20 30 40
1:  2:10  3: 20 30 40
1:10   2:20  3:
1:10   2:20  3:
1:10   2:20  3:
1:10   2:20  3:
1:  2:10  3: 20
1:  2:10  3: 20
1:  2:10  3: 20
1:  2:10  3: 20
1:  2:10  3:
1:  2:10  3:
1:  2:10  3:
1:  2:10  3:
1:  2:10  3:
1:  2:10  3:
1:  2:10  3:
1:  2:10  3:

Pro me je klicovy ty prvni 4 pripady, protoze si dokazi zapamatovat cely vstup, jen spravne rozdeleny...

Mam na vstupu (nekorektni) nejaky vyraz 10/3*50 a M4 me z toho udela 10/150 a pak nulu. eval me z toho udela 150. Pocita to jako (10/3)*50. Prizemz * / a % maji stejnou prioritu, jen to dela zleva doprava. A ja to nachazim zprava doleva...

PS: sed v bashi to dela presne naopak. Tam to zase neumim prinutit hleda zprava
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/RossetaCode$ echo "10 20 30 40" | sed -E 's#(^|^.*?\s)([0-9]+)(\s.*$)#1:\1  2:\2  3:\3#g'
1:  2:10  3: 20 30 40
dworkin@dw-A15:~/Programovani/ZX/Forth/RossetaCode$ echo "10 20 30 40" | sed -E 's#(^|^.*\s)([0-9]+)(\s.*$)#1:\1  2:\2  3:\3#g'
1:  2:10  3: 20 30 40
dworkin@dw-A15:~/Programovani/ZX/Forth/RossetaCode$ echo "10 20 30 40" | sed -E 's#(^|^.*\s)([0-9]+)(\s.*?$)#1:\1  2:\2  3:\3#g'
1:  2:10  3: 20 30 40
dworkin@dw-A15:~/Programovani/ZX/Forth/RossetaCode$ echo "10 20 30 40" | sed -E 's#(^|^.*?\s)([0-9]+)(\s.*?$)#1:\1  2:\2  3:\3#g'
1:  2:10  3: 20 30 40


Teorie je ze .* je greedy a necha zbytku az posledni moznost na shodu (posledni vyskyt). .*? to ma prepnout na nalezeni prvniho vyskytu. Tolik teorie z netu, ale je to zavisle v cem to delate...

PS: Stezovani funguje! Mam to! Spravne je "*?" a ne ".*?".
PPS: Tak ne nefunguje to, dela to neco jineho...

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 26.07.2023, 16:18 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Nasel jsem docela vtipne reseni na soucet dvou neznamych hodnot v retezci.

mam tam neco jako:

+abc-abc
-10*abc+abc
+1*abc-42*abc
-abc+5*abc

druha varianta kde nemusi byt uvodni znamenko ted nebudu ukazovat, ale je to podobne.

Podarilo se me tyto 4 reseni napsat jako jeden regexp

Prvne se hleda se zapamatovanim [-\+] plusko musim escapovat protoze je to specialni znak na nalezeni jednoho a vice vyskytu predchoziho ..neceho. A aby se to zapamatovalo tak je to v escapovanych zavorakch takze zaciname \([-\+]\) A jeste to minusko davam na zacatek, protoze uz jsem se spalil ze to bralo jako rozsah... mel jsem [\+-\*] a on to bral jako +..*

Pak se hleda cislo nasledovane * a nebo nic...

\([0-9]+\*\)? ...kde [0-9]+ je cislo s aspon jednou cifrou a pak escapovany *, protoze je to zase specialni znak. Cele je to pro zapamatovani v zavorce a za tim ? rika ze to muze byt jen jednou a nebo vubec

V treti casti se hleda ten retezec, bez znamenka protoze musim najit shodu bez ohledu na druhe znamenko.

\([_a-zA-Z][_a-zA-Z0-9]*\)

Ctvrta cast je stejna jako prvni hledame znamenko

Pata cast je zase najit cislo se znakem *, stejny postup jako v druhe casti

Sesta musi odpovidat treti, takze jde napsat \3 a v regexpu se to doplni co jsme nasli v treti casti. Netusil jsem ze to jde takhle primo vkladat v jeste hledane casti, vzdy jsem to pouzival az ve vysledku co to naslo.

Ve vysledku mam v

\1 a \4 znamenka
\2 a \5 jsou cisla s * a nebo nic
\3 je nazev promenne

Jak vyresit ze jednou mam prazdny retezec a ten chci nahradit za 1 a nebo mam cislo s * a tam chci odstranit *?

staci napsat eval(\1\2 1 \4\5 1)

to se zmeni na (+50* 1 -3* 1)
a nebo ( + 1 + 20*1)
a nebo ( - 1 +1)

Takze vystup bude "+eval(\1\2 1 \4\5 1)*\3"

a tak umim spocitat neznamou v retezci

+10*xxx-xxx --> "+9*xxx"

Kód:
dnl # 1     2  3       4   5  6       7
dnl # begin +- 50*/nul abc +- 20*/nul abc end
...,,,
__{}__{}regexp({$1},                                                   {^\(.*\)\([-\+]\)\([0-9]+\*\)?\([_a-zA-Z][_a-zA-Z0-9]*\)\([-\+]\)\([0-9]+\*\)?\4\([-\+!=<>&|^)].*$\|$\)}),0,{dnl # "-2*abc+6*abc" --> "+4*abc"
__{}__{}__{}ifelse(__DEBUG_$0,1,{errprint(__CR{±3*x±5*x:"}regexp({$1}, {^\(.*\)\([-\+]\)\([0-9]+\*\)?\([_a-zA-Z][_a-zA-Z0-9]*\)\([-\+]\)\([0-9]+\*\)?\4\([-\+!=<>&|^)].*$\|$\)},{\1\(fce(\2\3{1},\5\6{1})\*\4)\7}){"}__CR)}){}dnl
__{}__{}__{}$0(regexp({$1},                                            {^\(.*\)\([-\+]\)\([0-9]+\*\)?\([_a-zA-Z][_a-zA-Z0-9]*\)\([-\+]\)\([0-9]+\*\)?\4\([-\+!=<>&|^)].*$\|$\)},{\1+eval(\2\3{1}\5\6{1})\*\4\7}))},

dnl # 1     2      3       4   5  6       7
dnl # begin +-/nul 50*/nul abc +- 20*/nul abc end
...,,,
__{}__{}regexp({$1},                                                  {\(^\|^.*[=<>&^|(]\)\([-\+]?\)\([0-9]+\*\)?\([_a-zA-Z][_a-zA-Z0-9]*\)\([-\+]\)\([0-9]+\*\)?\4\([-\+!=<>&|^)].*$\|$\)}),0,{dnl # "-2*abc+6*abc" --> "+4*abc"
__{}__{}__{}ifelse(__DEBUG_$0,1,{errprint(__CR{3*x±5*x:"}regexp({$1}, {\(^\|^.*[=<>&^|(]\)\([-\+]?\)\([0-9]+\*\)?\([_a-zA-Z][_a-zA-Z0-9]*\)\([-\+]\)\([0-9]+\*\)?\4\([-\+!=<>&|^)].*$\|$\)},{\1\(fce(\2\3{1},\5\6{1})\*\4)\7}){"}__CR)}){}dnl
__{}__{}__{}$0(regexp({$1},                                           {\(^\|^.*[=<>&^|(]\)\([-\+]?\)\([0-9]+\*\)?\([_a-zA-Z][_a-zA-Z0-9]*\)\([-\+]\)\([0-9]+\*\)?\4\([-\+!=<>&|^)].*$\|$\)},{\1+eval(\2\3{1}\5\6{1})\*\4\7}))},


Cely je to teda jeste komplikovanejsi protoze musite osetrit kdy to muzete provest. Kdyz to zacina/konci "nicim". Nebo zacina ( a konci ) a nebo zacina konci operatory o stejne priorite, teda + -. Nebo to zacina nebo konci operatory o nizsi priorite, teda >> << == !== > >= <= < & | && ||. Atd.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 28.07.2023, 21:17 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Opravil jsem nejake chyby na __SIMPLIFY_EXPRESSION.

A ted ze to nekde pouziji...

nasel jsem perfektni misto kde by se to hodilo... jenze... nastal problem.

V nejednoznacnosti co je pointer a co je vyraz v zavorkach.

Celou dobu jsem si to nejak hlidal, kde to jednou mohl byt vyraz a podruhe zase vzdy pointer, ale __SIMPLIFY_EXPRESSION to proste nemuze delat dvema zpusoby. Tam jsem si jen hlidal ze pokud je to cele v zavorce tak je to pointer.

Ale zrovna bych to potreboval pouzit kdy na vstupu muze byt neco jako (0x8000) + 1.

napriklad fce co nahrava do registru HL nejakou hodnotu a mohu ji predat i parametry co maji ostatni registry aby se mohla lepe rozhodnout...

ja ji predam ze chci HL=(0x8000) a ze ted je v HL = (0x8000)+1 a ocekavam ze najde reseni "dec HL".

Kvuli tomuhle jsem resil nejake silenosti v retezcich kdyz jsem porovnaval retezce

"$1" == "1+$2-1" --> $1 == $2
"$1" == "$2+0" --> $1 == $2
"$1" == "$2-0" --> $1 == $2
"$1" == "0+$2" --> $1 == $2


"$1" == "$2+1" --> $1 == dec($2)
"$1" == "1+$2" --> $1 == dec($2)
"$1" == "$2-1" --> $1 == inc($2)

atd. s tim ze proste vsechny varianty takto stejne nikdy neporovnam napr.

"$1" == "$2+5-4" asi tezko budu porovnavat i kdyz plati --> $1 == dec($2)
"$1" == "5+$2-4" asi tezko budu porovnavat i kdyz plati --> $1 == dec($2)

Takze pouziji prvne __SIMPLIFY_EXPRESSION na prevod hodnot na nejaky standardni vystup jako je "5+abc-4" --> "1+abc" a kdyz vim ze takhle mam konstantu vzdy na zacatku je uz snadne porovnavat. (ne ze by to nemelo jeste jine problemy jako ze me to neradi viz jmen podle abecedy).

jenze pak me to najde shodu napriklad u (0x8000)+1 a 32768.

Co s tim? Pouzit intel syntaxi a vnitrne mit pointer jen jako [...].

To si vyzada zmeny na spouste mist kodu a asi nekde neco zapomenu a bude tam chyba...

Ale i tak jsem se do toho pustil a zacal primo s __SIMPLIFY_EXPRESSION

Tam jsem narazil na to ze uvnitr [...] nefunguje exscapovani.... vyresil jsem to slozite pomoci "nebo"

[...\]...] ---> ] \| [....] ale nemuzu tak vyresit vnorene pointery. Ale to snad nikdy nebude potreba aby nekdo dal na vstup:

[adresa + [adresa_2]]

Pak jsem se dival na uplne nejsnazsi PUSH kde davam neco do HL

a schvalne jsem nechal

misto

ld HL, (adresa)

jen

ld HL,[adresa]

a pasmo to normalne zkompilovalo spravne!

a sjasmplus taky!

Proc to tak neresim celou dobu? S timhle je jednoznacne co je adresa a co vyraz v zavorce. Jedine co si musim ohlidat je ze nikdy nesmi vyraz v zavorce zacinat (.
Ale uz ted me to prevadi (...)*5 na 5*(...).
Takze staci jeste pridat dalsi pravidlo pro ruseni zavorek ze pokud je to cele v zavorce tak ji mohu zrusit.
Pak uz jen zbyva
(....)/...
a
(....)%....

A tam staci pridat na konci na zacatek +

To bude jeste dlouha cesta, ale s (adresa) koncim, odted jen [adresa].

PS: Jeste teda budu muset prejmenovat __IS_MEM_REF() na __USE_PTR() protoze to je to co to dela dosud. A pridat __IS_PTR()

Potrebuji neco co identifikuje ze ani pasmo/sjasmplus nezna hodnotu, protoze vyraz obsahuje pointer a pak potrebuji neco co me rekne ze to je cele pointer takze mohu psat:

ld HL, [abc+20*xx]

a ne ze je to neco jako [abc+20*xx]+1

protoze to neni pointer ale vyraz s pointerem a pak je chyba psat

ld HL, [abc+20*xx]+1

a musim generovat vic instrukci

ld HL, [abc+20*xx]
inc HL

takze to cele nemam resit, protoze by cele znamenalo mit neco co generuje kod na jakykoliv vyraz a to by si vyzadalo pouzit vic instrukci, takze prepsat vsechno ostatni, protoze napriklad BC neni zrovna volne, nebo nesmim menit ani priznaky.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 29.07.2023, 12:54 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3675
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 798 times
_dworkin píše:
misto
ld HL, (adresa)
jen
ld HL,[adresa]
a pasmo to normalne zkompilovalo spravne!
a sjasmplus taky!
Ano, pretoze zatvorky [ ] sa v inych (hlavne x86) asembleroch casto pouzivaju na pametovy pristup, preto je tato moznost aj v niektorych Z80 asembleroch.
Dokonca v sjasmplus si mozes urcit, ze na pristup do pameti sa MUSIA pouzivat IBA hranate zatvorky [ ]. Citujem z dokumentacie:
Kód:
Value for --syntax option may consist of multiple letters, omitting letter for particular feature will use the default setting:
  ...
  B      memory access brackets [] required (default = relaxed syntax, [] allowed as extra)
Takze potom gulate ( ) sluzia iba na vyhodnocovanie vyrazov a vobec sa nemusis zdrzovat s prevadzanim veci typu (...)*5 na 5*(...) ;)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 31.07.2023, 02:33 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Jo presne tuhle direktivu ma i pasmo.
Citace:
-B --bracket
Bracket only mode: parenthesis are reserved for expressions.


Na prekladu do cestiny si vylame zuby jak google prekladac tak i chat GPT, pokud ho teda nepostrcis spravnym smerem.
Citace:
Režim pouze hranatých závorek: závorky () jsou vyhrazeny pouze pro výrazy.


Je to fajn, ale ja mam v kodu snad nekolik set pouziti odkazu do pameti a i kdyz jsem to ted nekolik dni predelaval jsem si jisty ze me neco uniklo a dokonce i nejake zasadni veci. (Zato jsem nasel 2 jine chyby)

Mit to strikne nastaveny by bylo fakt super. Ale mam tam i veci jako "ld (), BC" kde je na 100% jasne ze je to ukazatel a ne vyraz.

Pak tam mam in/out instrukce a jeste jsem netesteval zda to vyhodi chybu pri -B nebo je to v poradku.

Protoze jsem vedel ze si rozhasim ten kod tak jsem premyslel jak tohle sakra delaji profesionalove.

Jak vubec na githubu udelat nejaky verzovaci system a ptal se GPT a ta me postupne navedla na neco co bylo pro me nepouzitelne. Nechci delat nejaky velky zip soubor vseho. Takze me poradila "branch" a to se ukazalo jako cesta. Takze mam ted 2 vetve. Jednu ke dni pred zmenou na [] a druhou aktualni (master). Je to trosku otravne, protoze jsem ty 2 chyby musel resit ted ve dvou vetvich, ale lepsi reseni me nenapada.

PS: Rozsireni regexp v Gnu M4 rika ze je to identicke s regexpem emacu. ...ale fakt neni. Protoze ten umi no greedy veci a M4 regexp neumi ani to co zakladni sed. Nastesti me napadlo reseni jak zapsat ] uvnitr [ ... ]. Protoze M4 uvnitr neumi pouzit \, takze pak [^\]] znamena [^\] tedy vse krome znaku \ a pak tam musi nasledovat ].

Ja ale potrebuji udelat [^[\]] tedy jakykoliv znak krome [ nebo ]. Fakt nechci aby me ze vstupu ".....[....]...." kde chci odchytit cast uvnitr [] jsme omylem delal neco jineho kdyz me na vstup prijde tohle ".....[....].....[....]...." a jak pak odchytil "....].....[....".

Muj napad je zapsat to "doplnkove". S pouzitim znaku - jako jednoho z mala specialnich znaku co jeste plati uvnitr [...].

Znak s nejnizsi ascii hodnotou co jsem schopen bezpecne zapsat je tabulator a nejvyssi znak je 127 (~).

Takze [ -Z/^-~] pak znamena od znaku 0x09 do znaku Z, pak je mezere protoze je tam [ nasleduje / a pak je zase mezera protoze tam je ] a pak to pokracuje ^ az ~.

Zvlastni ze na netu nikdo tohle nepouzil. Ale asi nikdo nemel ten problem s \].

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 31.07.2023, 17:11 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Prunik chovani sjasmplus pri "--syntax=B" a pasma pri "-B" je prazdna mnozina...

Ok, prunik je pro chovani pri

ld hl,(0x8000)
ld hl,[0x8000]

oba bez prepinace tohle budou chapat jako ukazatel a oba s prepinacem prvni instrukci budou chapat jako "ld hl,0x8000"

Problem nastane uz u in/out instrukci. Pasmo bez prepinace podporuje obe varianty a s prepinacem skonci s tim ze ocekavalo [ a naslo (.
Sjasmplus naopak nikdy nepodporuje in/out [] a s prepinacem ho stale nepodporuje a ocekava () variantu.

Plus jeste nejake zahadne chovani kdy pri "ld e,(hl)" si mysli ze hl je jmeno labelu, ale to me nedava smysl... a uz dava! on si mysli ze je to:

_hl equ 5
ld e,_hl

Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ cat --number mem.asm
     1    org 0x8000
     2   
     3    ld hl,(0x8000)
     4    ld hl,[0x8000]
     5    
     6    ld e,(hl)
     7    in a,(0xFF)
     8    out (0xFF),a
     9   
    10    ld e,[hl]
    11    in a,[0xFF]
    12    out [0xFF],a
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ sjasmplus --syntax= --lst=mem.lst mem.asm
SjASMPlus Z80 Cross-Assembler v1.20.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
mem.asm(11): error: Syntax error: [0xFF]
mem.asm(11): error: Unexpected: [0xFF]
mem.asm(12): error: Syntax error: [0xFF],a
Pass 3 complete
Errors: 3, warnings: 0, compiled: 13 lines, work time: 0.001 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ sjasmplus --syntax=B --lst=mem.lst mem.asm
SjASMPlus Z80 Cross-Assembler v1.20.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
mem.asm(6): error: Label not found: hl
mem.asm(11): error: Syntax error: [0xFF]
mem.asm(11): error: Unexpected: [0xFF]
mem.asm(12): error: Syntax error: [0xFF],a
Pass 3 complete
Errors: 4, warnings: 0, compiled: 13 lines, work time: 0.001 seconds
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ pasmo -d mem.asm mem.bin
      ORG 8000
8000:2A0080   LD HL, (8000)
8003:2A0080   LD HL, (8000)
8006:5E      LD E, (HL)
8007:DBFF   IN A, (FF)
8009:D3FF   OUT(FF), A
800B:5E      LD E, (HL)
800C:DBFF   IN A, (FF)
800E:D3FF   OUT(FF), A
Emiting raw binary from 8000 to 800F
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ pasmo -B -d mem.asm mem.bin
ERROR: Value expected but 'HL' found  on line 6 of file mem.asm
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ cat mem.asm
 org 0x8000

 ld hl,(0x8000)
 ld hl,[0x8000]
 
;  ld e,(hl)
 in a,(0xFF)
 out (0xFF),a

 ld e,[hl]
 in a,[0xFF]
 out [0xFF],a
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ pasmo -B -d mem.asm mem.bin
ERROR: Expected '[' but '(' found  on line 7 of file mem.asm
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ cat mem.asm
 org 0x8000

 ld hl,(0x8000)
 ld hl,[0x8000]
 
;  ld e,(hl)
;  in a,(0xFF)
 out (0xFF),a

 ld e,[hl]
 in a,[0xFF]
 out [0xFF],a
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ pasmo -B -d mem.asm mem.bin
ERROR: Expected '[' but '(' found  on line 8 of file mem.asm
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ cat mem.asm
 org 0x8000

 ld hl,(0x8000)
 ld hl,[0x8000]
 
;  ld e,(hl)
;  in a,(0xFF)
;  out (0xFF),a

 ld e,[hl]
 in a,[0xFF]
 out [0xFF],a
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ pasmo -B -d mem.asm mem.bin
      ORG 8000
8000:210080   LD HL, 8000
8003:2A0080   LD HL, (8000)
8006:5E      LD E, (HL)
8007:DBFF   IN A, (FF)
8009:D3FF   OUT(FF), A
Emiting raw binary from 8000 to 800A
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 01.08.2023, 05:28 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Smutne jak pri opakovanem spousteni testu skoro polovina znovu nefunguje...

U jednoho me to hazelo zvlastni chybu kdy me to pridavalo znak ) do kodu. Snazil jsem se to zuzit na konkretni token, ale nejak se me to nedarilo. Musely tam byt 2 a to jeste kdyz se zmenil jeden tak chyba zmizla a to same kdyz jsem zmenil druhy token. Pritom nikde ty tokeny navzajem neiteragovaly...

Ukazalo se ze kdyz jsem zmenil v M4 znak pro komentar z # na kombinaci ;# tak to nebylo tak bezpecne jak jsem si myslel.
Trochu me predtim i udivilo ze to v urcitem pripade funguje... ale malo jsem testoval. Nenapadlo me to zkombinovat chyby.

Mel jsem v kodu v casti komentare za ; neco jako

; jmeno_tokenu # nastaveni jde zmenit pres define({JMENO},default)

a to ze se neaktivovalo to define ale vypsalo jako text bylo zarizeno tim ze to lezelo za #.

Takze jsem hromadne menil # za ;# a snad je to ok.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 07.08.2023, 16:00 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Predelal jsem rekurzivni smycky pokud prekladac nezna STOP hodnotu, protoze si ji taha ze stacku.

Da se rici ze jsem celkove zkratil kod a i zrychlil na jeden pruchod smyckou za cenu toho ze na zacatku je delsi a komplikovanejsi DO slovo. Je to stejny princip jako jsem delal u smycek kde znam vsechny hodnoty a kde "LOOP" uklada aktualizovany index az po zpetnem skoku na konec "DO".

Jen je to komplikovanejsi v tom ze pokud znam vse tak si musim ukladat jen "index" a ted za nim musim ukladat i "stop" hodnotu. Takze me stinove HL (ktere drzi index emulovaneho zasobniku pro RAS) ma ted pri navratu do DO ruzne hodnoty.

[HL] = lo index
[HL+1] = hi index
[HL+2] = lo stop
[HL+3] = hi stop

Predtim to vracelo HL zvysene o 1 ted je to bud o 2 a nebo o 3, podle toho zda uz u lo stop nezjistime ze muzeme smycku opakovat.

"DO" provadi ukladani hodnot, kde prvne ulozi "hi stop" pak "lo stop" a pak se ma provest ta spolecna/opakovana cast kdy se uklada prvne "hi index" a pak "lo index" a HL se dostava na puvodni hodnotu.

Ale pri tom skoku z "LOOP" nechci opakovane ukladat "lo stop" takze v tom "DO" udelam neco navic..
Kód:
HL--
[HL] = hi stop
HL--
[HL] = lo stop

HL++
skok_pri_hl_plus_3:   ; [hl] ukazuje na hi stop
HL--

skok_pri_hl_plus_2:   ; [hl] ukazuje na lo stop
HL--
[HL] = hi index
HL--
[HL] = lo index

Cele se to jeste vic komplikuje tim ze musim prevadet hodnoty z HL(tos), DE(nos) do stinovych registru a zaroven do novych TOS a NOS nacist co je za tim. Jedna hodnota je jeste v pohode, to se da udelat pres EX (SP),HL ale jak jsou dve tak prvni blokuje druhou. Takze se musi bud kopirovat do BC nebo to udelat 2x, coz se ukazuje vyhodnejsi protoze 2x "exx" je levne. Stejne jako 2x "ld reg8, reg8".

Puvodni +1 smycka
Kód:
dworkin@dw-A15:~/Programovani/ZX/M4_FORTH-Version-2023-7-23-/M4$ ../check_word.sh 'DO(R) LOOP'
                       ;[15:116]    do_101(r)   ( stop index -- ) ( R: -- stop index )
    ex  (SP),HL         ; 1:19      do_101(r)
    push DE             ; 1:11      do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = stop
    dec  HL             ; 1:6       do_101(r)
    ld  (HL),D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  (HL),E          ; 1:7       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = index
    dec  HL             ; 1:6       do_101(r)
    ld  (HL),D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  (HL),E          ; 1:7       do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)
do101:                  ;           do_101(r)
    exx                 ; 1:4       loop_101(r)
    ld    E,(HL)        ; 1:7       loop_101(r)
    inc   L             ; 1:4       loop_101(r)
    ld    D,(HL)        ; 1:7       loop_101(r)   DE = index
    inc  HL             ; 1:6       loop_101(r)
    inc  DE             ; 1:6       loop_101(r)   index++
    ld    A,(HL)        ; 1:7       loop_101(r)
    xor   E             ; 1:4       loop_101(r)   lo(index ^ stop)
    jr   nz, $+8        ; 2:7/12    loop_101(r)
    ld    A, D          ; 1:4       loop_101(r)
    inc   L             ; 1:4       loop_101(r)
    xor (HL)            ; 1:7       loop_101(r)   hi(index ^ stop)
    jr    z, leave101   ; 2:7/12    loop_101(r)   exit
    dec   L             ; 1:4       loop_101(r)
    dec  HL             ; 1:6       loop_101(r)
    ld  (HL), D         ; 1:7       loop_101(r)
    dec   L             ; 1:4       loop_101(r)
    ld  (HL), E         ; 1:7       loop_101(r)
    exx                 ; 1:4       loop_101(r)
    jp   do101          ; 3:10      loop_101(r)
leave101:               ;           loop_101(r)
    inc  HL             ; 1:6       loop_101(r)
    exx                 ; 1:4       loop_101(r)
exit101:                ;           loop_101(r)
; seconds: 1           ;[41:242]


Nove +1 smycka
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'DO(R) LOOP'
                       ;[19:132]    do_101(r)   ( stop index -- ) ( R: -- stop index )
    ex  [SP],HL         ; 1:19      do_101(r)
    push DE             ; 1:11      do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = stop
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = index
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)
    exx                 ; 1:4       do_101(r)
    inc   L             ; 1:4       do_101(r)
do101save1:             ;           do_101(r)   R:( stop index -- stop index )
    dec   L             ; 1:4       do_101(r)
do101save2:             ;           do_101(r)   
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    exx                 ; 1:4       do_101(r)
                       ;[19:90]     loop_101(r)   ( R: stop index -- stop index )
    exx                 ; 1:4       loop_101(r)
    ld    E,[HL]        ; 1:7       loop_101(r)
    inc   L             ; 1:4       loop_101(r)
    ld    D,[HL]        ; 1:7       loop_101(r)   DE = index
    inc  HL             ; 1:6       loop_101(r)
    inc  DE             ; 1:6       loop_101(r)   index++
    ld    A,[HL]        ; 1:7       loop_101(r)
    xor   E             ; 1:4       loop_101(r)   lo(index ^ stop)
    jp   nz, do101save2 ; 3:10      loop_101(r)
    ld    A, D          ; 1:4       loop_101(r)
    inc   L             ; 1:4       loop_101(r)
    xor [HL]            ; 1:7       loop_101(r)   hi(index ^ stop)
    jp   nz, do101save1 ; 3:10      loop_101(r)
leave101:               ;           loop_101(r)
    inc  HL             ; 1:6       loop_101(r)
    exx                 ; 1:4       loop_101(r)
exit101:                ;           loop_101(r)
; seconds: 1           ;[38:222]


Puvodni -1 smycka
Kód:
dworkin@dw-A15:~/Programovani/ZX/M4_FORTH-Version-2023-7-23-/M4$ ../check_word.sh 'DO(R) PUSH(-1) ADDLOOP'
                       ;[15:116]    do_101(r)   ( stop index -- ) ( R: -- stop index )
    ex  (SP),HL         ; 1:19      do_101(r)
    push DE             ; 1:11      do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = stop
    dec  HL             ; 1:6       do_101(r)
    ld  (HL),D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  (HL),E          ; 1:7       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = index
    dec  HL             ; 1:6       do_101(r)
    ld  (HL),D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  (HL),E          ; 1:7       do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)
do101:                  ;           do_101(r)
    exx                 ; 1:4       -1 +loop_101(r)
    ld    E,(HL)        ; 1:7       -1 +loop_101(r)
    inc   L             ; 1:4       -1 +loop_101(r)
    ld    D,(HL)        ; 1:7       -1 +loop_101(r)   DE = index
    inc  HL             ; 1:6       -1 +loop_101(r)
    ld    A,(HL)        ; 1:7       -1 +loop_101(r)
    xor   E             ; 1:4       -1 +loop_101(r)   lo index - stop
    jr   nz, $+8        ; 2:7/12    -1 +loop_101(r)
    inc   L             ; 1:4       -1 +loop_101(r)
    ld    A,(HL)        ; 1:7       -1 +loop_101(r)
    xor   D             ; 1:4       -1 +loop_101(r)   hi index - stop
    jr    z, leave101   ; 2:7/12    -1 +loop_101(r)   exit
    dec   L             ; 1:4       -1 +loop_101(r)
    dec  HL             ; 1:6       -1 +loop_101(r)
    dec  DE             ; 1:6       -1 +loop_101(r)   index--
    ld  (HL), D         ; 1:7       -1 +loop_101(r)
    dec   L             ; 1:4       -1 +loop_101(r)
    ld  (HL), E         ; 1:7       -1 +loop_101(r)
    exx                 ; 1:4       -1 +loop_101(r)
    jp   do101          ; 3:10      -1 +loop_101(r)
leave101:               ;           -1 +loop_101(r)
    inc  HL             ; 1:6       -1 +loop_101(r)
    exx                 ; 1:4       -1 +loop_101(r)
exit101:                ;           -1 +loop_101(r)
; seconds: 0           ;[41:242]


Nove -1 smycka je o neco slozitejsi nez +1 smycka, protoze snizuji STOP o 1 uz v DO, abych mohl testovat konec az PO snizeni "indexu" a mohl tak snadno skakat uz po testu "low" casti.
Tohle se musi vsude ohlidat ze to bude pasovat s jakymkoliv LOOP (ze vi ze STOP je snizen).
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'DO(R) PUSH(-1) ADDLOOP'
                       ;[20:138]    do_101(r)   ( stop index -- ) ( R: -- stop-1 index )
    ex  [SP],HL         ; 1:19      do_101(r)
    push DE             ; 1:11      do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = stop
    dec  DE             ; 1:6       do_101(r)   DE = stop-1
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = index
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)
    exx                 ; 1:4       do_101(r)
    inc   L             ; 1:4       do_101(r)
do101save1:             ;           do_101(r)   R:( stop-1 index -- stop-1 index )
    dec   L             ; 1:4       do_101(r)
do101save2:             ;           do_101(r)   
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    exx                 ; 1:4       do_101(r)
                       ;[19:90]     -1 +loop_101(r)   ( R: stop-1 index -- stop-1 index )
    exx                 ; 1:4       -1 +loop_101(r)
    ld    E,[HL]        ; 1:7       -1 +loop_101(r)
    inc   L             ; 1:4       -1 +loop_101(r)
    ld    D,[HL]        ; 1:7       -1 +loop_101(r)   DE = index
    inc  HL             ; 1:6       -1 +loop_101(r)
    dec  DE             ; 1:6       -1 +loop_101(r)   index--
    ld    A,[HL]        ; 1:7       -1 +loop_101(r)
    xor   E             ; 1:4       -1 +loop_101(r)   lo8(--index ^ --stop)
    jp   nz, do101save2 ; 3:10      -1 +loop_101(r)
    inc   L             ; 1:4       -1 +loop_101(r)
    ld    A,[HL]        ; 1:7       -1 +loop_101(r)
    xor   D             ; 1:4       -1 +loop_101(r)   hi8(--index ^ --stop)
    jp   nz, do101save1 ; 3:10      -1 +loop_101(r)
leave101:               ;           -1 +loop_101(r)
    inc  HL             ; 1:6       -1 +loop_101(r)
    exx                 ; 1:4       -1 +loop_101(r)
exit101:                ;           -1 +loop_101(r)
; seconds: 1           ;[39:228]

Puvodni s obecnym/neznamym "step"
Kód:
dworkin@dw-A15:~/Programovani/ZX/M4_FORTH-Version-2023-7-23-/M4$ ../check_word.sh 'DO(R) PUSH(step) ADDLOOP'
                       ;[15:116]    do_101(r)   ( stop index -- ) ( R: -- stop index )
    ex  (SP),HL         ; 1:19      do_101(r)
    push DE             ; 1:11      do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = stop
    dec  HL             ; 1:6       do_101(r)
    ld  (HL),D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  (HL),E          ; 1:7       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = index
    dec  HL             ; 1:6       do_101(r)
    ld  (HL),D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  (HL),E          ; 1:7       do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)
do101:                  ;           do_101(r)
                       ;[38:170]    step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)
    ld   BC, step       ; 3:10      step +loop_101(r)   BC = step
    ld    E,(HL)        ; 1:7       step +loop_101(r)
    ld    A, E          ; 1:4       step +loop_101(r)
    add   A, C          ; 1:4       step +loop_101(r)
    ld  (HL),A          ; 1:7       step +loop_101(r)
    inc   L             ; 1:4       step +loop_101(r)
    ld    D,(HL)        ; 1:7       step +loop_101(r)   DE = index
    ld    A, D          ; 1:4       step +loop_101(r)
    adc   A, B          ; 1:4       step +loop_101(r)
    ld  (HL),A          ; 1:7       step +loop_101(r)
    inc  HL             ; 1:6       step +loop_101(r)
    ld    A, E          ; 1:4       step +loop_101(r)
    sub (HL)            ; 1:7       step +loop_101(r)
    ld    E, A          ; 1:4       step +loop_101(r)
    inc   L             ; 1:4       step +loop_101(r)
    ld    A, D          ; 1:4       step +loop_101(r)
    sbc   A,(HL)        ; 1:7       step +loop_101(r)
    ld    D, A          ; 1:4       step +loop_101(r)   DE = index-stop
    ld    A, E          ; 1:4       step +loop_101(r)
    add   A, C          ; 1:4       step +loop_101(r)
    ld    A, D          ; 1:4       step +loop_101(r)
    adc   A, B          ; 1:4       step +loop_101(r)
    xor   D             ; 1:4       step +loop_101(r)
    jp    m, $+10       ; 3:10      step +loop_101(r)
    dec   L             ; 1:4       step +loop_101(r)
    dec  HL             ; 1:6       step +loop_101(r)
    dec   L             ; 1:4       step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)
    jp   do101         ; 3:10      step +loop_101(r)   ( -- ) R:( stop index -- stop index+step )
leave101:               ;           step +loop_101(r)
    inc  HL             ; 1:6       step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)   ( -- ) R:( stop index -- )
exit101:                ;           step +loop_101(r)
; seconds: 0           ;[53:286]

Nova varianta s neznamym "step". Mimochodem tady jsem se na dlouho zasekl jak to zapsat, protoze jsem delal neustale chyby...
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'DO(R) PUSH(step) ADDLOOP'
                       ;[19:132]    do_101(r)   ( stop index -- ) ( R: -- stop index )
    ex  [SP],HL         ; 1:19      do_101(r)
    push DE             ; 1:11      do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = stop
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = index
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)
    exx                 ; 1:4       do_101(r)
    inc   L             ; 1:4       do_101(r)
do101save1:             ;           do_101(r)   R:( stop index -- stop index )
    dec   L             ; 1:4       do_101(r)
do101save2:             ;           do_101(r)   
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    exx                 ; 1:4       do_101(r)
                       ;[28:138]    step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)
    ld    E,[HL]        ; 1:7       step +loop_101(r)
    inc   L             ; 1:4       step +loop_101(r)
    ld    D,[HL]        ; 1:7       step +loop_101(r)   DE = index
    inc  HL             ; 1:6       step +loop_101(r)
    ld    C,[HL]        ; 1:7       step +loop_101(r)
    inc   L             ; 1:4       step +loop_101(r)
    ld    B,[HL]        ; 1:7       step +loop_101(r)   BC = stop
    ex   DE, HL         ; 1:4       step +loop_101(r)
    or    A             ; 1:4       step +loop_101(r)
    sbc  HL, BC         ; 2:15      step +loop_101(r)   HL = index-stop
    ld    A, low step   ; 2:7       step +loop_101(r)   lo8(step)
    add   A, L          ; 1:4       step +loop_101(r)
    ld    L, A          ; 1:4       step +loop_101(r)
    ld    A, high step  ; 2:7       step +loop_101(r)   hi8(step)
    adc   A, H          ; 1:4       step +loop_101(r)
    ld    H, A          ; 1:4       step +loop_101(r)   HL = index-stop+step
    sbc   A, A          ; 1:4       step +loop_101(r)   save carry to sign
    add  HL, BC         ; 1:11      step +loop_101(r)   HL = index+step
    ex   DE, HL         ; 1:4       step +loop_101(r)
if (((step) & 0x8000) = 0)
    jp    p, do101save1 ; 3:10      step +loop_101(r)
else
    jp    m, do101save1 ; 3:10      step +loop_101(r)
endif
leave101:               ;           step +loop_101(r)
    inc  HL             ; 1:6       step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)   ( -- ) R:( stop index -- )
exit101:                ;           step +loop_101(r)
; seconds: 1           ;[50:280]

To same jen znam pocatek, puvodni varianta
Kód:
dworkin@dw-A15:~/Programovani/ZX/M4_FORTH-Version-2023-7-23-/M4$ ../check_word.sh 'PUSH(begin) DO(R) PUSH(step) ADDLOOP'
                       ;[15:95]     begin do_101(r)   ( stop begin -- ) ( R: -- stop begin )
    ex  (SP),HL         ; 1:19      begin do_101(r)
    exx                 ; 1:4       begin do_101(r)
    pop  DE             ; 1:10      begin do_101(r)   DE = stop
    dec  HL             ; 1:6       begin do_101(r)
    ld  (HL),D          ; 1:7       begin do_101(r)
    dec   L             ; 1:4       begin do_101(r)
    ld  (HL),E          ; 1:7       begin do_101(r)
    dec  HL             ; 1:6       begin do_101(r)
    ld  (HL),high begin ; 2:10      begin do_101(r)   hi index
    dec  L              ; 1:4       begin do_101(r)
    ld  (HL),low begin  ; 2:10      begin do_101(r)   lo index
    exx                 ; 1:4       begin do_101(r)
    ex   DE, HL         ; 1:4       begin do_101(r)
do101:                  ;           begin do_101(r)
                       ;[38:170]    step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)
    ld   BC, step       ; 3:10      step +loop_101(r)   BC = step
    ld    E,(HL)        ; 1:7       step +loop_101(r)
    ld    A, E          ; 1:4       step +loop_101(r)
    add   A, C          ; 1:4       step +loop_101(r)
    ld  (HL),A          ; 1:7       step +loop_101(r)
    inc   L             ; 1:4       step +loop_101(r)
    ld    D,(HL)        ; 1:7       step +loop_101(r)   DE = index
    ld    A, D          ; 1:4       step +loop_101(r)
    adc   A, B          ; 1:4       step +loop_101(r)
    ld  (HL),A          ; 1:7       step +loop_101(r)
    inc  HL             ; 1:6       step +loop_101(r)
    ld    A, E          ; 1:4       step +loop_101(r)
    sub (HL)            ; 1:7       step +loop_101(r)
    ld    E, A          ; 1:4       step +loop_101(r)
    inc   L             ; 1:4       step +loop_101(r)
    ld    A, D          ; 1:4       step +loop_101(r)
    sbc   A,(HL)        ; 1:7       step +loop_101(r)
    ld    D, A          ; 1:4       step +loop_101(r)   DE = index-stop
    ld    A, E          ; 1:4       step +loop_101(r)
    add   A, C          ; 1:4       step +loop_101(r)
    ld    A, D          ; 1:4       step +loop_101(r)
    adc   A, B          ; 1:4       step +loop_101(r)
    xor   D             ; 1:4       step +loop_101(r)
    jp    m, $+10       ; 3:10      step +loop_101(r)
    dec   L             ; 1:4       step +loop_101(r)
    dec  HL             ; 1:6       step +loop_101(r)
    dec   L             ; 1:4       step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)
    jp   do101         ; 3:10      step +loop_101(r)   ( -- ) R:( stop index -- stop index+step )
leave101:               ;           step +loop_101(r)
    inc  HL             ; 1:6       step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)   ( -- ) R:( stop index -- )
exit101:                ;           step +loop_101(r)
; seconds: 1           ;[53:265]

Nova varianta kdyz znam pocatek
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'PUSH(begin) DO(R) PUSH(step) ADDLOOP'
                       ;[18:107]    begin do_101(r)   ( stop -- ) ( R: -- stop index )
    ex  [SP],HL         ; 1:19      begin do_101(r)
    ex   DE, HL         ; 1:4       begin do_101(r)
    exx                 ; 1:4       begin do_101(r)
    pop  DE             ; 1:10      begin do_101(r)   DE = stop
    dec  HL             ; 1:6       begin do_101(r)
    ld  [HL],D          ; 1:7       begin do_101(r)
    dec   L             ; 1:4       begin do_101(r)
    ld  [HL],E          ; 1:7       begin do_101(r)
    ld   DE,begin       ; 3:10      begin do_101(r)   DE = index
    inc   L             ; 1:4       begin do_101(r)
do101save1:             ;           begin do_101(r)   R:( stop index -- stop index )
    dec   L             ; 1:4       begin do_101(r)
do101save2:             ;           begin do_101(r)   
    dec  HL             ; 1:6       begin do_101(r)
    ld  [HL],D          ; 1:7       begin do_101(r)
    dec   L             ; 1:4       begin do_101(r)
    ld  [HL],E          ; 1:7       begin do_101(r)
    exx                 ; 1:4       begin do_101(r)
                       ;[28:138]    step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)
    ld    E,[HL]        ; 1:7       step +loop_101(r)
    inc   L             ; 1:4       step +loop_101(r)
    ld    D,[HL]        ; 1:7       step +loop_101(r)   DE = index
    inc  HL             ; 1:6       step +loop_101(r)
    ld    C,[HL]        ; 1:7       step +loop_101(r)
    inc   L             ; 1:4       step +loop_101(r)
    ld    B,[HL]        ; 1:7       step +loop_101(r)   BC = stop
    ex   DE, HL         ; 1:4       step +loop_101(r)
    or    A             ; 1:4       step +loop_101(r)
    sbc  HL, BC         ; 2:15      step +loop_101(r)   HL = index-stop
    ld    A, low step   ; 2:7       step +loop_101(r)   lo8(step)
    add   A, L          ; 1:4       step +loop_101(r)
    ld    L, A          ; 1:4       step +loop_101(r)
    ld    A, high step  ; 2:7       step +loop_101(r)   hi8(step)
    adc   A, H          ; 1:4       step +loop_101(r)
    ld    H, A          ; 1:4       step +loop_101(r)   HL = index-stop+step
    sbc   A, A          ; 1:4       step +loop_101(r)   save carry to sign
    add  HL, BC         ; 1:11      step +loop_101(r)   HL = index+step
    ex   DE, HL         ; 1:4       step +loop_101(r)
if (((step) & 0x8000) = 0)
    jp    p, do101save1 ; 3:10      step +loop_101(r)
else
    jp    m, do101save1 ; 3:10      step +loop_101(r)
endif
leave101:               ;           step +loop_101(r)
    inc  HL             ; 1:6       step +loop_101(r)
    exx                 ; 1:4       step +loop_101(r)   ( -- ) R:( stop index -- )
exit101:                ;           step +loop_101(r)
; seconds: 1           ;[49:255]

atd. Je toho mnohem vic. Nebudu to ukazovat vsechno.

Puvodni test na rekurzivni smycky byl velky po kompilaci 29208 bajtu. Nove je to 28140 bajtu.

PS: Cilem je to dostat do stavu kdy budu moci pouzit casto pouzivane slovo "DO I" a diky tomu ze "DO" ted uklada aktualizovany "index" to bude o dost snazsi.
Puvodni:
Kód:
dworkin@dw-A15:~/Programovani/ZX/M4_FORTH-Version-2023-7-23-/M4$ ../check_word.sh 'DO(R) I'
                       ;[15:116]    do_101(r)   ( stop index -- ) ( R: -- stop index )
    ex  (SP),HL         ; 1:19      do_101(r)
    push DE             ; 1:11      do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = stop
    dec  HL             ; 1:6       do_101(r)
    ld  (HL),D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  (HL),E          ; 1:7       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = index
    dec  HL             ; 1:6       do_101(r)
    ld  (HL),D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  (HL),E          ; 1:7       do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)
do101:                  ;           do_101(r)
                        ;           i_101(r)   ( -- i )
                        ;[9:64]     i_101(r)   ( -- i ) ( R: i -- i )
    exx                 ; 1:4       i_101(r)
    ld    E,(HL)        ; 1:7       i_101(r)
    inc   L             ; 1:4       i_101(r)
    ld    D,(HL)        ; 1:7       i_101(r)
    dec   L             ; 1:4       i_101(r)
    push DE             ; 1:11      i_101(r)
    exx                 ; 1:4       i_101(r)
    ex   DE, HL         ; 1:4       i_101(r)
    ex  (SP), HL        ; 1:19      i_101(r)
; seconds: 0           ;[24:180]

Nove je to diky komplikovanejsimu DO delsi:
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'DO(R) I'
                       ;[19:132]    do_101(r)   ( stop index -- ) ( R: -- stop index )
    ex  [SP],HL         ; 1:19      do_101(r)
    push DE             ; 1:11      do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = stop
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = index
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)
    exx                 ; 1:4       do_101(r)
    inc   L             ; 1:4       do_101(r)
do101save1:             ;           do_101(r)   R:( stop index -- stop index )
    dec   L             ; 1:4       do_101(r)
do101save2:             ;           do_101(r)   
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    exx                 ; 1:4       do_101(r)
                        ;           i_101(r)   ( -- i )
                        ;[9:64]     i_101(r)   ( -- i ) ( R: i -- i )
    exx                 ; 1:4       i_101(r)
    ld    E,[HL]        ; 1:7       i_101(r)
    inc   L             ; 1:4       i_101(r)
    ld    D,[HL]        ; 1:7       i_101(r)
    dec   L             ; 1:4       i_101(r)
    push DE             ; 1:11      i_101(r)
    exx                 ; 1:4       i_101(r)
    ex   DE, HL         ; 1:4       i_101(r)
    ex  [SP], HL        ; 1:19      i_101(r)
; seconds: 1           ;[28:196]

ale umozni me to predelat na
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'DO(R) I'
                       ;[19:132]    do_101(r)   ( stop index -- ) ( R: -- stop index )
    ex  [SP],HL         ; 1:19      do_101(r)
    push DE             ; 1:11      do_101(r)
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = stop
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    pop  DE             ; 1:10      do_101(r)   DE = index
    exx                 ; 1:4       do_101(r)
    pop  DE             ; 1:10      do_101(r)
    exx                 ; 1:4       do_101(r)
    inc   L             ; 1:4       do_101(r)
do101save1:             ;           do_101(r)   R:( stop index -- stop index )
    dec   L             ; 1:4       do_101(r)
do101save2:             ;           do_101(r)   
    dec  HL             ; 1:6       do_101(r)
    ld  [HL],D          ; 1:7       do_101(r)
    dec   L             ; 1:4       do_101(r)
    ld  [HL],E          ; 1:7       do_101(r)
    push DE             ; 1:11      do_101(r)  !!!
    exx                 ; 1:4       do_101(r)
    ex   DE, HL         ; 1:4       i_101(r)
    ex  [SP], HL        ; 1:19      i_101(r)
                       ;[22:166]

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 09.08.2023, 16:36 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Tak pro "recurse" variantu smycky uz mam DO_I slovo. Navysoval jsem ten test o promenne definovane jako slova, takze M4 nezna jejich hodnotu, takze se ten test zase zvetsil. Ale DO_I ubere vic jak kilobajt.

Kód:
old: -rw-rw-r-- 1 30485 Aug  9 06:08 test_xloop_r.bin
new: -rw-rw-r-- 1 29231 Aug  9 15:32 test_xloop_r.bin

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
Zobrazit příspěvky za předchozí:  Seřadit podle  
Odeslat nové téma Odpovědět na téma  [ Příspěvků: 598 ]  Přejít na stránku Předchozí  1 ... 34, 35, 36, 37, 38, 39, 40  Další

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 27 návštevníků


Nemůžete zakládat nová témata v tomto fóru
Nemůžete odpovídat v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete přikládat soubory v tomto fóru

Hledat:
Přejít na:  
Založeno na phpBB® Forum Software © phpBB Group
Český překlad – phpBB.cz