Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #3603 > unrolled thread

macro expansion ?

Started byChris Hinsley <chris.hinsley@gmail.com>
First post2011-06-28 14:43 +0100
Last post2011-07-05 17:35 -0700
Articles 20 on this page of 29 — 10 participants

Back to article view | Back to comp.lang.forth


Contents

  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 →


#3603 — macro expansion ?

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-06-28 14:43 +0100
Subjectmacro 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]


#3604

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2011-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]


#3605

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3606

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3608

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3609

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3610

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3612

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3629

FromJosh Grams <josh@qualdan.com>
Date2011-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]


#3637

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3620

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2011-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]


#3624

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3633

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2011-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]


#3634

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2011-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]


#3639

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3710

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2011-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]


#3617

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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]


#3645

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2011-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]


#3613

FromElizabeth D Rather <erather@forth.com>
Date2011-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]


#3614

FromChris Hinsley <chris.hinsley@gmail.com>
Date2011-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