| Thread overview | |||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 18, 2007 AST macros | ||||
|---|---|---|---|---|
| ||||
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.
>
> And what about mixin templates? Couldn't they just be fixed to do this work?
>
> From docs:
> " Unlike a template instantiation, a template mixin's body is evaluated
> within the scope where the mixin appears, not where the template
> declaration is defined. It is analogous to cutting and pasting the body of
> the template into the location of the mixin. It is useful for injecting
> parameterized 'boilerplate' code, as well as for creating templated nested
> functions, which is not possible with template instantiations. "
>
> For me it looks exactly like this what you want to do with macro.
>
> What would be a difference?
Mixin templates have a fundamental problem with this - the mixin arguments are semantically evaluated before the mixin is instantiated. To manipulate AST's, it's necessary to get at them before the semantic analysis is done.
> For me it seems that the whole mixin thing is rather buggy and unusfull at
> the moment - for reference see:
> http://www.digitalmars.com/d/archives/digitalmars/D/learn/3412.html#N3416
They're not buggy, but it's possible they aren't the right design.
| ||||
March 18, 2007 Re: AST macros | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | >> eao197 wrote: > On naming why not use mixin, since they are so similar? > > mixin print(arg) > { > > } I thought it would be too confusing to have 3 different mixin things. > What if you want the file in some other context? It would be nice to have a complete solution to that, which allows some sort of stack traversal. Although I'm not sure its possible, due to not wanting to keep this sort of information around at release time. > > ie: > > macro print(arg) > { > writefln(__FILE__[stack_level], __LINE__[stack_level], arg); > } > > Or even better: > > Stack[0].Line; //Current line > Stack[1].Line; //Line one level up > Stack[0].File; > Stack[0].Module; > Stack[0].Function; > Stack[0].NumbArgs; //Some form of reflection > Stack[0].Arg[N]; //Access to the value of the argument (ie Turple of values) > Stack[0].ArgIdentifier[N] //String name of the identifier > Stack[0].FuncType //The type of function we are in (is it a macro, a compile time function a member, a regular function) > ect... That would be something for much later. | |||
March 18, 2007 Re: AST macros | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | > As I can see the content of macro body will be inserted into AST in the place of invocation. But there is not much differences with existing C/C++ macro handling (insertion of right __FILE__, __LINE__ is good thing anyway).
>
> Is there allowed any access to previous parsed entity? For example, can I define macro:
>
> macro some_class_extender(class_name) {
> ...modification of 'class_name' class structure...
> }
>
> class MyCoolClass { ... }
> some_class_extender( MyCoolClass );
>
> and get the modified version of MyCoolClass after some_class_externder invocation?
>
> --Regards,
> Yauheni Akhotnikau
Right now, I see AST macros as manipulating expressions and statements, not declarations.
| |||
March 18, 2007 Re: AST macros | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Sun, 18 Mar 2007 05:00:34 +0300, Walter Bright <newshound@digitalmars.com> wrote: > Right now, I see AST macros as manipulating expressions and statements, not declarations. If I have understood you correctly the D macros will be used like class_eval/module_eval in Ruby -- for generation new content of the programm. For example, in Ruby I can write: class ProjectDescription # Methods which accept Array as argument. def add_files( files ); ...; end def add_resources( resouces ); ...; end # Helper class instance method for defining singular argument methods # on top on plural form method. def self.define_singular_form_method( method ) class_eval %Q{ # Construct 'method[0...-1]' removes ending 's' from method name. def #{method[0...-1]}(a); #{method}( [ a ] ); end } end ... end The same trick will be available in D via macro: macro defineSingularFormMethod(methodName, paramType) { void methodName[0..$-1]( paramType a ) { methodName( [ a ] ); } } class ProjectDescription { // Methods which accept Array as argument. void addFiles( char[][] files ) { ... } void addResources( char[][] resources ) { ... } // Addition of singular form methods via macros. defineSingularFormMethod( addFiles, char[] ); defineSingularFormMethod( addResources, char[] ); } The main difference between Ruby's class_eval and D's macro is in the time of execution: in Ruby class_eval is executed in run-time, and in D macro is executed in compile-time (at syntax analyzing stage). Am I right? -- Regards, Yauheni Akhotnikau | |||
March 18, 2007 Re: AST macros | ||||
|---|---|---|---|---|
| ||||
Posted in reply to eao197 | eao197 wrote:
> On Sun, 18 Mar 2007 05:00:34 +0300, Walter Bright <newshound@digitalmars.com> wrote:
>
>> Right now, I see AST macros as manipulating expressions and statements, not declarations.
>
> If I have understood you correctly the D macros will be used like class_eval/module_eval in Ruby -- for generation new content of the programm. For example, in Ruby I can write:
Macros wouldn't be for adding declarations to classes, for that use template mixins.
| |||
March 18, 2007 Re: AST macros | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Sun, 18 Mar 2007 23:30:54 +0300, Walter Bright <newshound@digitalmars.com> wrote: > eao197 wrote: >> On Sun, 18 Mar 2007 05:00:34 +0300, Walter Bright <newshound@digitalmars.com> wrote: >> >>> Right now, I see AST macros as manipulating expressions and statements, not declarations. >> If I have understood you correctly the D macros will be used like class_eval/module_eval in Ruby -- for generation new content of the programm. For example, in Ruby I can write: > > Macros wouldn't be for adding declarations to classes, for that use template mixins. I don't know how use template mixins for such case: // It isn't real D. template ValueAccessor(Type,Name) { Type Name; bool is_<Name>_defined; Type get<Name>() { if( !is_<Name>_defined ) throw new ValueNotDefined("<Name>"); return Name; } void set<Name>( Type value ) { Name = value; is_<Name>_defined = true; } } class SomeValueHolder { mixin ValueAccessor!( uint, DataCoding ); mixin ValueAccessor!( char[], SourceAddress ); mixin ValueAccessor!( char[], DestinationAddress ); ... // And another bunch of ValueAccessor calls. } auto holder = new SomeValueHolder; holder.setDataCoding( 0x01 ); holder.setSourceAddress( "..." ); This can be done via compile-time functions and mixin expression, but I don't think it is possible via template mixins. So I think it is better for me to wait while you implement your macro system in D and see the result. I hope it will be very interesting. Good luck! Thank you for your patience. -- Regards, Yauheni Akhotnikau | |||
March 19, 2007 Re: AST macros | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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?
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.
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.
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.
| |||
March 19, 2007 Re: AST macros | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > ... Question: are AST macros going to use an AST hierarchy exactly like the one in the DMD frontend, or will there be some changes? I say this because I think the DMD frontend AST hierarchy is in some cases quite strange, to say the least. -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D | |||
March 19, 2007 Re: AST macros | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Don Clugston | 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. | |||
March 20, 2007 Re: AST macros | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | Bruno Medeiros wrote:
> Question: are AST macros going to use an AST hierarchy exactly like the one in the DMD frontend, or will there be some changes? I say this because I think the DMD frontend AST hierarchy is in some cases quite strange, to say the least.
You'll just write AST's as normal D code in normal D notation.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply