digitalmars.D - Feature discussion: __traits(getSource, function)
- Adam D. Ruppe (24/24) Oct 15 2010 I have what might be a weird request here: a way to get the source code ...
- dennis luehring (4/6) Oct 15 2010 as weird as a _traits( getAST, function ) would be :)
- Nick Sabalausky (6/43) Oct 15 2010 With a __traits(getSource, this_statement), things like assert could dis...
- Robert Jacques (6/43) Oct 15 2010 I would favor some form of AST as opposed to raw strings, but I do belie...
- Nick Sabalausky (38/39) Oct 15 2010 Definitely, but strings would probably a lot easier to put in and work w...
- Adam D. Ruppe (7/7) Oct 16 2010 Well, it sounds like I'm not the only one who'd find this useful, so I t...
- Nick Sabalausky (31/42) Oct 16 2010 I've been dealing with ddmd's source a bit lately. Unless it's different...
I have what might be a weird request here: a way to get the source code of a function (or maybe class, etc. too) out of the compiler as a string literal. Using existing features, I was able to think up a hacky solution: use __FILE__, __LINE__, and string import to get the source and read it in. But my implementation was bug riddled, needed extra code at the function, and relied on conventions. So I'd prefer something built in - a trait addition could do the job. I looked at the compiler's source, and it doesn't seem to keep all the needed info around, but I imagine it would be a lot easier for it to figure this out than doing it with mixins. Why would this be useful? My specific case is taking a D function and translating it into javascript at run time, so I can print it out to the browser and run it there too. (naturally, this requires some conventions and simplifcation in the code to work anyway, so my hacky solution works for me). Other advantages might be mixing it with string mixins to edit code at compile time. Honestly, I'm not sure about what else it would be good for. Can anyone think of something compelling enough for me to dive into the dmd source and see about doing it myself? I started typing this excited about the possibilities, but I ended up changing my mind while typing the short list of advantages... but let's discuss it. Any ideas on how it would be useful? Perhaps a simpler alternative would be __traits(sourceFile) and sourceLine - to mimic my current solution.
Oct 15 2010
Am 15.10.2010 18:28, schrieb Adam D. Ruppe:I have what might be a weird request here: a way to get the source code of a function (or maybe class, etc. too) out of the compiler as a string literal.as weird as a _traits( getAST, function ) would be :) my personal feeling is that every compiletime knowledge should be accessable through traits (and maybe change-able)
Oct 15 2010
"Adam D. Ruppe" <destructionator gmail.com> wrote in message news:i99vgb$1pju$1 digitalmars.com...I have what might be a weird request here: a way to get the source code of a function (or maybe class, etc. too) out of the compiler as a string literal. Using existing features, I was able to think up a hacky solution: use __FILE__, __LINE__, and string import to get the source and read it in. But my implementation was bug riddled, needed extra code at the function, and relied on conventions. So I'd prefer something built in - a trait addition could do the job. I looked at the compiler's source, and it doesn't seem to keep all the needed info around, but I imagine it would be a lot easier for it to figure this out than doing it with mixins. Why would this be useful? My specific case is taking a D function and translating it into javascript at run time, so I can print it out to the browser and run it there too. (naturally, this requires some conventions and simplifcation in the code to work anyway, so my hacky solution works for me). Other advantages might be mixing it with string mixins to edit code at compile time. Honestly, I'm not sure about what else it would be good for. Can anyone think of something compelling enough for me to dive into the dmd source and see about doing it myself? I started typing this excited about the possibilities, but I ended up changing my mind while typing the short list of advantages... but let's discuss it. Any ideas on how it would be useful? Perhaps a simpler alternative would be __traits(sourceFile) and sourceLine - to mimic my current solution.With a __traits(getSource, this_statement), things like assert could display the actual line of code that failed, not just the line number. I'm certainly all for it. I've found myself wishing for it on occasion myself.
Oct 15 2010
On Fri, 15 Oct 2010 12:28:59 -0400, Adam D. Ruppe <destructionator gmail.com> wrote:I have what might be a weird request here: a way to get the source code of a function (or maybe class, etc. too) out of the compiler as a string literal. Using existing features, I was able to think up a hacky solution: use __FILE__, __LINE__, and string import to get the source and read it in. But my implementation was bug riddled, needed extra code at the function, and relied on conventions. So I'd prefer something built in - a trait addition could do the job. I looked at the compiler's source, and it doesn't seem to keep all the needed info around, but I imagine it would be a lot easier for it to figure this out than doing it with mixins. Why would this be useful? My specific case is taking a D function and translating it into javascript at run time, so I can print it out to the browser and run it there too. (naturally, this requires some conventions and simplifcation in the code to work anyway, so my hacky solution works for me). Other advantages might be mixing it with string mixins to edit code at compile time. Honestly, I'm not sure about what else it would be good for. Can anyone think of something compelling enough for me to dive into the dmd source and see about doing it myself? I started typing this excited about the possibilities, but I ended up changing my mind while typing the short list of advantages... but let's discuss it. Any ideas on how it would be useful? Perhaps a simpler alternative would be __traits(sourceFile) and sourceLine - to mimic my current solution.I would favor some form of AST as opposed to raw strings, but I do believe backend to generate optimal SQL, etc queries based on the expression tree of the user's lambda functions.
Oct 15 2010
"Robert Jacques" <sandford jhu.edu> wrote in message news:op.vknih4dy26stm6 sandford.myhome.westell.com...I would favor some form of AST as opposed to raw strings,Definitely, but strings would probably a lot easier to put in and work well enough in the meantime. I just came across another case where access to original source would be useful. I have a helper tool in my SemiTwistDTools lib that I use all the time that works like this: int a=3; mixin(traceVal!("a+4")); // runtime output: a+4: 7 Which is almost as much a pain to type as it is useful. But if there was a finer-graned version of __traits(getSource, function), say, to get the source of a parameter from the caller's side, then I could probably just simplify it to this: traceVal(a+4); By doing something like this: void traceVal(T, string str = __traits(getParamSource, expr))(T expr) { writeln(str, ": ", expr); } Which would be similar to this trick already in D2: int bar(int line = __LINE__)() { return line; } void main() { #line 1000 writeln(bar()); // Output: 1000 } ...Although in testing that I just noticed that defining bar this way doesn't work the same: template bar(int line = __LINE__) { enum bar = to!string(line); } Bug?
Oct 15 2010
Well, it sounds like I'm not the only one who'd find this useful, so I took a look at the compiler. It seems to only store file and line internally (I might have missed something though) so the path of least resistance seems to be exposing that, and then pulling the source with a library function. But I'll keep looking, since avoiding the library function would be nice (no -J and no bugs!).
Oct 16 2010
"Adam D. Ruppe" <destructionator gmail.com> wrote in message news:i9cud5$1um2$1 digitalmars.com...Well, it sounds like I'm not the only one who'd find this useful, so I took a look at the compiler. It seems to only store file and line internally (I might have missed something though) so the path of least resistance seems to be exposing that, and then pulling the source with a library function. But I'll keep looking, since avoiding the library function would be nice (no -J and no bugs!).I've been dealing with ddmd's source a bit lately. Unless it's different in dmd, the entirety of the source file should be available here: // Relevent snippets from ddmd, probably similar in dmd: class Module // in Module.d { File srcfile; } class File // in File.d { ubyte* buffer; // data for our file uint len; // amount of data in buffer[] } So if you have a "Module myModule", then you can get the full original source code of the module with (D-ified): myModule.srcfile.buffer[0..myModule.srcfile.len]; You're right that aside from the Module, dmd only keeps track of filename and line number (via the "Loc" struct, which is a member of most classes in the AST). You should be able to add members to Loc for "starting index in source file" and "ending index", and then just use those to index into Module.srcfile.buffer. (Although at that point, it's not really a "Line Of Code", more like "Location Of Code"...and for all I know there might be places that are reliant on it actually having the semantic meaning of "line of code", expecialy since Loc appears to have an "equals(Loc)" member). I'd probably start by adding those members to Loc's ctors, searching all the files for all Loc instantiations, and updating them as relevent. You'll probably also have to find wherever dmd keeps track of the current line number (probably in the lexer or parser somewere, but I've never looked into those, so I don't even know where they are), and keep track of the current srcIndex, etc. along with it.
Oct 16 2010