DIP 50 - AST macros

luka8088 luka8088 at owave.net
Wed Nov 13 00:15:29 PST 2013


On 10.11.2013. 22:20, Jacob Carlborg wrote:
> I've been thinking quite long of how AST macros could look like in D.
> I've been posting my vision of AST macros here in the newsgroup a couple
> of times already. I've now been asked to create a DIP out of it, so here
> it is:
> 
> http://wiki.dlang.org/DIP50
> 

I took a look at it as here is my conclusion for now:

Statement and attribute macro examples look great. But I don't like Linq
example. I don't think code like the following should be allowed.

query {
  from element in array
  where element > 2
  add element to data
}


>From my point of view this whole idea is great as it makes it easier
what is already possible. For example, with current behavior if I wanted
to write.

foo {
  writeln("foo");
  writeln("foo again");
}

I would have to write:

mixin(foo!(q{
  writeln("foo");
  writeln("foo again");
}));

So the proposed behavior looks much nicer, and I agree with it as the
content of foo block is actually written in D and I think whoever is
reading it would be comfortable with it.


However, for other, non-D syntax-es I would prefer something like:

query q{
  from element in array
  where element > 2
  add element to data
}

Which can be handled by:

macro query (Context context, string dsl) {
    return domainSpecificLanguageToD(dsl);
}

This in terms is already possible by writing the following, it only
allows to be written in a more readable way. And the q{ ... } notation
clearly points out that there is something special going on. Also by
passing such content as string user can implement custom (or call one of
the predefined) tokenizer/lexer/parser.

mixin(query!(q{
  from element in array
  where element > 2
  add element to data
}));


I also don't like the <[ ... ]> syntax because:
1. Like others have said, it looks very foreign.
2. I don't think there is a need to add a new syntax.

I think that string concatenation is enough (at least for now), and if
you want another syntax for templates you can write a macro for that.

For example:

macro myAssert (Context context, Ast!(bool) val, Ast!(string) str = null) {
  auto message = str ? "Assertion failure: " ~ str.eval : val.toString();
  auto msgExpr = literal(constant(message));

  return "
    if (!" ~ val ~ ")
      throw new AssertError(" ~ msgExpr ~ ");
  ";

  // or
  return astTemplate q{
    if (!$val)
      throw new AssertError($msgExpr);
  };
}

void main () {
    myAssert(1 + 2 == 4);
}


What do you guys think?

--
Luka


More information about the Digitalmars-d mailing list