OldComp.cz

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


Právě je 09.02.2023, 15:00

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




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 395 ]  Přejít na stránku Předchozí  1 ... 23, 24, 25, 26, 27
Autor Zpráva
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 11.01.2023, 01:16 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 896
Has thanked: 74 times
Been thanked: 136 times
Ve zkratce. Byl jsem v podstate donucen zmenit jmena pomocnych maker.

Mel jsem pro praci s daty posledniho tokenu makra zacinajici jako "__LAST_TOKEN_...".

Casem se ukazalo ze potrebuji zjistit i hodnoty co jsou pred poslednim tokenem tak vznikl "__BEFORELAST_...".

Ani to nestacilo takze jsem zavedl obecne "__BEFORE_X...(parametr)", kde parametr rovnajici se nule je to same jako __LAST_TOKEN a kdyz je tam jedna tak je to jako __BEFORELAST_. S tim ze ne vsechny manipulace atd byly podporovany. Nejvic toho bylo u __LAST_TOKEN.

Kdyz uz jsem mel funkcni __BEFORE_X tak jsem to mohl upravit na "__T_" a prepsat vsechny __LAST_TOKEN a __BEFORELAST.

Napr.
__LAST_TOKEN_NAME --> __T_NAME(0)
__BEFORELAST_TOKEN_NAME --> __T_NAME(1)
__BEFORE_X_NAME --> __T_NAME(2)

Jen jsem musel podporit vsechny varianty.
Umazal jsem moznost kdy se zjistuje cislo a zavedl jen HEX varianty. Ta ma tu vyhodu ze bud vrati cislo jako 0x0012 a to i u ciselneho vyrazu jako (10*1)-9-1 nebo prazdny retezec bez toho ze by vsude kricela chyby.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH((10*1)-9-1) PICK __SHOW_TOKEN(1)'
; name: __TOKEN_DUP
; info: (10*1)-9-1 pick
;items: 0
;param: ()
    push DE             ; 1:11      (10*1)-9-1 pick   ( a -- a a )
    ld    D, H          ; 1:4       (10*1)-9-1 pick
    ld    E, L          ; 1:4       (10*1)-9-1 pick
; seconds: 0           ;[ 3:19]

Pravidlo si najde ze je tam PUSH(0x0000) + PICK a to se prevede na token DUP.
Predtim tam bylo neco jako "save_eval", ale tam se museli pravidla duplikovat u zapornych hodnot.
Jednou se testovala -1 a podruhe 0xFFFF. Ted se testuje jen 0xFFFF.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH((adr))PUSH(-1) OR __SHOW_TOKEN(1)'
; name: __TOKEN_PUSHS
; info: (adr) -1 or
;items: 1
;param: (            0xFFFF)
;array1: >0xFFFF<
;array: 0xFFFF
    push DE             ; 1:11      (adr) -1 or
    ex   DE, HL         ; 1:4       (adr) -1 or
    ld   HL, 0xFFFF     ; 3:10      (adr) -1 or
; seconds: 0           ;[ 5:25]


Pokud mame v testovani nejake EVAL tak se nekdy musi pouzivat trik ze se musi na zacatek pripsat nula aby ten EVAL nerval ze tam je neco jako "> 5". Napr. "eval(0__T_ITEMS(0)>1)" se zmeni na eval(00>1) nebo eval(05>1" a nebo kdyz se to vyhodocuje u prvniho tokenu tak predchozi jeste neexistuje takze se to zmeni na eval(0>1), jinak by se pri prvnim tokenu se vypsalo spoustu chyb.

Citace:
Zakladni makra jsou:
__T_NAME()
__T_INFO()
__T_ITEMS()
__T_PARAM()
__T_ARRAY()

Vypis X-teho parametru pocitano od zacatku(zleva):
__T_ARRAY_1()
__T_ARRAY_2()
__T_ARRAY_3()
__T_ARRAY_4()
__T_ARRAY_5()
__T_ARRAY_6()

Vypis X-teho parametru jako pocitano od konce(zprava)
__T_REVERSE_1()
__T_REVERSE_2()
__T_REVERSE_3()
__T_REVERSE_4()
__T_REVERSE_5()
__T_REVERSE_6()

Vypis X-teho parametru jako hex hodnota 0x0000 pocitano od zacatku(zleva):
__T_HEX_1()
__T_HEX_2()
__T_HEX_3()
__T_HEX_4()
__T_HEX_5()
__T_HEX_6()

Vypis X-teho parametru jako hex hodnota 0x0000 pocitano od konce(zprava)
__T_HEX_REVERSE_1()
__T_HEX_REVERSE_2()
__T_HEX_REVERSE_3()
__T_HEX_REVERSE_4()
__T_HEX_REVERSE_5()
__T_HEX_REVERSE_6()

Vypis X poslednich parametru:
__T_LAST_1_PAR()
__T_LAST_2_PAR()
__T_LAST_3_PAR()
__T_LAST_4_PAR()

Zjisteni zda X-ta hodnota nebo hodnoty jsou cislo ktere dokazi hned vyhodnotit. Tzn. zadny ukazatel nebo neznama promenna.
Vraci TRUE = 1 jen kdyz vsechny jsou cislo.
__T_IS_NUM_1()
__T_IS_NUM_2()
__T_IS_NUM_3()
__T_IS_NUM_4()
__T_IS_NUM_5()
__T_IS_NUM_6()
__T_IS_NUM_1_2()
__T_IS_NUM_1_3()
__T_IS_NUM_1_4()
__T_IS_NUM_2_3()
__T_IS_NUM_2_4()
__T_IS_NUM_3_4()
__T_IS_NUM_1_2_3()
__T_IS_NUM_1_2_3_4()

To same co predchozi jen jsou indexy brane pozpatku.
__T_IS_NUM_REVERSE_1()
__T_IS_NUM_REVERSE_2()
__T_IS_NUM_REVERSE_3()
__T_IS_NUM_REVERSE_4()
__T_IS_NUM_REVERSE_5()
__T_IS_NUM_REVERSE_6()
__T_IS_NUM_REVERSE_2_1()
__T_IS_NUM_REVERSE_3_1()
__T_IS_NUM_REVERSE_4_1()
__T_IS_NUM_REVERSE_3_2()
__T_IS_NUM_REVERSE_4_2()
__T_IS_NUM_REVERSE_4_3()
__T_IS_NUM_REVERSE_3_2_1()
__T_IS_NUM_REVERSE_4_3_2_1()

Zjisteni zda X-ta hodnota nebo hodnoty jsou ukazatele.
Vraci TRUE = 1 kdyz aspon jeden je ukazatek. Je to pak "otravene" pro dalsi testy.
__T_IS_PTR_1()
__T_IS_PTR_2()
__T_IS_PTR_3()
__T_IS_PTR_4()
__T_IS_PTR_5()
__T_IS_PTR_6()
__T_IS_PTR_1_2()
__T_IS_PTR_1_3()
__T_IS_PTR_1_4()
__T_IS_PTR_2_3()
__T_IS_PTR_2_4()
__T_IS_PTR_3_4()
__T_IS_PTR_1_2_3()
__T_IS_PTR_1_2_3_4()

To same co predchozi jen jsou indexy brane pozpatku.
__T_IS_PTR_REVERSE_1()
__T_IS_PTR_REVERSE_2()
__T_IS_PTR_REVERSE_3()
__T_IS_PTR_REVERSE_4()
__T_IS_PTR_REVERSE_5()
__T_IS_PTR_REVERSE_6()
__T_IS_PTR_REVERSE_2_1()
__T_IS_PTR_REVERSE_3_1()
__T_IS_PTR_REVERSE_4_1()
__T_IS_PTR_REVERSE_3_2()
__T_IS_PTR_REVERSE_4_2()
__T_IS_PTR_REVERSE_4_3()
__T_IS_PTR_REVERSE_3_2_1()
__T_IS_PTR_REVERSE_4_3_2_1()

Zbytek co umel jen __LAST_TOKEN, ale stejne to nikde nebylo pouzito. Takze jsem nedelal tyhle kombinace pro IS_PTR atd.
__T_IS_NUM_4_5()
__T_IS_NUM_5_6()
__T_IS_NUM_2_3_4()
__T_IS_NUM_3_4_5()
__T_IS_NUM_4_5_6()


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 11.01.2023, 01:55 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 896
Has thanked: 74 times
Been thanked: 136 times
Dale jsem si hral s pravidlama pro (C/H)STORE.
Tohle slovo ma na zasobniku parametry "number address" a uklada to cislo na tu zadanou adresu a jako vetsina Forth slov tim odstrani parametry.

U toho jsem narazil na kombinace kdy si zachovavam adresu v zasobniku a to co chci ulozit tam vkladam na posledni chvili.

Pokud je adresa v TOS:
PUSH(num) OVER STORE

Pokud je adresa v NOS:
PUSH(num) PUSH(2) PICK STORE

atd.

Tohle jsem se snazil pridat do tokenovych pravidel protoze to tam nebylo.
Zacal jsem ale primo tim ze jsem to rozdelil na

PUSH(num) PUSH(x) PICK.

Kde jsem postupne zvedal x od nuly

x=0

PUSH(0) PICK --> DUP
Pokud pred tim je uz nejake PUSHS tak to muze uz zduplikovat jen posledni parametr a zustat u tokenu PUSHS.

x=1

PUSH(1) PICK --> OVER
Pokud je pred tim jeden parametr v PUSHS tak se to meni na PUSH_OVER
Pokud ji je vic tak to muze uz zduplikovat jen predposledni parametr a zustat u tokenu PUSHS.

x=2 uz zacne byt zajimavejsi protoze se ukazuje, ze nez se hluboko hrabat v zasobniku je lepsi to nejak osulit kombinaci jinych slov. V podstate se pokusime vytahnout neznamou co nejdriv nez zacneme na zasobnik ukladat dalsi hodnoty.

PUSH(2) PICK --> OVER
Pokud je pred tim jeden parametr v PUSHS tak se to meni na OVER_PUSH_SWAP, protoze je to mnohem lepsi nez PUSH(num1) a _2_PICK.
Pokud jsou pred tim dva parametry v PUSHS tak se to meni na DUP_PUSH_SWAP a PUSH_SWAP, protoze je to mnohem lepsi nez PUSH(num1,num2) a _2_PICK.
Pokud ji je vic tak to muze uz zduplikovat jen predpredposledni parametr a zustat u tokenu PUSHS.

x=3

PUSH(3) PICK --> _3_PICK
Pokud je pred tim jeden parametr v PUSHS tak se to meni na _2_PICK a PUSH_SWAP, protoze je to mnohem lepsi PUSH(num1) a _3_PICK.
Pokud jsou pred tim dva parametry v PUSHS tak se to meni na OVER_PUSH_SWAP a PUSH_SWAP, protoze je to mnohem lepsi nez PUSH(num1,num2) a _3_PICK.
Pokud jsou pred tim tri parametry v PUSHS tak se to meni na DUP_PUSH_SWAP a PUSH_SWAP_PUSH_SWAP, protoze je to mnohem lepsi nez PUSH(num1,num2,num3) a _3_PICK.
Pokud ji je vic tak to muze uz zduplikovat jen predpredposledni parametr a zustat u tokenu PUSHS.

x=4
atd.


Tohle nejak fungovalo, jen jsem musel vyresit jak zapsat __INFO. Kdyz jsem pokud se to rozpadlo zadal pro oba tokeny stejne info tak to vypadalo dobre...

...jenze kdyz jsem zacal psat pravidla ze za to hodim STORE (pripadne CSTORE nebo HSTORE), tak vznikly komplikace.
Nemluvim jen o tom ze najednou kdyz ocekavam ze pred tim je PUSHS token a _3_PICK token tak tam je nejaka kombinace jinych tokenu.
Ale hlavne o INFU, protoze se me nekdy zdvojuje a ja nemam informaci ze je to zdvojene. A kdyz to bylo napr. PUSH(num1) PUSH(3) PICK STORE tak to najednou bylo "num1 3 pick num1 3 pick !".

Kdyz bych info u druheho tokenu umazal tak by nekdy byla fakt velka mezera v komentarich.
Osetril jsem to nejak ale vysledek proste nekdy vytvarel chyby nebo uplne nesmysly. Protoze STORE uz nevi zda predtim tam bylo
"OVER PUSH(num1) SWAP PUSH(num2) SWAP" a nebo "PUSH(num1,num2) _3_PICK". A pro obe varianty by se mel chova jinak.

Nakonec jsem to vyresil tak ze jsem zavedl specialni info "__dtto". Pokud pri uz vytvareni kodu ten token ma hodnotu stale __dtto tak se mu priradi info predchoziho tokenu. Pokud naopak se vola makro/fce __CONCATENATE_WITH a nejaky parametr ma hodnotu __dtto tak se tvari jako by tam nebyl. Tahlo makro/fce odstranuje i zbytecne mezery, protoze ignoruje i prazdne retezce. Prvni parametr fce je cim se bude oddelovat takze se to vola vetsinou jako __CONCATENATE_WITH({ },__T_INFO(1),__T_INFO(0),$2). To by melo spojit info z predchoziho, posledniho a $2 je aktualne ukladaneho tokenu.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0) PICK __SHOW_TOKEN(1)'
; name: __TOKEN_DUP
; info: 0 pick
;items: 0
;param: ()
    push DE             ; 1:11      0 pick   ( a -- a a )
    ld    D, H          ; 1:4       0 pick
    ld    E, L          ; 1:4       0 pick
; seconds: 0           ;[ 3:19]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xaa) PUSH(0) PICK __SHOW_TOKEN(1)'
; name: __TOKEN_PUSHS
; info: 0xaa 0 pick
;items: 2
;param: (0xaa,0xaa)
;array1: >0xaa<
;array2: >0xaa<
;array: 0xaa,0xaa
                        ;[7:40]     0xaa 0 pick   ( -- 0xaa 0xaa )
    push DE             ; 1:11      0xaa 0 pick
    push HL             ; 1:11      0xaa 0 pick
    ld   DE, 0x00AA     ; 3:10      0xaa 0 pick
    ld    L, E          ; 1:4       0xaa 0 pick   L = E = 0xAA
    ld    H, D          ; 1:4       0xaa 0 pick   H = D = 0x00
; seconds: 0           ;[ 7:40]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(1) PICK __SHOW_TOKEN(1)'
; name: __TOKEN_OVER
; info: 1 pick
;items: 0
;param: ()
    push DE             ; 1:11      1 pick   ( b a -- b a b )
    ex   DE, HL         ; 1:4       1 pick
; seconds: 0           ;[ 2:15]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xaa) PUSH(1) PICK __SHOW_TOKEN(1)'
; name: __TOKEN_PUSH_OVER
; info: 0xaa 1 pick
;items: 1
;param: (0xaa)
;array1: >0xaa<
;array: 0xaa
    push DE             ; 1:11      0xaa 1 pick   ( a -- a 0xaa a )
    push HL             ; 1:11      0xaa 1 pick
    ld   DE, 0xaa       ; 3:10      0xaa 1 pick
; seconds: 0           ;[ 5:32]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xbb) PUSH(0xaa) PUSH(1) PICK __SHOW_TOKEN(1)'
; name: __TOKEN_PUSHS
; info: 0xbb 0xaa 1 pick
;items: 3
;param: (0xbb,0xaa,0xbb)
;array1: >0xbb<
;array2: >0xaa<
;array3: >0xbb<
;array: 0xbb,0xaa,0xbb
    push DE             ; 1:11      0xbb 0xaa 1 pick   ( -- 0xbb 0xaa 0xbb ) push3.m4
    push HL             ; 1:11      0xbb 0xaa 1 pick
    ld   HL, 0x00BB     ; 3:10      0xbb 0xaa 1 pick
    push HL             ; 1:11      0xbb 0xaa 1 pick
    ld   DE, 0x00AA     ; 3:10      0xbb 0xaa 1 pick
; seconds: 0           ;[ 9:53]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(2) PICK __SHOW_TOKEN(1)'
; name: __TOKEN_2_PICK
; info: 2 pick
;items: 0
;param: ()
                       ;[ 6:44]     2 pick   ( c b a -- c b a c )
    pop  BC             ; 1:10      2 pick
    push BC             ; 1:11      2 pick
    push DE             ; 1:11      2 pick
    ex   DE, HL         ; 1:4       2 pick
    ld    H, B          ; 1:4       2 pick
    ld    L, C          ; 1:4       2 pick
; seconds: 0           ;[ 6:44]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xaa) PUSH(2) PICK __SHOW_TOKEN(1)'
; name: __TOKEN_OVER_PUSH_SWAP
; info: 0xaa 2 pick
;items: 1
;param: (0xaa)
;array1: >0xaa<
;array: 0xaa
                        ;[6:36]     0xaa 2 pick   ( x1 x0 -- x1 x0 0xaa x1 )
    push DE             ; 1:11      0xaa 2 pick
    push HL             ; 1:11      0xaa 2 pick
    ld   HL, 0xaa       ; 3:10      0xaa 2 pick
    ex   DE, HL         ; 1:4       0xaa 2 pick
; seconds: 0           ;[ 6:36]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xbb) PUSH(0xaa) PUSH(2) PICK __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_DUP_PUSH_SWAP
; info: 0xbb 0xaa 2 pick
;items: 2
;param: (0xbb,0xaa)
;array1: >0xbb<
;array2: >0xaa<
;array: 0xbb,0xaa
; name: __TOKEN_PUSH_SWAP
; info: __dtto
;items: 1
;param: (2)
;array1: >2<
;array: 2
    push DE             ; 1:11      0xbb 0xaa 2 pick   ( a -- a 0xbb a )
    push HL             ; 1:11      0xbb 0xaa 2 pick
    ld   DE, 0xbb       ; 3:10      0xbb 0xaa 2 pick
    push DE             ; 1:11      0xbb 0xaa 2 pick   ( x -- 2 x )
    ld   DE, 2          ; 3:10      0xbb 0xaa 2 pick
; seconds: 0           ;[ 9:53]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xcc) PUSH(0xbb) PUSH(0xaa) PUSH(2) PICK __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_PUSHS
; info: 0xcc 0xbb 0xaa 2 pick
;items: 4
;param: (0xcc,0xbb,0xaa,0xcc)
;array1: >0xcc<
;array2: >0xbb<
;array3: >0xaa<
;array4: >0xcc<
;array: 0xcc,0xbb,0xaa,0xcc
; name:
; info:
;items: 0
;param:
    push DE             ; 1:11      0xcc 0xbb 0xaa 2 pick
    push HL             ; 1:11      0xcc 0xbb 0xaa 2 pick
    ld   HL, 0x00CC     ; 3:10      0xcc 0xbb 0xaa 2 pick
    push HL             ; 1:11      0xcc 0xbb 0xaa 2 pick
    ld   DE, 0x00BB     ; 3:10      0xcc 0xbb 0xaa 2 pick
    push DE             ; 1:11      0xcc 0xbb 0xaa 2 pick
    ld    E, 0xAA       ; 2:7       0xcc 0xbb 0xaa 2 pick
; seconds: 1           ;[12:71]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(3) PICK __SHOW_TOKEN(1)'
; name: __TOKEN_3_PICK
; info: 3 pick
;items: 0
;param: ()
                       ;[ 8:65]     3 pick   ( d c b a -- d c b a d )
    pop  AF             ; 1:10      3 pick
    pop  BC             ; 1:10      3 pick
    push BC             ; 1:11      3 pick
    push AF             ; 1:11      3 pick
    push DE             ; 1:11      3 pick
    ex   DE, HL         ; 1:4       3 pick
    ld    H, B          ; 1:4       3 pick
    ld    L, C          ; 1:4       3 pick
; seconds: 1           ;[ 8:65]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xaa) PUSH(3) PICK __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_2_PICK
; info: 0xaa 3 pick
;items: 0
;param: ()
; name: __TOKEN_PUSH_SWAP
; info: __dtto
;items: 1
;param: (0xaa)
;array1: >0xaa<
;array: 0xaa
                       ;[ 6:44]     0xaa 3 pick   ( c b a -- c b a c )
    pop  BC             ; 1:10      0xaa 3 pick
    push BC             ; 1:11      0xaa 3 pick
    push DE             ; 1:11      0xaa 3 pick
    ex   DE, HL         ; 1:4       0xaa 3 pick
    ld    H, B          ; 1:4       0xaa 3 pick
    ld    L, C          ; 1:4       0xaa 3 pick
    push DE             ; 1:11      0xaa 3 pick   ( x -- 0xaa x )
    ld   DE, 0xaa       ; 3:10      0xaa 3 pick
; seconds: 0           ;[10:65]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xbb) PUSH(0xaa) PUSH(3) PICK __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_OVER_PUSH_SWAP
; info: 0xbb 0xaa 3 pick
;items: 1
;param: (0xbb)
;array1: >0xbb<
;array: 0xbb
; name: __TOKEN_PUSH_SWAP
; info: __dtto
;items: 1
;param: (0xaa)
;array1: >0xaa<
;array: 0xaa
                        ;[6:36]     0xbb 0xaa 3 pick   ( x1 x0 -- x1 x0 0xbb x1 )
    push DE             ; 1:11      0xbb 0xaa 3 pick
    push HL             ; 1:11      0xbb 0xaa 3 pick
    ld   HL, 0xbb       ; 3:10      0xbb 0xaa 3 pick
    ex   DE, HL         ; 1:4       0xbb 0xaa 3 pick
    push DE             ; 1:11      0xbb 0xaa 3 pick   ( x -- 0xaa x )
    ld   DE, 0xaa       ; 3:10      0xbb 0xaa 3 pick
; seconds: 0           ;[10:57]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xcc) PUSH(0xbb) PUSH(0xaa) PUSH(3) PICK __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_DUP_PUSH_SWAP
; info: 0xcc 0xbb 0xaa 3 pick
;items: 1
;param: (0xcc)
;array1: >0xcc<
;array: 0xcc
; name: __TOKEN_PUSH_SWAP_PUSH_SWAP
; info: __dtto
;items: 2
;param: (0xbb,0xaa)
;array1: >0xbb<
;array2: >0xaa<
;array: 0xbb,0xaa
    push DE             ; 1:11      0xcc 0xbb 0xaa 3 pick   ( a -- a 0xcc a )
    push HL             ; 1:11      0xcc 0xbb 0xaa 3 pick
    ld   DE, 0xcc       ; 3:10      0xcc 0xbb 0xaa 3 pick
    push DE             ; 1:11      0xcc 0xbb 0xaa 3 pick   ( x -- 0xbb 0xaa x )
    ld   DE, 0xbb       ; 3:10      0xcc 0xbb 0xaa 3 pick
    push DE             ; 1:11      0xcc 0xbb 0xaa 3 pick
    ld    E, 0xAA       ; 2:7       0xcc 0xbb 0xaa 3 pick
; seconds: 1           ;[12:71]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(0xdd) PUSH(0xcc) PUSH(0xbb) PUSH(0xaa) PUSH(3) PICK __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_PUSHS
; info: 0xdd 0xcc 0xbb 0xaa 3 pick
;items: 5
;param: (0xdd,0xcc,0xbb,0xaa,0xdd)
;array1: >0xdd<
;array2: >0xcc<
;array3: >0xbb<
;array4: >0xaa<
;array: 0xdd,0xcc,0xbb,0xaa,0xdd
; name:
; info:
;items: 0
;param:
    push DE             ; 1:11      0xdd 0xcc 0xbb 0xaa 3 pick
    push HL             ; 1:11      0xdd 0xcc 0xbb 0xaa 3 pick
    ld   HL, 0x00DD     ; 3:10      0xdd 0xcc 0xbb 0xaa 3 pick
    push HL             ; 1:11      0xdd 0xcc 0xbb 0xaa 3 pick
    ld   DE, 0x00CC     ; 3:10      0xdd 0xcc 0xbb 0xaa 3 pick
    push DE             ; 1:11      0xdd 0xcc 0xbb 0xaa 3 pick
    ld    E, 0xBB       ; 2:7       0xdd 0xcc 0xbb 0xaa 3 pick
    push DE             ; 1:11      0xdd 0xcc 0xbb 0xaa 3 pick
    ld    E, 0xAA       ; 2:7       0xdd 0xcc 0xbb 0xaa 3 pick
; seconds: 2           ;[15:89]
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$


PS: Nevyhoda je ze se to zacina komplikovat... a pokud neco zmenim a token se rozpadne nebo zmeni jinak tak uz ho nezachyti STORE nebo jiny navazujici token. Pokud by se me to neustale nemenilo pod rukama tak by to tak nevadilo...

PPS: Opraveno eval(0__T_ITEMS(0)>1) na eval(1__T_ITEMS(0)>11). Protoze kdyz bylo parametru vic jak sedm a zaroven se tam objevila cislice 8 nebo 9 tak to vyhodilo chybu protoze uvodni nula oznamuje ze je to oktalove cislo. Myslel jsem ze to nevadi ale 08>5 vadi. Musim si hlidat i levou stranu.
Mozna jsem to mel prohodit a udelat eval(__T_ITEMS(0)0>10) ktere by se menilo na (0>10) nebo (10>10) nebo (20>10)...


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 18.01.2023, 03:40 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 896
Has thanked: 74 times
Been thanked: 136 times
Rozdelil jsem soubor __macro.m4 na nekolik souboru, protoze uz zacal byt prilis velky.

Vznikly soubory __t_rules.m4, kde jsou tokenova pravidla a __eval.m4, kde jsou makra pro aritmeticke vypocty
Kód:
dnl # Input:
dnl #    operation num_1 num_2
dnl #    operation num_1 num_2 num_3
dnl # Output:
dnl #    eval(            (num_1) operation (num_2))
dnl #    eval(            (num_1) operation (num_2)),eval(            (num_1) operation (num_2))
dnl #    eval(((num_1)<<16+num_2) operation (num_3))
dnl #    eval(((num_1)<<16+num_2) operation (num_3)),eval(((num_1)<<16+num_2) operation (num_3))
define({__EVAL_S16},{dnl

Kód:
dnl # Input:
dnl #    $1 ...operation
dnl #    $2 ...hi16(num_1)
dnl #    $3 ...lo16(num_1)
dnl #    $4 ...hi16(num_2)
dnl #    $5 ...lo16(num_2)
dnl # Output:
dnl #    eval(            (num_1) operation (num_2))
define({__EVAL_S32},{dnl


Pak jsem mel nejaka nedodelana pravidla s indexem a naslednym push, kde jsem mel poznamku ze to mam prevest do pravidel do druheho pruchodu. Plus to umelo jen I a ne J a K.

Kdyz jsem to zacal testovat ve smyckach pres check_word.sh a objevil jsem nejakou nesrovnalost... Pokud jsem zadal ze ty smycky jsou typu S (stack) tak kdyz jsem dal za smycku FOR, tak ta ma jen jednu polozku a to index ulozenty na zasobniku, ale index si myslel ze jsou tam dve polozky, vcetne konce, i kdyz konec je u FOR nula. Takze u J indexu a K indexu by to vytahovalo spatna data.

Tak jsem se dival na kod a snazil se to pochopit a pak to opravil. Pak jsem zjistil ze jsem to pochopil blbe a misto opravy jsem to uplne podelal. Takze jsem to vratil ze souboru co je na githubu a postupne pridaval znovu zmeny co jsem tam mel.
Postupne jsem to cele zjednodusoval a pouzival dalsi pomocne makra, aby to vypadalo prehledne.

Kdyz jsem pouzival stack smycky tak jsem na rozdil od ostatnich smycek pokud zjistit hodnotu STOP tak ji necham v NOS (DE) a v TOS (HL) je index. Ta smycka je pak rychlejsi i kdyz to zabira dve polozky misto jedne.
Jedina vyjimka byla STOP hodnota nula a jedna. Kdy se to nevyplati nechat v DE, protoze test na nulu nebo jednicku jde udelat snadneji. FOR smycka je to same co DO ADDLOOP(-1) smycka kde znam END ze je nula.

A u tehle vyjimky jsem kdy nedrzim dve hodnoty jsem to zapomnel opravit u indexu. Mel jsem tam ze pokud neznam END tak jsou to dve polozky a kdyz END znam tak je jedna polozka. A to plati prave jen u te nuly a jednicky.

Nanestesti to bylo jeste zamotanejsi a kdyz jsem LOOP konec zmenil za ADDLOOP, tak me to stale bralo ze je to LOOP smycka.
Chyba se objevovala jen u vnorenych smycek, tak jsem zacal vsude delat vypisy a nechapal jsem... vse bylo dobre, po tokenovych pravidlech me __SHOW_LOOP ukazovalo spravny STEP a pak se to nekdy nejak preplo na STEP je +1.
Prokrokoval jsem vsechny ADDLOOP atd a nic.
Nastesti jsem zjistil jsem ze kdyz mam jen ADDLOOP tak to funguje a jakmile za to pridam LOOP tak to selze.
Krokoval jsem i LOOP a nic a pak jsem to nasel. Mel jsem jen primo v LOOP kde se vytvari volani pro token __TOKEN_LOOP mel misto STACK_LOOP promennou COUNT_LOOP... Takhle nenapadne to bylo.

Fixnul jsem to, k I tokenovym pravidlum pridal i J a K pravidla. Krome vyjimky na nulu a jednicku jsem pridal i -1. Snad jsem tim nezavlekl dalsi regresi...
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'DO(S) FOR(S) PUSH(1) PUSH(10) DO(S,,,) K PUSH(5) LOOP NEXT LOOP'
do101:                  ;           do_101(s)   ( stop index -- stop index )
for102:                 ;           for_102(s) ( index -- index )
    push DE             ; 1:11      1 10 do_103(s)
    ex   DE, HL         ; 1:4       1 10 do_103(s)
    ld   HL, 10         ; 3:10      1 10 do_103(s)
do103:                  ;           1 10 do_103(s)   ( stop index -- index )  stop = 1
Tady K saha jen ob dve polozky. Protoze smycka 103 konci v nule a 102 je FOR, takze taky konci v nule. A smycka 101 je Stack, takze K je ulozena na zasobniku jako ostatni indexy. To ze smycka 101 ma stale i STOP na zasobniku uz K nezajima, protoze Index je prvni.
Takze to ( c b a -- c b a c 5 ) jde cist jako ( k j i -- k j i k 5 )
Kód:
                        ;           k_101 5(s)   ( -- k 5 )
    pop  BC             ; 1:10      k_101 5(s)   ( c b a -- c b a c 5 )
    push BC             ; 1:11      k_101 5(s)
    push DE             ; 1:11      k_101 5(s)
    push HL             ; 1:11      k_101 5(s)
    ld    D, B          ; 1:4       k_101 5(s)
    ld    E, C          ; 1:4       k_101 5(s)
    ld   HL, 5          ; 3:10      k_101 5(s)
Kód:
    ld    A, L          ; 1:4       loop_103(s)
    or    H             ; 1:4       loop_103(s)
    inc  HL             ; 1:6       loop_103(s)   index++
    jp   nz, do103      ; 3:10      loop_103(s)
leave103:               ;           loop_103(s)
    ex   DE, HL         ; 1:4       unloop_103(s)   ( i -- )
    pop  DE             ; 1:10      unloop_103(s)
exit103:                ;           loop_103(s)
    ld    A, H          ; 1:4       next_102(s)
    or    L             ; 1:4       next_102(s)
    dec  HL             ; 1:6       next_102(s)   index--
    jp  nz, for102      ; 3:10      next_102(s)
leave102:               ;           next_102(s)
    ex   DE, HL         ; 1:4       unloop_102(s)   ( i -- )
    pop  DE             ; 1:10      unloop_102(s)
    inc  HL             ; 1:6       loop_101(s)   index++
    ld    A, L          ; 1:4       loop_101(s)
    xor   E             ; 1:4       loop_101(s)   lo(index - stop)
    jp   nz, do101      ; 3:10      loop_101(s)
    ld    A, H          ; 1:4       loop_101(s)
    xor   D             ; 1:4       loop_101(s)   hi(index - stop)
    jp   nz, do101      ; 3:10      loop_101(s)
leave101:               ;           loop_101(s)
    pop  HL             ; 1:10      unloop_101(s)   ( stop_i i -- )
    pop  DE             ; 1:10      unloop_101(s)
exit101:                ;           loop_101(s)
; seconds: 1           ;[43:224]


PS: Ten kod je samozrejme nesmysl, protoze by neustale pridaval polozky na zasobnik. Nedal jsem tam neco co ve vnitrni smycce smaze ty dve nove pridane polozky.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 07.02.2023, 15:05 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 896
Has thanked: 74 times
Been thanked: 136 times
Lol, Z80 dokaze stale prekvapit.

Dival jsem se na reseni co me leze pokud volame fci MOVE co kopiruje blok dat s tim ze zname posledni parametr, ktery je pocet word slov.
A to je presne rovno jedne.
Takze PUSH(1) MOVE. Pak v TOS(HL) je cilova adresa a NOS(DE) je zdrojova adresa.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(5-4) MOVE __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_PUSH_MOVE
; info: 5-4 move
;items: 1
;param: (5-4)
;array1: >5-4<
;array: 5-4
; name:
; info:
;items: 0
;param:
                        ;[7:56]     5-4 move   ( from_addr to_addr -- )   u = 1 word
    ex   DE, HL         ; 1:4       5-4 move   HL = from_addr, DE = to_addr
    ldi                 ; 2:16      5-4 move   addr++
    ldi                 ; 2:16      5-4 move   addr++
    pop  HL             ; 1:10      5-4 move
    pop  DE             ; 1:10      5-4 move
; seconds: 0           ;[ 7:56]


Zkousel jsem ty dva bajty kopirovat rucne pomoci
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(5-4) MOVE __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_PUSH_MOVE
; info: 5-4 move
;items: 1
;param: (5-4)
;array1: >5-4<
;array: 5-4
; name:
; info:
;items: 0
;param:
                        ;[8:60]     5-4 move   ( from_addr to_addr -- )   u = 1 word
    ld    A,(DE)        ; 1:7       5-4 move
    ld  (HL),A          ; 1:7       5-4 move
    inc  DE             ; 1:6       5-4 move
    inc  HL             ; 1:6       5-4 move
    ld    A,(DE)        ; 1:7       5-4 move
    ld  (HL),A          ; 1:7       5-4 move
    pop  HL             ; 1:10      5-4 move
    pop  DE             ; 1:10      5-4 move
; seconds: 0           ;[ 8:60]

Kopirovani je sice rychlejsi, ale to rucni zvedani adres je i pres odpadnuti prohozeni DE za HL drazsi reseni. LDI je proste efektivnejsi.
Ale... LDI zveda adresu az POTE co prekopiruje bajt a ja nepotrebuji na konci mit adresy o jednicku za koncem. Takze kdyz posledni LDI nahradim za proste kopirovani tak usetrim 2 takty!
A tohle reseni funguje pokazde kdyz pouzivame opakovane LDI!
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH(5-4) MOVE __SHOW_TOKEN(1) __SHOW_TOKEN(2)'
; name: __TOKEN_PUSH_MOVE
; info: 5-4 move
;items: 1
;param: (5-4)
;array1: >5-4<
;array: 5-4
; name:
; info:
;items: 0
;param:
                        ;[7:54]     5-4 move   ( from_addr to_addr -- )   u = 1 word
    ex   DE, HL         ; 1:4       5-4 move   HL = from_addr, DE = to_addr
    ldi                 ; 2:16      5-4 move   addr++
    ld    A,(HL)        ; 1:7       5-4 move
    ld  (DE),A          ; 1:7       5-4 move
    pop  HL             ; 1:10      5-4 move
    pop  DE             ; 1:10      5-4 move
; seconds: 0           ;[ 7:54]


Nikdy by me nenapadlo kdyz se divam na 2 LDI za sebou, ze to jde zrychlit.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 08.02.2023, 23:41 
Offline
Profík

Registrován: 23.06.2013, 23:49
Příspěvky: 896
Has thanked: 74 times
Been thanked: 136 times
Upravoval jsem soubor if.m4. Protoze tam mam hodne
Kód:
define({__INFO},dup_push_lt_if){}dnl
...
   nejaky kod          ; bajty:takty     dup $1 < if

kde to define jsem delal automaticky skriptem s nazvu makra a to "dup $1 < if" byl puvodni rucne psany info.

A nove chci
Kód:
define({__INFO},__COMPILE_INFO){}dnl
...
   nejaky kod          ; bajty:takty     __INFO

Protoze info se prebira "zhora" a nekdy muze byt vic tokenu spojeno a tvarit se jako spojenene slovo, i kdyz to muze byt spojeni uplne jinych tokenu se stejnym efektem. Z vysledenho kodu to uz neni poznat jak to bylo generovane. Nevim jak to vysvetli jednoduse na prikladu, protoze by se to jeste vic zamotalo... .)

Poznamka: bavime se u forthu o 16 bitovych cislech se ZNAMENKEM.

A zjistil jsem ze me chybi nektere kombinace slov

mel jsem

_0LT_IF
DUP_0LT_IF
_0GE_IF
DUP_0GE_IF

ale uz ne

_0GT_IF
DUP_0GT_IF
_0LE_IF
DUP_0LE_IF

ani samotne

_0GT
_0LE

protoze jsem udelal jen _0LT a _0GE protoze je to fakt snadny napsat. Staci jen zkontrolovat nejvyssi (znamenkovy) bit.

Takze jsem neco vyplodil pro ty dve zbyvajici varianty.

Kód:
                        ;[9:41/20]  0>   ( x -- flag )  flag: x > 0
    ld    A, L          ; 1:4       0>
    or    H             ; 1:4       0>
    jr    z, $+7        ; 2:7/12    0>   zero is false and result
    ld    A, H          ; 1:4       0>
    sub   0x80          ; 2:7       0>
    sbc  HL, HL         ; 2:15      0>

_0LE bylo trosku jinak resene, myslim ze to bylo nejak
Kód:
                        ;[8:39]  0<=   ( x -- flag )  flag: x <= 0
    ld    A, L          ; 1:4       0<=
    or    H             ; 1:4       0<=
    sub  0x01           ; 1:4       0<=
    sbc   A, A          ; 1:4       0<=
    or    H             ; 1:4       0<=
    add   A, A          ; 1:4       0<=
    sbc  HL, HL         ; 2:15      0<=


a pak me pri psani v kombinaci s IFem doslo ze to jde udelat jinak, efektivneji a ze ty slova nemit byla celou dobu jen ma lenost a hloupost. Staci na to v podstate 3 instrukce. Nactu si do A znamenkovy bit. Snizim HL o jedna a tim se stane nula zapornym cislem a udelam obycejny bitovy OR. Znamenko me ukazuje vysledek! Pri snizeni znamenka me nejvic zaporne cislo pretece do nejvysiho kladneho cisla, ale proto si drzim to znamenko uz v A, takze to nevadi.

Kód:
                        ;[7:36]     0>   ( x -- flag )  flag: x > 0
    ld    A, H          ; 1:4       0>   save sign
    dec  HL             ; 1:6       0>   zero to negative
    or    H             ; 1:4       0>
    sub   0x80          ; 2:7       0>
    sbc  HL, HL         ; 2:15      0>


Kód:
                        ;[6:33]     0<=   ( x -- flag )  flag: x <= 0
    ld    A, H          ; 1:4       0<=
    dec  HL             ; 1:6       0<=
    or    H             ; 1:4       0<=
    add   A, A          ; 1:4       0<=   carry if zero or negative HL
    sbc  HL, HL         ; 2:15      0<=


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ů: 395 ]  Přejít na stránku Předchozí  1 ... 23, 24, 25, 26, 27

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


Kdo je online

Uživatelé procházející toto fórum: Kremik a 1 návštěvní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