AST macros

Walter Bright newshound at digitalmars.com
Mon Mar 19 15:28:40 PDT 2007


Don Clugston wrote:
> Walter Bright wrote:
>> Marcin Kuszczak wrote:
>>  > Walter Bright wrote:
>>  >> It's pretty simple:
>>  >>
>>  >> macro foo(args)
>>  >> {
>>  >> ...syntax that gets inserted...
>>  >> }
>>  >>
>>  >> and the args and syntax is evaluated in the context of the 
>> invocation  of
>>  >> the macro, not the definition of the macro. You'll be able to do 
>> things
>>  >> like:
>>  >>
>>  >> macro print(arg)
>>  >> {
>>  >> writefln(__FILE__, __LINE__, arg);
>>  >> }
>>  >>
>>  >> which get the file and line in the right context. There's no way 
>> to do
>>  >> that right now.
> 
> This looks great already. However, I don't see any specific "abstract 
> syntax tree" syntax in this. Is that still a work-in-progress?

The beauty of it is that (a+b), before semantic analysis, is an AST! So 
there's no funky new grammar to learn.

> An observation:
> My version of vector operation expression templates is mostly working 
> now, using the existing mixins. It deals with ASTs by constructing a 
> string representing the operations to be performed, and a tuple 
> containing all of the parameters. The operations string is of the form
> "g+=((a+b)*c)+((d*e)+f)", where a, b, c... correspond to T[0], T[1], 
> T[2]... of the tuple T.
> 
> A compile-time function converts the string into postfix, and then 
> another CFTE function converts that into optimised x87 asm, which is 
> mixed in.

Wow! I think the macros can help by obviating the need for the user to 
do the mixin manually.

> Unexpectedly, I found that it's actually very nice to have flattened 
> tuples. If an AST could recognise that two parameters are the same, it 
> could avoid duplication in the tuple, something that a tree can't easily 
> do:
> eg   somevec+= othervec + somevec*3;
> could become "T[1]+=T[0]+(T[1]*3)" which allows better code generation 
> in the final stage.

There's a way to do this using specialization:

	macro foo(somevec : somevec+=othervec+somevec, othervec)

which will only match for parameters of the form:

	foo( a += b + a);

	somevec => a
	othervec => b

It works analogously to how you can match type patterns in templates 
using specializations.

> It may be useful to separate the tree from the values in this way -- 
> it's not clear to me that (for D) it's desirable to have function calls 
> and parameters mixed together in the way that Lisp does.



More information about the Digitalmars-d mailing list