www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Getting function's AST at compile-time

reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
I'm looking for something like __traits(getAST, fn). The AST should 
represent only run-time (instantiated) code without any compile-time 
features.

How hard it would be to implement this in the frontend?

It would enable analysis of code at compile-time (without the need to 
modify the compiler).
Sep 15 2013
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-09-16 00:59, Piotr Szturmaj wrote:
 I'm looking for something like __traits(getAST, fn). The AST should
 represent only run-time (instantiated) code without any compile-time
 features.

 How hard it would be to implement this in the frontend?

 It would enable analysis of code at compile-time (without the need to
 modify the compiler).

I would love to have something like that. I've been thinking about that myself. It's fairly easy to add new things to __traits. Example, I added getUnitTests. But that just returned the functions representing the unit tests. Most traits today returns simple types, as strings, bools, tuples, symbols and so on. I would guess it's a lot more complicated to return a complete tree of classes/structs. I'm guessing these need to be defined in druntime as well. -- /Jacob Carlborg
Sep 15 2013
prev sibling next sibling parent "Kapps" <opantm2+spam gmail.com> writes:
On Sunday, 15 September 2013 at 22:59:37 UTC, Piotr Szturmaj 
wrote:
 I'm looking for something like __traits(getAST, fn). The AST 
 should represent only run-time (instantiated) code without any 
 compile-time features.

 How hard it would be to implement this in the frontend?

 It would enable analysis of code at compile-time (without the 
 need to modify the compiler).

There was a pull request previously for a trait that would get the code of a function, but apparently there were issues with when the semantic stage was run and having things be transformed at that point. I don't remember the exact details, but the pull request goes into a bit more detail: https://github.com/D-Programming-Language/dmd/pull/953
Sep 16 2013
prev sibling next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
On Sunday, 15 September 2013 at 22:59:37 UTC, Piotr Szturmaj 
wrote:
 I'm looking for something like __traits(getAST, fn). The AST 
 should represent only run-time (instantiated) code without any 
 compile-time features.

 How hard it would be to implement this in the frontend?

 It would enable analysis of code at compile-time (without the 
 need to modify the compiler).

Someone somewhere in this newsgroup mentioned that we need to define the order in which compile time constructs are evaluated. This should be done before the addition of more compile time features. Can a function depend on it's own ast? What if two functions mutually depend on the ast of the other?
Sep 16 2013
prev sibling next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 15 September 2013 at 22:59:37 UTC, Piotr Szturmaj 
wrote:
 I'm looking for something like __traits(getAST, fn). The AST 
 should represent only run-time (instantiated) code without any 
 compile-time features.

 How hard it would be to implement this in the frontend?

 It would enable analysis of code at compile-time (without the 
 need to modify the compiler).

That is something I'd like to see, but it has 2 difficult pitfalls : - Compile time feature aren't always well defined. What happen if the AST of the function you look for depends on the CTFE you are running ? Note that is can in very subtle manners. - It require to define the AST properly. And then, every change in the AST become a breaking change. That is really difficult, especially since we are reluctant to clean up some implementations quirks (some even consider them as feature).
Sep 16 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-09-16 10:05, deadalnix wrote:

 That is something I'd like to see, but it has 2 difficult pitfalls :
   - Compile time feature aren't always well defined. What happen if the
 AST of the function you look for depends on the CTFE you are running ?
 Note that is can in very subtle manners.
   - It require to define the AST properly. And then, every change in the
 AST become a breaking change. That is really difficult, especially since
 we are reluctant to clean up some implementations quirks (some even
 consider them as feature).

The AST returned does not need to have the same API as the AST used by the compiler. -- /Jacob Carlborg
Sep 16 2013
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Monday, 16 September 2013 at 10:55:20 UTC, Jacob Carlborg 
wrote:
 On 2013-09-16 10:05, deadalnix wrote:

 That is something I'd like to see, but it has 2 difficult 
 pitfalls :
  - Compile time feature aren't always well defined. What 
 happen if the
 AST of the function you look for depends on the CTFE you are 
 running ?
 Note that is can in very subtle manners.
  - It require to define the AST properly. And then, every 
 change in the
 AST become a breaking change. That is really difficult, 
 especially since
 we are reluctant to clean up some implementations quirks (some 
 even
 consider them as feature).

The AST returned does not need to have the same API as the AST used by the compiler.

Sure, but it still need to be specified.
Sep 16 2013
prev sibling parent "Daniel N" <ufo orbiting.us> writes:
On Monday, 16 September 2013 at 07:07:01 UTC, Kapps wrote:
 There was a pull request previously for a trait that would get 
 the code of a function, but apparently there were issues with 
 when the semantic stage was run and having things be 
 transformed at that point. I don't remember the exact details, 
 but the pull request goes into a bit more detail: 
 https://github.com/D-Programming-Language/dmd/pull/953

The compiler wouldn't even have to provide the original source, only 2 offsets into the original file which then could be used to create a slice from an user owned "import(__FILE__)" buffer. I posted a very inefficient proof-of-concept hack a while ago when the original [] UDA syntax was used, now slightly updated for . http://dpaste.dzfl.pl/b6c7a95f The __LINE__ based approach is clearly not robust enough... but it allows prototyping as if (a very broken) .codeof was available today. I think a realistic first step would be to have a working ".codeof", instead of arguing how the perfect AST representation would look like. Once a robust way of getting the original code is available, it's easy to plugin the upcoming std.lex or any 3rd party software, like pegged to build AST:s. After people start using this feature a lot, it will be easier to define the next step. One way could be to have a 3rd param to codeof for the import(__FILE__)" buffer. __traits(codeof, buffer_2_slice, symbol)
Sep 16 2013