On 21/04/14 19:49, Frustrated wrote:
Not quite. AST macros simply transform code. Attributes attach meta data
to code. While I'm sure there is some overlap they are not the same.
Unless AST macros have the ability to arbitrary add additional
contextual information to meta code then they can't emulate attributes.
I'm not saying we should emulate attributes, we already have those.
BTW, I'm pretty sure they could be implemented with macros. Just return
the exact same AST that was passed in, but replace the top AST node with
a node that is a subclass that adds the data for the UDA.
E.g., Suppose you have D with AST macros but not attributes, how can you
add them?
In the dip, you have
macro attr (Context context, Declaration decl)
{
auto attrName = decl.name;
auto type = decl.type;
return <[
private $decl.type _$decl.name;
$decl.type $decl.name ()
{
return _$decl.name;
}
$decl.type $decl.name ($decl.type value)
{
return _$decl.name = value;
}
]>;
}
class Foo
{
@attr int bar;
}
but attr is not an attribute. It is an macro. @attr converts the "int
bar" field into a private setter and getter. This has nothing to do with
attributes.
Sure it does. @nogc could be implemented with AST macros.
@nogc void foo ()
{
new Object;
}
macro nogc (Context context, Declaration decl)
{
if (containsGCAllocation(decl))
context.compiler.error(decl.name ~ " marked with @nogc performs
GC allocations);
return decl;
}
(just cause you use the attr word and the @ symbol doesn't make it an
attribute)
I don't see how you could ever add attributes to D using AST macros
above unless the definition of an AST macro is modified. [Again,
assuming D didn't have attributes in the first place]
This does not mean that AST macros could not be used to help define the
generalized attributes though.
What I am talking about is instead of hard coding attributes in the
compiler, one abstracts and generalizes the code so that any attribute
could be added in the future with minimal work.
It would simply require one to add the built in attributes list, add the
attribute grammar(which is used to reduce compound attributes), add any
actions that happen when the attribute is used in code.
e.g.,
builtin_attributes = {
{pureness, pure, !pure/impure,
attr = any(attr, impure) => impure
attr = all(attr, pure) => pure
}
{gc, gc, !gc/nogc,
attr = any(attr, gc) => gc
attr = all(attr, nogc) => nogc
}
etc... }
notices that pureness and gc have the same grammatical rules. Code would
be added to handle the pureness and gc attributes when they are come
across for optimization purposes.
The above syntax is just made up and pretty bad but hopefully not too
difficult to get the bigger picture.
Every new built in attribute would just have to be added to the list
above(easy) and code that uses it for whatever purpose would be added in
the code where it belongs.
User define attributes essentially would make the attributes list above
dynamic allowing the user to add to it. The compiler would only be told
how to simplify the attributes using the grammar and would do so but
would not have any code inserted because there is no way for the user to
hook into the compiler properly(I suppose it could be done if the
compiler was written in an oop like way).
The AST macros would provide a way to hook into the compiler. We already
have a way to define attributes, that is, UDA's. What is missing is a
way to add semantic meanings the UDA's, that is where macros come in.
--
/Jacob Carlborg