rebcode - cht'i patch | |
coccinelle | 23-Feb-2007/22:52:22+1:00 |
Voilà un petit patch pour rebcode de manière à pouvoir appeler des routines. Je trouvais quand même un peu ennuyeux de ne pas pouvoir organiser mon code. Voici le patch : ; Patch to rebcode assembler ; - setl: ["Set variable to label offset (0 based offset)" word! word!] ; - call: ["call a sub routine" word! word!] ; - ret: ["return from sub routine" word!] system/internal/rebcode*: make system/internal/rebcode* [ fix-bl: func [block /local labels here label][ labels: make block! 16 block-action: :fix-bl if debug? [print "=== Fixing binding and labels... ==="] parse block [ some [ here: subblock-rule (here/1: bind here/1 words) | 'label word! (here/1: bind here/1 words insert insert tail labels here/2 index? here) | 'setl word! word! | 'call word! word! ( insert at here 4 reduce [ bind 'bra words here/2 ] ) | 'ret word! (insert at here 2 none) skip | opcode-rule (here/1: bind here/1 words) | skip (error here) ] ] parse block [ some [ here: ['bra word! | 'brat word! | 'braf word!] ( fix-label labels at here 2 here 0 ) | 'brab into [some word!] word! ( label: here/2 forall label [ fix-label labels label here -1 ] ) | 'brab word! word! ( fix-label labels at here 2 here -1 ) | 'setl word! word! ( here/1: bind 'set words here/3: any [ select labels to word! here/3 error/with here join "Missing label '" [here/3 ":"] ] ) | 'call word! word! ( here/1: bind 'set words here/2: here/3 here/3: 4 + (index? here) ) | 'ret none! word! ( here/1: bind 'brab words here/2: negate 2 + index? here ) | opcode-rule | skip (print "ICI" error here) ] ] ] system/internal/assemble: func [ "REBCODE Assembler" body /local frame here do-blks labels tmp rule ][ body: second :body fix-bl body ] ]Voici un exemple d'emploi : test: rebcode [ i [integer!] /local ret-ofs begin ][ setl sub-ofs sub print ["sub offset is" sub-ofs newline] brab [lab-1 lab-2] i label lab-1 print "call from lab-1" call sub ret-ofs print "returned to ret-1" exit label sub print ["return offset is" ret-ofs] ret ret-ofs label lab-2 print "call from lab-2" call sub ret-ofs print "returned to ret-2" exit ]Ce qui donne donne : >> test 0 offset of sub label is 21 call from lab-1 return offset is 17 returned to ret-1 >> test 1 offset of sub label is 21 call from lab-2 return offset is 36 returned to ret-2 >> | |
coccinelle | 24-Feb-2007/0:29:04+1:00 |
J'ai amélioré la chose en stackant les adresses de retour. L'écriture est nettement simplififée et les call multiples et/ou récursifs sont possibles. Voici la nouvelle version : ; Patch to rebcode assembler ; - setl: ["Set variable to label offset (0 based offset)" word! word!] ; - call: ["Call (unconditional) to sub-routine" word!] ; - callf: ["Call to sub-routine if the T flag is not set." word!] ; - callt: ["Call to sub-routine if the T flag is set." word!] ; - ret: ["Return (unconditional) from sub-routine"] ; - retf: ["Return from sub-routine if the T flag is not set."] ; - rett: ["Return from sub-routine if the T flag is set."] system/internal/rebcode*: make system/internal/rebcode* [ call-stack: [] call-ofs: 0 fix-bl: func [block /local labels here label][ labels: make block! 16 block-action: :fix-bl if debug? [print "=== Fixing binding and labels... ==="] parse block [ some [ here: subblock-rule (here/1: bind here/1 words) | 'label word! (here/1: bind here/1 words insert insert tail labels here/2 index? here) | 'setl word! word! | ['call | 'callt | 'callf] word! ( change/part here compose [ (bind 'insert words) call-stack (5 + index? here) 1 (bind select [call bra callt brat callf braf] here/1 words) (here/2) (bind 'remove words) call-stack 1 ] 2 ) 7 skip | 'ret ( change/part here compose [ (bind 'pick words) call-ofs call-stack 1 ret offset call-ofs ] 1 ) 6 skip | ['rett | 'retf] ( change/part here compose [ (here/1) offset (bind 'pick words) call-ofs call-stack 1 ret offset call-ofs ] 1 ) 8 skip | opcode-rule (here/1: bind here/1 words) | skip (print "ICI" probe block error here) ] ] parse block [ some [ here: ['bra word! | 'brat word! | 'braf word!] ( fix-label labels at here 2 here 0 ) | 'brab into [some word!] word! ( label: here/2 forall label [ fix-label labels label here -1 ] ) | 'brab word! word! ( fix-label labels at here 2 here -1 ) | 'setl word! word! ( here/1: bind 'set words here/3: any [ select labels to word! here/3 error/with here join "Missing label '" [here/3 ":"] ] ) | 'ret 'offset 'call-ofs ( here/1: bind 'brab words here/2: negate 2 + index? here ) | ['rett | 'retf] 'offset ( here/1: bind select [rett braf retf brat] here/1 words here/2: 7 ) | opcode-rule | skip (print "LA" probe block error here) ] ] ] system/internal/assemble: func [ "REBCODE Assembler" body /local frame here do-blks labels tmp rule ][ body: second :body fix-bl body ] ]qui s'emploie maintenant ainsi : test: rebcode [ i [integer!] /local ret-ofs begin ][ setl sub-ofs sub print ["offset of sub label is" sub-ofs newline] brab [lab-1 lab-2] i label lab-1 print "call from lab-1" call sub print "returned to ret-1" exit label sub pick ret-ofs call-stack 1 print ["return offset is" ret-ofs] ret label lab-2 print "call from lab-2" call sub print "returned to ret-2" exit ] | |
Login required to Post. |