Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #3603 > unrolled thread
| Started by | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| First post | 2011-06-28 14:43 +0100 |
| Last post | 2011-07-05 17:35 -0700 |
| Articles | 20 on this page of 29 — 10 participants |
Back to article view | Back to comp.lang.forth
macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-28 14:43 +0100
Re: macro expansion ? Andrew Haley <andrew29@littlepinkcloud.invalid> - 2011-06-28 10:58 -0500
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-28 18:34 +0100
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-28 18:51 +0100
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-28 19:02 +0100
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-28 19:11 +0100
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-28 19:17 +0100
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-28 19:47 +0100
Re: macro expansion ? Josh Grams <josh@qualdan.com> - 2011-06-29 15:34 +0000
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-29 19:21 +0100
Re: macro expansion ? Andrew Haley <andrew29@littlepinkcloud.invalid> - 2011-06-29 03:15 -0500
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-29 13:11 +0100
Re: macro expansion ? Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-06-29 17:17 +0100
Re: macro expansion ? Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-06-29 18:09 +0100
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-29 19:32 +0100
Re: macro expansion ? Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-07-02 08:48 +0100
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-29 00:44 +0100
Re: macro expansion ? Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-06-29 20:39 +0100
Re: macro expansion ? Elizabeth D Rather <erather@forth.com> - 2011-06-28 08:59 -1000
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-28 20:39 +0100
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-28 21:34 +0100
Re: macro expansion ? Andrew Haley <andrew29@littlepinkcloud.invalid> - 2011-06-29 03:26 -0500
Re: macro expansion ? anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-06-29 11:25 +0000
Re: macro expansion ? Chris Hinsley <chris.hinsley@gmail.com> - 2011-06-29 13:24 +0100
Re: macro expansion ? anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-07-03 14:02 +0000
Re: macro expansion ? Albert van der Horst <albert@spenarnc.xs4all.nl> - 2011-06-29 18:48 +0000
Re: macro expansion ? BruceMcF <agila61@netscape.net> - 2011-06-30 11:11 -0700
Re: macro expansion ? Ian Osgood <iano@quirkster.com> - 2011-07-02 16:22 -0700
Re: macro expansion ? Hugh Aguilar <hughaguilar96@yahoo.com> - 2011-07-05 17:35 -0700
Page 1 of 2 [1] 2 Next page →
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-28 14:43 +0100 |
| Subject | macro expansion ? |
| Message-ID | <2011062814435882049-chrishinsley@gmailcom> |
From the recent thread on IMMEDIATE I quote this word: \ macros : MACRO ( "name" <ccccc"> -- ) CREATE ," IMMEDIATE DOES> COUNT EVALUATE ; When I first added this word to my Forth project I belived it would allow me to define words that were 'macro expanded' in a text substitution manner. Is this indead the case ? The call to EVALUATE made me think this would act as if it was text substitution rather than just a IMMIDEATE word that would execute during compilation. My intention was somthing that would be expanded during compilation and therefore may get optimised as inlined code into the word curently deing defined, so no subroutine call overhead. Clearly it suffers from haveing a single " being scanned for the end of the evaluated string, but that could be improved maybe ? But this led me on to thinking how would I do a more Lisp like macro ? Somthing that would be expanded and then that expantion expanded till there was no more expantions. One of the thoughs that's bothering me on this is what happens if the expansion leads to new words needing to be defined within a partial expansion, and then on the next expantion pass they are executed, all this while not yet finishing the definition of the original word that used the macro in the first place ? I would like to resolve these thoughts with any help from the Forth GURU's out there. :) Chris
[toc] | [next] | [standalone]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2011-06-28 10:58 -0500 |
| Message-ID | <DLadnaa9famEZ5TTnZ2dnUVZ8v2dnZ2d@supernews.com> |
| In reply to | #3603 |
Chris Hinsley <chris.hinsley@gmail.com> wrote: > From the recent thread on IMMEDIATE I quote this word: > > \ macros > : MACRO ( "name" <ccccc"> -- ) > CREATE ," IMMEDIATE DOES> COUNT EVALUATE ; > > When I first added this word to my Forth project I belived it would > allow me to define words that were 'macro expanded' in a text > substitution manner. > > Is this indead the case ? The call to EVALUATE made me think this would > act as if it was text substitution rather than just a IMMIDEATE word > that would execute during compilation. My intention was somthing that > would be expanded during compilation and therefore may get optimised as > inlined code into the word curently deing defined, so no subroutine > call overhead. > > Clearly it suffers from haveing a single " being scanned for the end of > the evaluated string, but that could be improved maybe ? Sure, there are lots of ways you can improve on it. You could nominate a terminator, so macro foo m" .... bar baz bletch ... whatever ... foo m" Here, the author of the macro chooses what the terminator should be. This is better, because you get to use strings in macros, if you want. Or perhaps macro foo .... bar baz bletch ... whatever ... foo Here, the macro name _itself_ is used as the terminator. (How you do this is an exercise for the reader.) > But this led me on to thinking how would I do a more Lisp like macro ? > Somthing that would be expanded and then that expantion expanded till > there was no more expantions. I think that's going to happen anyway. When EVALUATE comes across a MACRO it'll expand it recursively. Perhaps you could show us an example of something like this not working. Andrew.
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-28 18:34 +0100 |
| Message-ID | <2011062818340635857-chrishinsley@gmailcom> |
| In reply to | #3604 |
>> But this led me on to thinking how would I do a more Lisp like macro ? >> Somthing that would be expanded and then that expantion expanded till >> there was no more expantions. > > I think that's going to happen anyway. When EVALUATE comes across a > MACRO it'll expand it recursively. > > Perhaps you could show us an example of something like this not > working. > > Andrew. A simple example that does work as intended. macro ma * +" macro mp1 1 -rot ma" : t1 1 -rot * + ; : t2 mp1 ; Both t1 and t2 dissesemble to exactly the same code. Good that's as I intended. And show the expansion of macros is recursive. :) However now I'm thinking how would a do a macro that can use itself ? Part of this is no problem, the EVALUATE call will be able to find the named macro and recurse in no problem. macro bert bert" Would just recurse till it crashed. But there's no problem with defineing it. So how would I exit a macro expansion ? I'd presumably have to have interpret time, rather than runtime conditions used in the macro ? Forgive me if I'm rambling a bit, I'm making this up on the fly here, trying to see if I can spot a problem. Would I hit a problem that IF, ELSE, ENDIF are only available as compile time words (well they are for my Forth, I know others have made them work at interpret time). Maybe you just stick to useing [IF], [ELSE], [THEN] in macro definitions and it will all just work (tm). I'll try a few more experiments. Chris
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-28 18:51 +0100 |
| Message-ID | <20110628185151666-chrishinsley@gmailcom> |
| In reply to | #3605 |
On 2011-06-28 18:34:06 +0100, Chris Hinsley said: >>> >>> But this led me on to thinking how would I do a more Lisp like macro ? >>> Somthing that would be expanded and then that expantion expanded till >>> there was no more expantions. >> >> I think that's going to happen anyway. When EVALUATE comes across a >> MACRO it'll expand it recursively. >> >> Perhaps you could show us an example of something like this not >> working. >> >> Andrew. > > A simple example that does work as intended. > > macro ma * +" > macro mp1 1 -rot ma" > : t1 1 -rot * + ; > : t2 mp1 ; > > Both t1 and t2 dissesemble to exactly the same code. Good that's as I > intended. And show the expansion of macros is recursive. :) > > However now I'm thinking how would a do a macro that can use itself ? > Part of this is no problem, the EVALUATE call will be able to find the > named macro and recurse in no problem. > > macro bert bert" > > Would just recurse till it crashed. But there's no problem with defineing it. > > So how would I exit a macro expansion ? I'd presumably have to have > interpret time, rather than runtime conditions used in the macro ? > > Forgive me if I'm rambling a bit, I'm making this up on the fly here, > trying to see if I can spot a problem. Would I hit a problem that IF, > ELSE, ENDIF are only available as compile time words (well they are for > my Forth, I know others have made them work at interpret time). Maybe > you just stick to useing [IF], [ELSE], [THEN] in macro definitions and > it will all just work (tm). > > I'll try a few more experiments. > > Chris OK, somthing definate as an example I'd like to see work. Lets say I have a Forth Hakiu pixel shader, it defines a word that takes x,y and gives back an ARGB. Normally I call this each pixel at runtime to generate a pixel on the fly, either in a shader on the GPU or with a peice of code that creates a texture at runtime. However, maybe I'd like to create a macro that uses the Haiku to create an embeded version of the texture as read only data stored as a word that returned a pointer to the embeded array of pixels ? All the processing of the pixels is to be done at compile time, no runtime overhead. Can I create a _macro_ that expands into the ARGB data array given a Hauku name and resolution value at compile time ? I'm just throwing this out as an example, I've not actualy tried to do it yet, but it might show up a problem. I can see that you could define a word that is an IMMEDIATE word to do this job at compile time, but can you do it with the/a macro concept ? Chris
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-28 19:02 +0100 |
| Message-ID | <2011062819022446632-chrishinsley@gmailcom> |
| In reply to | #3606 |
On 2011-06-28 18:51:51 +0100, Chris Hinsley said: > On 2011-06-28 18:34:06 +0100, Chris Hinsley said: > >>>> >>>> But this led me on to thinking how would I do a more Lisp like macro ? >>>> Somthing that would be expanded and then that expantion expanded till >>>> there was no more expantions. >>> >>> I think that's going to happen anyway. When EVALUATE comes across a >>> MACRO it'll expand it recursively. >>> >>> Perhaps you could show us an example of something like this not >>> working. >>> >>> Andrew. >> >> A simple example that does work as intended. >> >> macro ma * +" >> macro mp1 1 -rot ma" >> : t1 1 -rot * + ; >> : t2 mp1 ; >> >> Both t1 and t2 dissesemble to exactly the same code. Good that's as I >> intended. And show the expansion of macros is recursive. :) >> >> However now I'm thinking how would a do a macro that can use itself ? >> Part of this is no problem, the EVALUATE call will be able to find the >> named macro and recurse in no problem. >> >> macro bert bert" >> >> Would just recurse till it crashed. But there's no problem with defineing it. >> >> So how would I exit a macro expansion ? I'd presumably have to have >> interpret time, rather than runtime conditions used in the macro ? >> >> Forgive me if I'm rambling a bit, I'm making this up on the fly here, >> trying to see if I can spot a problem. Would I hit a problem that IF, >> ELSE, ENDIF are only available as compile time words (well they are for >> my Forth, I know others have made them work at interpret time). Maybe >> you just stick to useing [IF], [ELSE], [THEN] in macro definitions and >> it will all just work (tm). >> >> I'll try a few more experiments. >> >> Chris > > OK, somthing definate as an example I'd like to see work. > > Lets say I have a Forth Hakiu pixel shader, it defines a word that > takes x,y and gives back an ARGB. Normally I call this each pixel at > runtime to generate a pixel on the fly, either in a shader on the GPU > or with a peice of code that creates a texture at runtime. > > However, maybe I'd like to create a macro that uses the Haiku to create > an embeded version of the texture as read only data stored as a word > that returned a pointer to the embeded array of pixels ? All the > processing of the pixels is to be done at compile time, no runtime > overhead. Can I create a _macro_ that expands into the ARGB data array > given a Hauku name and resolution value at compile time ? > > I'm just throwing this out as an example, I've not actualy tried to do > it yet, but it might show up a problem. I can see that you could define > a word that is an IMMEDIATE word to do this job at compile time, but > can you do it with the/a macro concept ? > > Chris How about a macro that did greatest common divider ? Function gcd(a As Integer, b As Integer) As Integer If b = 0 Then gcd = a Else gcd = gcd(b,a) End If End Function Chris
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-28 19:11 +0100 |
| Message-ID | <2011062819111570841-chrishinsley@gmailcom> |
| In reply to | #3608 |
On 2011-06-28 19:02:24 +0100, Chris Hinsley said: > On 2011-06-28 18:51:51 +0100, Chris Hinsley said: > >> On 2011-06-28 18:34:06 +0100, Chris Hinsley said: >> >>>>> >>>>> But this led me on to thinking how would I do a more Lisp like macro ? >>>>> Somthing that would be expanded and then that expantion expanded till >>>>> there was no more expantions. >>>> >>>> I think that's going to happen anyway. When EVALUATE comes across a >>>> MACRO it'll expand it recursively. >>>> >>>> Perhaps you could show us an example of something like this not >>>> working. >>>> >>>> Andrew. >>> >>> A simple example that does work as intended. >>> >>> macro ma * +" >>> macro mp1 1 -rot ma" >>> : t1 1 -rot * + ; >>> : t2 mp1 ; >>> >>> Both t1 and t2 dissesemble to exactly the same code. Good that's as I >>> intended. And show the expansion of macros is recursive. :) >>> >>> However now I'm thinking how would a do a macro that can use itself ? >>> Part of this is no problem, the EVALUATE call will be able to find the >>> named macro and recurse in no problem. >>> >>> macro bert bert" >>> >>> Would just recurse till it crashed. But there's no problem with defineing it. >>> >>> So how would I exit a macro expansion ? I'd presumably have to have >>> interpret time, rather than runtime conditions used in the macro ? >>> >>> Forgive me if I'm rambling a bit, I'm making this up on the fly here, >>> trying to see if I can spot a problem. Would I hit a problem that IF, >>> ELSE, ENDIF are only available as compile time words (well they are for >>> my Forth, I know others have made them work at interpret time). Maybe >>> you just stick to useing [IF], [ELSE], [THEN] in macro definitions and >>> it will all just work (tm). >>> >>> I'll try a few more experiments. >>> >>> Chris >> >> OK, somthing definate as an example I'd like to see work. >> >> Lets say I have a Forth Hakiu pixel shader, it defines a word that >> takes x,y and gives back an ARGB. Normally I call this each pixel at >> runtime to generate a pixel on the fly, either in a shader on the GPU >> or with a peice of code that creates a texture at runtime. >> >> However, maybe I'd like to create a macro that uses the Haiku to create >> an embeded version of the texture as read only data stored as a word >> that returned a pointer to the embeded array of pixels ? All the >> processing of the pixels is to be done at compile time, no runtime >> overhead. Can I create a _macro_ that expands into the ARGB data array >> given a Hauku name and resolution value at compile time ? >> >> I'm just throwing this out as an example, I've not actualy tried to do >> it yet, but it might show up a problem. I can see that you could define >> a word that is an IMMEDIATE word to do this job at compile time, but >> can you do it with the/a macro concept ? >> >> Chris > > How about a macro that did greatest common divider ? > > Function gcd(a As Integer, b As Integer) As Integer > If b = 0 Then > gcd = a > Else > gcd = gcd(b,a) > End If > End Function > > Chris I think I'm rapidly getting into the 'but you wouldn't do it like that' teritory. You'd just define a word that did the calcutation, and then use it with somthing like [ 15 5 GCD ] LITERAL. But I'm pushing the issue of how you'd do it with a macro called GCD to expose the limits. Chris
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-28 19:17 +0100 |
| Message-ID | <2011062819173534070-chrishinsley@gmailcom> |
| In reply to | #3609 |
On 2011-06-28 19:11:15 +0100, Chris Hinsley said: > On 2011-06-28 19:02:24 +0100, Chris Hinsley said: > >> On 2011-06-28 18:51:51 +0100, Chris Hinsley said: >> >>> On 2011-06-28 18:34:06 +0100, Chris Hinsley said: >>> >>>>>> >>>>>> But this led me on to thinking how would I do a more Lisp like macro ? >>>>>> Somthing that would be expanded and then that expantion expanded till >>>>>> there was no more expantions. >>>>> >>>>> I think that's going to happen anyway. When EVALUATE comes across a >>>>> MACRO it'll expand it recursively. >>>>> >>>>> Perhaps you could show us an example of something like this not >>>>> working. >>>>> >>>>> Andrew. >>>> >>>> A simple example that does work as intended. >>>> >>>> macro ma * +" >>>> macro mp1 1 -rot ma" >>>> : t1 1 -rot * + ; >>>> : t2 mp1 ; >>>> >>>> Both t1 and t2 dissesemble to exactly the same code. Good that's as I >>>> intended. And show the expansion of macros is recursive. :) >>>> >>>> However now I'm thinking how would a do a macro that can use itself ? >>>> Part of this is no problem, the EVALUATE call will be able to find the >>>> named macro and recurse in no problem. >>>> >>>> macro bert bert" >>>> >>>> Would just recurse till it crashed. But there's no problem with defineing it. >>>> >>>> So how would I exit a macro expansion ? I'd presumably have to have >>>> interpret time, rather than runtime conditions used in the macro ? >>>> >>>> Forgive me if I'm rambling a bit, I'm making this up on the fly here, >>>> trying to see if I can spot a problem. Would I hit a problem that IF, >>>> ELSE, ENDIF are only available as compile time words (well they are for >>>> my Forth, I know others have made them work at interpret time). Maybe >>>> you just stick to useing [IF], [ELSE], [THEN] in macro definitions and >>>> it will all just work (tm). >>>> >>>> I'll try a few more experiments. >>>> >>>> Chris >>> >>> OK, somthing definate as an example I'd like to see work. >>> >>> Lets say I have a Forth Hakiu pixel shader, it defines a word that >>> takes x,y and gives back an ARGB. Normally I call this each pixel at >>> runtime to generate a pixel on the fly, either in a shader on the GPU >>> or with a peice of code that creates a texture at runtime. >>> >>> However, maybe I'd like to create a macro that uses the Haiku to create >>> an embeded version of the texture as read only data stored as a word >>> that returned a pointer to the embeded array of pixels ? All the >>> processing of the pixels is to be done at compile time, no runtime >>> overhead. Can I create a _macro_ that expands into the ARGB data array >>> given a Hauku name and resolution value at compile time ? >>> >>> I'm just throwing this out as an example, I've not actualy tried to do >>> it yet, but it might show up a problem. I can see that you could define >>> a word that is an IMMEDIATE word to do this job at compile time, but >>> can you do it with the/a macro concept ? >>> >>> Chris >> >> How about a macro that did greatest common divider ? >> >> Function gcd(a As Integer, b As Integer) As Integer >> If b = 0 Then >> gcd = a >> Else >> gcd = gcd(b,a) >> End If >> End Function >> >> Chris > > I think I'm rapidly getting into the 'but you wouldn't do it like that' > teritory. You'd just define a word that did the calcutation, and then > use it with somthing like [ 15 5 GCD ] LITERAL. > > But I'm pushing the issue of how you'd do it with a macro called GCD to > expose the limits. > > Chris Err I think that should be: gcd = gcd(b, a mod b) Sombody was bound to point this out, so I'll fess up to getting it wrong now. Chris
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-28 19:47 +0100 |
| Message-ID | <2011062819470472889-chrishinsley@gmailcom> |
| In reply to | #3610 |
On 2011-06-28 19:17:35 +0100, Chris Hinsley said: > On 2011-06-28 19:11:15 +0100, Chris Hinsley said: > >> On 2011-06-28 19:02:24 +0100, Chris Hinsley said: >> >>> On 2011-06-28 18:51:51 +0100, Chris Hinsley said: >>> >>>> On 2011-06-28 18:34:06 +0100, Chris Hinsley said: >>>> >>>>>>> >>>>>>> But this led me on to thinking how would I do a more Lisp like macro ? >>>>>>> Somthing that would be expanded and then that expantion expanded till >>>>>>> there was no more expantions. >>>>>> >>>>>> I think that's going to happen anyway. When EVALUATE comes across a >>>>>> MACRO it'll expand it recursively. >>>>>> >>>>>> Perhaps you could show us an example of something like this not >>>>>> working. >>>>>> >>>>>> Andrew. >>>>> >>>>> A simple example that does work as intended. >>>>> >>>>> macro ma * +" >>>>> macro mp1 1 -rot ma" >>>>> : t1 1 -rot * + ; >>>>> : t2 mp1 ; >>>>> >>>>> Both t1 and t2 dissesemble to exactly the same code. Good that's as I >>>>> intended. And show the expansion of macros is recursive. :) >>>>> >>>>> However now I'm thinking how would a do a macro that can use itself ? >>>>> Part of this is no problem, the EVALUATE call will be able to find the >>>>> named macro and recurse in no problem. >>>>> >>>>> macro bert bert" >>>>> >>>>> Would just recurse till it crashed. But there's no problem with defineing it. >>>>> >>>>> So how would I exit a macro expansion ? I'd presumably have to have >>>>> interpret time, rather than runtime conditions used in the macro ? >>>>> >>>>> Forgive me if I'm rambling a bit, I'm making this up on the fly here, >>>>> trying to see if I can spot a problem. Would I hit a problem that IF, >>>>> ELSE, ENDIF are only available as compile time words (well they are for >>>>> my Forth, I know others have made them work at interpret time). Maybe >>>>> you just stick to useing [IF], [ELSE], [THEN] in macro definitions and >>>>> it will all just work (tm). >>>>> >>>>> I'll try a few more experiments. >>>>> >>>>> Chris >>>> >>>> OK, somthing definate as an example I'd like to see work. >>>> >>>> Lets say I have a Forth Hakiu pixel shader, it defines a word that >>>> takes x,y and gives back an ARGB. Normally I call this each pixel at >>>> runtime to generate a pixel on the fly, either in a shader on the GPU >>>> or with a peice of code that creates a texture at runtime. >>>> >>>> However, maybe I'd like to create a macro that uses the Haiku to create >>>> an embeded version of the texture as read only data stored as a word >>>> that returned a pointer to the embeded array of pixels ? All the >>>> processing of the pixels is to be done at compile time, no runtime >>>> overhead. Can I create a _macro_ that expands into the ARGB data array >>>> given a Hauku name and resolution value at compile time ? >>>> >>>> I'm just throwing this out as an example, I've not actualy tried to do >>>> it yet, but it might show up a problem. I can see that you could define >>>> a word that is an IMMEDIATE word to do this job at compile time, but >>>> can you do it with the/a macro concept ? >>>> >>>> Chris >>> >>> How about a macro that did greatest common divider ? >>> >>> Function gcd(a As Integer, b As Integer) As Integer >>> If b = 0 Then >>> gcd = a >>> Else >>> gcd = gcd(b,a) >>> End If >>> End Function >>> >>> Chris >> >> I think I'm rapidly getting into the 'but you wouldn't do it like that' >> teritory. You'd just define a word that did the calcutation, and then >> use it with somthing like [ 15 5 GCD ] LITERAL. >> >> But I'm pushing the issue of how you'd do it with a macro called GCD to >> expose the limits. >> >> Chris > > Err I think that should be: > > gcd = gcd(b, a mod b) > > Sombody was bound to point this out, so I'll fess up to getting it wrong now. > > Chris A big problem with doing recursive macros is that EVALUATE will push a potentially unknow amount of state on the stack before the next iteration of the macro ? I suppose you could create another stack for use within macros but it's all getting really horible. Chris
[toc] | [prev] | [next] | [standalone]
| From | Josh Grams <josh@qualdan.com> |
|---|---|
| Date | 2011-06-29 15:34 +0000 |
| Message-ID | <4e0b45ea$0$6982$a8266bb1@newsreader.readnews.com> |
| In reply to | #3612 |
Chris Hinsley wrote: <2011062819470472889-chrishinsley@gmailcom> > A big problem with doing recursive macros is that EVALUATE will push a > potentially unknown amount of state on the stack before the next > iteration of the macro Not on any sensible Forth system, it won't. The macros may, but EVALUATE itself can't keep stuff on the data stack if it is going to be at all useful. 1 s" 2 +" evaluate . \ this had better display 3 Or were you talking about something else? --Josh
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-29 19:21 +0100 |
| Message-ID | <2011062919212920834-chrishinsley@gmailcom> |
| In reply to | #3629 |
On 2011-06-29 16:34:02 +0100, Josh Grams said: > Chris Hinsley wrote: <2011062819470472889-chrishinsley@gmailcom> >> A big problem with doing recursive macros is that EVALUATE will push a >> potentially unknown amount of state on the stack before the next >> iteration of the macro > > Not on any sensible Forth system, it won't. The macros may, but > EVALUATE itself can't keep stuff on the data stack if it is going to be > at all useful. > > 1 s" 2 +" evaluate . \ this had better display 3 > > Or were you talking about something else? > > --Josh Ah, yes, your quite right ! It puts things on the return stack, silly me. :( I should have spotted that. \ string evaluation : EVALUATE \ ( ... c-addr len -- ... ) SAVE-INPUT N>R \ save input spec #IN 2! \ set the string as the SOURCE 0 >IN ! \ reset buffer offset ['] INTERPRET CATCH NR> RESTORE-INPUT -37 ?THROW THROW ; OK, maybe the macro word then isn't so bad. I might have misjudged it. Chris
[toc] | [prev] | [next] | [standalone]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2011-06-29 03:15 -0500 |
| Message-ID | <zP6dnYvJ8ZqTQpfTnZ2dnUVZ8oidnZ2d@supernews.com> |
| In reply to | #3609 |
Chris Hinsley <chris.hinsley@gmail.com> wrote: > > I think I'm rapidly getting into the 'but you wouldn't do it like that' > teritory. You'd just define a word that did the calcutation, and then > use it with somthing like [ 15 5 GCD ] LITERAL. Exactly. You're already got immediate words, which are like LISP macros in that they do computation at runtime; they're not just expanded. Simple text macros are just a limited version of the same idea. Andrew.
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-29 13:11 +0100 |
| Message-ID | <2011062913114214583-chrishinsley@gmailcom> |
| In reply to | #3620 |
On 2011-06-29 09:15:10 +0100, Andrew Haley said: > Chris Hinsley <chris.hinsley@gmail.com> wrote: >> >> I think I'm rapidly getting into the 'but you wouldn't do it like that' >> teritory. You'd just define a word that did the calcutation, and then >> use it with somthing like [ 15 5 GCD ] LITERAL. > > Exactly. You're already got immediate words, which are like LISP > macros in that they do computation at runtime; they're not just > expanded. Simple text macros are just a limited version of the same > idea. > > Andrew. I kind of knew that's where this conversation was going. ;) Can anyone see a good reason for keeping this MACRO word at all ? I might just bin it. Chris
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2011-06-29 17:17 +0100 |
| Message-ID | <iufj50$tct$1@dont-email.me> |
| In reply to | #3609 |
On 28/06/2011 19:11, Chris Hinsley wrote: > On 2011-06-28 19:02:24 +0100, Chris Hinsley said: > [...] >> How about a macro that did greatest common divider ? >> >> Function gcd(a As Integer, b As Integer) As Integer >> If b = 0 Then >> gcd = a >> Else >> gcd = gcd(b,a) >> End If >> End Function >> >> Chris > > I think I'm rapidly getting into the 'but you wouldn't do it like that' > teritory. You'd just define a word that did the calcutation, and then > use it with somthing like [ 15 5 GCD ] LITERAL. > > But I'm pushing the issue of how you'd do it with a macro called GCD to > expose the limits. > Andrew & Anton have given you good reasons not to do it via a macro, but if you really want to have a gcd macro it's not difficult e.g an interpret time macro for gcd is: macro gcd ?dup [if] tuck mod gcd [then]" cr 17 118 * 17 62 * gcd . \ Should display 34 To use it in a colon definition you can do : t1 [ 17 118 * 17 62 * gcd ] literal ; t1 . \ Should display 34 To pass the arguments into the colon definition requires a little more trickery (for systems such as GForth that place control information on the data stack and other systems that require a balanced stack between : and ;) e.g.: : pass >r ' execute r> ; immediate 17 118 * 17 62 * pass pass : t2 [ gcd ] literal ; t2 . \ Should display 34 Alternatively [gcd] can be defined as a macro: macro [gcd] [ ?dup [if] tuck mod [gcd] [else] ] [then]" 17 177 * 17 93 * pass pass : t3 [gcd] literal ; t3 . \ should display 51 It all works with GForth -- Gerry
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2011-06-29 18:09 +0100 |
| Message-ID | <iufm7g$kf4$1@dont-email.me> |
| In reply to | #3633 |
On 29/06/2011 17:17, Gerry Jackson wrote: > On 28/06/2011 19:11, Chris Hinsley wrote: >> On 2011-06-28 19:02:24 +0100, Chris Hinsley said: >> > > [...] > >>> How about a macro that did greatest common divider ? >>> >>> Function gcd(a As Integer, b As Integer) As Integer >>> If b = 0 Then >>> gcd = a >>> Else >>> gcd = gcd(b,a) >>> End If >>> End Function >>> >>> Chris >> >> I think I'm rapidly getting into the 'but you wouldn't do it like that' >> teritory. You'd just define a word that did the calcutation, and then >> use it with somthing like [ 15 5 GCD ] LITERAL. >> >> But I'm pushing the issue of how you'd do it with a macro called GCD to >> expose the limits. >> > > Andrew & Anton have given you good reasons not to do it via a macro, but > if you really want to have a gcd macro it's not difficult e.g an > interpret time macro for gcd is: > > macro gcd ?dup [if] tuck mod gcd [then]" > cr 17 118 * 17 62 * gcd . \ Should display 34 > > To use it in a colon definition you can do > : t1 [ 17 118 * 17 62 * gcd ] literal ; > t1 . \ Should display 34 > > To pass the arguments into the colon definition requires a little more > trickery (for systems such as GForth that place control information on > the data stack and other systems that require a balanced stack between : > and ;) e.g.: > > : pass >r ' execute r> ; immediate > 17 118 * 17 62 * pass pass : t2 [ gcd ] literal ; > t2 . \ Should display 34 > > Alternatively [gcd] can be defined as a macro: > > macro [gcd] [ ?dup [if] tuck mod [gcd] [else] ] [then]" > 17 177 * 17 93 * pass pass : t3 [gcd] literal ; > t3 . \ should display 51 > > It all works with GForth > Incidentally the gcd calculation can be done in interpret mode without a macro e.g. 51 59 * 51 31 * ?dup [if] tuck mod 0 >in ! [then] . -- Gerry
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-29 19:32 +0100 |
| Message-ID | <2011062919320387546-chrishinsley@gmailcom> |
| In reply to | #3634 |
On 2011-06-29 18:09:49 +0100, Gerry Jackson said: > On 29/06/2011 17:17, Gerry Jackson wrote: >> On 28/06/2011 19:11, Chris Hinsley wrote: >>> On 2011-06-28 19:02:24 +0100, Chris Hinsley said: >>> >> >> [...] >> >>>> How about a macro that did greatest common divider ? >>>> >>>> Function gcd(a As Integer, b As Integer) As Integer >>>> If b = 0 Then >>>> gcd = a >>>> Else >>>> gcd = gcd(b,a) >>>> End If >>>> End Function >>>> >>>> Chris >>> >>> I think I'm rapidly getting into the 'but you wouldn't do it like that' >>> teritory. You'd just define a word that did the calcutation, and then >>> use it with somthing like [ 15 5 GCD ] LITERAL. >>> >>> But I'm pushing the issue of how you'd do it with a macro called GCD to >>> expose the limits. >>> >> >> Andrew & Anton have given you good reasons not to do it via a macro, but >> if you really want to have a gcd macro it's not difficult e.g an >> interpret time macro for gcd is: >> >> macro gcd ?dup [if] tuck mod gcd [then]" >> cr 17 118 * 17 62 * gcd . \ Should display 34 >> >> To use it in a colon definition you can do >> : t1 [ 17 118 * 17 62 * gcd ] literal ; >> t1 . \ Should display 34 >> >> To pass the arguments into the colon definition requires a little more >> trickery (for systems such as GForth that place control information on >> the data stack and other systems that require a balanced stack between : >> and ;) e.g.: >> >> : pass >r ' execute r> ; immediate >> 17 118 * 17 62 * pass pass : t2 [ gcd ] literal ; >> t2 . \ Should display 34 >> >> Alternatively [gcd] can be defined as a macro: >> >> macro [gcd] [ ?dup [if] tuck mod [gcd] [else] ] [then]" >> 17 177 * 17 93 * pass pass : t3 [gcd] literal ; >> t3 . \ should display 51 >> >> It all works with GForth >> > > Incidentally the gcd calculation can be done in interpret mode without > a macro e.g. > > 51 59 * 51 31 * > ?dup [if] tuck mod 0 >in ! [then] . Neat ! This sort of thing is the mind bending stuff I like about Forth. ! Chris
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2011-07-02 08:48 +0100 |
| Message-ID | <iumifc$86v$1@dont-email.me> |
| In reply to | #3639 |
On 29/06/2011 19:32, Chris Hinsley wrote: > On 2011-06-29 18:09:49 +0100, Gerry Jackson said: > >> On 29/06/2011 17:17, Gerry Jackson wrote: >>> On 28/06/2011 19:11, Chris Hinsley wrote: >>>> On 2011-06-28 19:02:24 +0100, Chris Hinsley said: >>>> >>> >>> [...] >>> >>>>> How about a macro that did greatest common divider ? >>>>> >>>>> Function gcd(a As Integer, b As Integer) As Integer >>>>> If b = 0 Then >>>>> gcd = a >>>>> Else >>>>> gcd = gcd(b,a) >>>>> End If >>>>> End Function >>>>> >>>>> Chris >>>> >>>> I think I'm rapidly getting into the 'but you wouldn't do it like that' >>>> teritory. You'd just define a word that did the calcutation, and then >>>> use it with somthing like [ 15 5 GCD ] LITERAL. >>>> >>>> But I'm pushing the issue of how you'd do it with a macro called GCD to >>>> expose the limits. >>>> >>> >>> Andrew & Anton have given you good reasons not to do it via a macro, but >>> if you really want to have a gcd macro it's not difficult e.g an >>> interpret time macro for gcd is: >>> >>> macro gcd ?dup [if] tuck mod gcd [then]" >>> cr 17 118 * 17 62 * gcd . \ Should display 34 >>> >>> To use it in a colon definition you can do >>> : t1 [ 17 118 * 17 62 * gcd ] literal ; >>> t1 . \ Should display 34 >>> >>> To pass the arguments into the colon definition requires a little more >>> trickery (for systems such as GForth that place control information on >>> the data stack and other systems that require a balanced stack between : >>> and ;) e.g.: >>> >>> : pass >r ' execute r> ; immediate >>> 17 118 * 17 62 * pass pass : t2 [ gcd ] literal ; >>> t2 . \ Should display 34 >>> >>> Alternatively [gcd] can be defined as a macro: >>> >>> macro [gcd] [ ?dup [if] tuck mod [gcd] [else] ] [then]" >>> 17 177 * 17 93 * pass pass : t3 [gcd] literal ; >>> t3 . \ should display 51 >>> >>> It all works with GForth >>> >> >> Incidentally the gcd calculation can be done in interpret mode without >> a macro e.g. >> >> 51 59 * 51 31 * >> ?dup [if] tuck mod 0 >in ! [then] . > > Neat ! > > This sort of thing is the mind bending stuff I like about Forth. ! I agree. I should have pointed out that the definition of PASS (a nice trick) was due to Michael Gassanenko I believe. -- Gerry
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-29 00:44 +0100 |
| Message-ID | <2011062900443165073-chrishinsley@gmailcom> |
| In reply to | #3604 |
<snip> >> But this led me on to thinking how would I do a more Lisp like macro ? >> Somthing that would be expanded and then that expantion expanded till >> there was no more expantions. > > I think that's going to happen anyway. When EVALUATE comes across a > MACRO it'll expand it recursively. > > Perhaps you could show us an example of something like this not > working. > > Andrew. Can one create a macro that takes paramaters ? Even a single paramater is a problem, how do you accsess it once EVALUATE has pushed an unknown amount onto the stack ? Chris
[toc] | [prev] | [next] | [standalone]
| From | Gerry Jackson <gerry@jackson9000.fsnet.co.uk> |
|---|---|
| Date | 2011-06-29 20:39 +0100 |
| Message-ID | <iufv00$mk9$1@dont-email.me> |
| In reply to | #3604 |
On 28/06/2011 16:58, Andrew Haley wrote:
> Chris Hinsley<chris.hinsley@gmail.com> wrote:
>> From the recent thread on IMMEDIATE I quote this word:
>>
>> \ macros
>> : MACRO ( "name"<ccccc"> -- )
>> CREATE ," IMMEDIATE DOES> COUNT EVALUATE ;
>>
[...]
>> Clearly it suffers from haveing a single " being scanned for the end of
>> the evaluated string, but that could be improved maybe ?
>
> Sure, there are lots of ways you can improve on it. You could
> nominate a terminator, so
>
> macro foo m" .... bar baz bletch ... whatever ... foo m"
>
> Here, the author of the macro chooses what the terminator should be.
> This is better, because you get to use strings in macros, if you want.
>
> Or perhaps
>
> macro foo .... bar baz bletch ... whatever ... foo
>
> Here, the macro name _itself_ is used as the terminator. (How you do
> this is an exercise for the reader.)
>
If it is acceptable that the macro string can be terminated at the end
of the line, MACRO could be defined as:
: ,rest-of-line \ Need a better name
source >in @ /string string, source >in ! drop
;
: macro
create immediate ,rest-of-line
does> count evaluate
;
Then any ascii character can be used in the string.
Or ,rest-of-line can even be (naughty but works in practice):
: ,rest-of-line 1234 parse string, ; \ Any number > 127 will do
--
Gerry
[toc] | [prev] | [next] | [standalone]
| From | Elizabeth D Rather <erather@forth.com> |
|---|---|
| Date | 2011-06-28 08:59 -1000 |
| Message-ID | <o56dncRbu8HmuZfTnZ2dnUVZ_uidnZ2d@supernews.com> |
| In reply to | #3603 |
On 6/28/11 3:43 AM, Chris Hinsley wrote: > From the recent thread on IMMEDIATE I quote this word: > > \ macros > : MACRO ( "name" <ccccc"> -- ) > CREATE ," IMMEDIATE DOES> COUNT EVALUATE ; > > When I first added this word to my Forth project I belived it would > allow me to define words that were 'macro expanded' in a text > substitution manner. > > Is this indead the case ? The call to EVALUATE made me think this would > act as if it was text substitution rather than just a IMMIDEATE word > that would execute during compilation. My intention was somthing that > would be expanded during compilation and therefore may get optimised as > inlined code into the word curently deing defined, so no subroutine call > overhead. Whether it compiles something would depend on whether it's used in compile state, obviously. The use of EVALUATE has a potential side-effect in that if a word in the string has been redefined, you'll get the most recent version, whereas when you compile a definition you always have the version that was current at the time it was compiled. > Clearly it suffers from haveing a single " being scanned for the end of > the evaluated string, but that could be improved maybe ? > > But this led me on to thinking how would I do a more Lisp like macro ? > Somthing that would be expanded and then that expantion expanded till > there was no more expantions. One of the thoughs that's bothering me on > this is what happens if the expansion leads to new words needing to be > defined within a partial expansion, and then on the next expantion pass > they are executed, all this while not yet finishing the definition of > the original word that used the macro in the first place ? > > I would like to resolve these thoughts with any help from the Forth > GURU's out there. :) My big question is, why do you want to do this? If it's an academic exercise, to just see if it's possible, that's one thing: enjoy. But I'm not very enamored of macros in general, because they're often a substitute for "programming by copy/paste" which is a pernicious practice. People do it in languages where a CALL (and surrounding setup, etc.) is costly, but given that the entire architecture of Forth is designed to minimize the cost of a call, I really don't see the point as a practical matter. Cheers, Elizabeth -- ================================================== Elizabeth D. Rather (US & Canada) 800-55-FORTH FORTH Inc. +1 310.999.6784 5959 West Century Blvd. Suite 700 Los Angeles, CA 90045 http://www.forth.com "Forth-based products and Services for real-time applications since 1973." ==================================================
[toc] | [prev] | [next] | [standalone]
| From | Chris Hinsley <chris.hinsley@gmail.com> |
|---|---|
| Date | 2011-06-28 20:39 +0100 |
| Message-ID | <2011062820391536125-chrishinsley@gmailcom> |
| In reply to | #3613 |
On 2011-06-28 19:59:06 +0100, Elizabeth D Rather said: > On 6/28/11 3:43 AM, Chris Hinsley wrote: >> From the recent thread on IMMEDIATE I quote this word: >> >> \ macros >> : MACRO ( "name" <ccccc"> -- ) >> CREATE ," IMMEDIATE DOES> COUNT EVALUATE ; >> >> When I first added this word to my Forth project I belived it would >> allow me to define words that were 'macro expanded' in a text >> substitution manner. >> >> Is this indead the case ? The call to EVALUATE made me think this would >> act as if it was text substitution rather than just a IMMIDEATE word >> that would execute during compilation. My intention was somthing that >> would be expanded during compilation and therefore may get optimised as >> inlined code into the word curently deing defined, so no subroutine call >> overhead. > > Whether it compiles something would depend on whether it's used in > compile state, obviously. The use of EVALUATE has a potential > side-effect in that if a word in the string has been redefined, you'll > get the most recent version, whereas when you compile a definition you > always have the version that was current at the time it was compiled. I see the possibility of redefintion during expansion as a feature, not a problem. ! > >> Clearly it suffers from haveing a single " being scanned for the end of >> the evaluated string, but that could be improved maybe ? >> >> But this led me on to thinking how would I do a more Lisp like macro ? >> Somthing that would be expanded and then that expantion expanded till >> there was no more expantions. One of the thoughs that's bothering me on >> this is what happens if the expansion leads to new words needing to be >> defined within a partial expansion, and then on the next expantion pass >> they are executed, all this while not yet finishing the definition of >> the original word that used the macro in the first place ? >> >> I would like to resolve these thoughts with any help from the Forth >> GURU's out there. :) > > My big question is, why do you want to do this? If it's an academic > exercise, to just see if it's possible, that's one thing: enjoy. But > I'm not very enamored of macros in general, because they're often a > substitute for "programming by copy/paste" which is a pernicious > practice. People do it in languages where a CALL (and surrounding > setup, etc.) is costly, but given that the entire architecture of Forth > is designed to minimize the cost of a call, I really don't see the > point as a practical matter. > > Cheers, > Elizabeth It's not an academic exersise ! At least not the way I see it. I disagree that CALL is cheap ! It is on your own Forth CPU, it's not on a general RISC chip. I would like to have the ability to have a powerfull macro system that works at the source level. Somthing like what LISP has, or (forgive me mentioning it) C++ templates. Before the Forth compiler starts to lay down the definition of a word I wish to have text substitution happen, I want the full power of Forth to be available during the expansion to manipulate the source. I don't seam to be able to do this in a simple way useing what's available within the language itself ? Chris
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.forth
csiph-web