| Thread overview | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 12, 2009 __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
It's not foolproof, but I found it useful enough; maybe others will too.
// Parsing mangles for fun and profit.
char[] _getJustName(char[] mangle)
{
size_t idx = 1;
size_t start = idx;
size_t len = 0;
while(idx < mangle.length && mangle[idx] >= '0' &&
mangle[idx] <= '9')
{
int size = mangle[idx++] - '0';
while(mangle[idx] >= '0' && mangle[idx] <= '9')
size = (size * 10) + (mangle[idx++] - '0');
start = idx;
len = size;
idx += size;
}
if(start < mangle.length)
return mangle[start .. start + len];
else
return "";
}
// Eheheh, I has a __FUNCTION__.
const char[] FuncNameMix = "static if(!is(typeof(__FUNCTION__)))"
"{ struct __FUNCTION {} const char[] __FUNCTION__ ="
"_getJustName(__FUNCTION.mangleof); }";
To use, just mix into any function where you want to use __FUNCTION__, and it'll be declared as a const char[].
void forble()
{
mixin(FuncNameMix);
pragma(msg, __FUNCTION__); // shows "forble"
}
It doesn't seem to cause any noticeable bloat. The only reference I found to __FUNCTION in an executable compiled with -release was the contents of the FuncNameMix constant itself; I'm sure an "enum string" in D2 wouldn't be emitted like this.
It doesn't work for nested functions, but that's just a little more parsing work. If you want a version that displays the FQN instead of just the function name, I have that too.
For those wondering how this works, it's pretty simple: when you declare a type within a function, its mangleof contains the function's name. All the mixin is doing is declaring a type within the function (struct __FUNCTION), then parsing the owning function's name out of the type's mangleof.
| ||||
June 12, 2009 Re: __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | 在 Sat, 13 Jun 2009 00:40:09 +0800,Jarrett Billingsley <jarrett.billingsley@gmail.com> 写道: > It's not foolproof, but I found it useful enough; maybe others will too. > > // Parsing mangles for fun and profit. > char[] _getJustName(char[] mangle) > { > size_t idx = 1; > size_t start = idx; > size_t len = 0; > > while(idx < mangle.length && mangle[idx] >= '0' && > mangle[idx] <= '9') > { > int size = mangle[idx++] - '0'; > > while(mangle[idx] >= '0' && mangle[idx] <= '9') > size = (size * 10) + (mangle[idx++] - '0'); > > start = idx; > len = size; > idx += size; > } > > if(start < mangle.length) > return mangle[start .. start + len]; > else > return ""; > } > > // Eheheh, I has a __FUNCTION__. > const char[] FuncNameMix = "static if(!is(typeof(__FUNCTION__)))" > "{ struct __FUNCTION {} const char[] __FUNCTION__ =" > "_getJustName(__FUNCTION.mangleof); }"; > > To use, just mix into any function where you want to use __FUNCTION__, > and it'll be declared as a const char[]. > > void forble() > { > mixin(FuncNameMix); > pragma(msg, __FUNCTION__); // shows "forble" > } > > It doesn't seem to cause any noticeable bloat. The only reference I > found to __FUNCTION in an executable compiled with -release was the > contents of the FuncNameMix constant itself; I'm sure an "enum string" > in D2 wouldn't be emitted like this. > > It doesn't work for nested functions, but that's just a little more > parsing work. If you want a version that displays the FQN instead of > just the function name, I have that too. > > For those wondering how this works, it's pretty simple: when you > declare a type within a function, its mangleof contains the function's > name. All the mixin is doing is declaring a type within the function > (struct __FUNCTION), then parsing the owning function's name out of > the type's mangleof. Cool! But basing on mangled name might be broken in the future release of DMD. -- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/ | |||
June 12, 2009 Re: __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
Posted in reply to davidl | 2009/6/12 davidl <davidl@nospam.org>:
> $B:_(B Sat, 13 Jun 2009 00:40:09 +0800$B!$(BJarrett Billingsley
> <jarrett.billingsley@gmail.com> $B<LF;(B:
>
>> It's not foolproof, but I found it useful enough; maybe others will too.
>>
>> // Parsing mangles for fun and profit.
>> char[] _getJustName(char[] mangle)
>> {
>> size_t idx = 1;
>> size_t start = idx;
>> size_t len = 0;
>>
>> while(idx < mangle.length && mangle[idx] >= '0' &&
>> mangle[idx] <= '9')
>> {
>> int size = mangle[idx++] - '0';
>>
>> while(mangle[idx] >= '0' && mangle[idx] <= '9')
>> size = (size * 10) + (mangle[idx++] - '0');
>>
>> start = idx;
>> len = size;
>> idx += size;
>> }
>>
>> if(start < mangle.length)
>> return mangle[start .. start + len];
>> else
>> return "";
>> }
>>
>> // Eheheh, I has a __FUNCTION__.
>> const char[] FuncNameMix = "static if(!is(typeof(__FUNCTION__)))"
>> "{ struct __FUNCTION {} const char[] __FUNCTION__ ="
>> "_getJustName(__FUNCTION.mangleof); }";
>>
>> To use, just mix into any function where you want to use __FUNCTION__, and it'll be declared as a const char[].
>>
>> void forble()
>> {
>> mixin(FuncNameMix);
>> pragma(msg, __FUNCTION__); // shows "forble"
>> }
>>
>> It doesn't seem to cause any noticeable bloat. The only reference I found to __FUNCTION in an executable compiled with -release was the contents of the FuncNameMix constant itself; I'm sure an "enum string" in D2 wouldn't be emitted like this.
>>
>> It doesn't work for nested functions, but that's just a little more parsing work. If you want a version that displays the FQN instead of just the function name, I have that too.
>>
>> For those wondering how this works, it's pretty simple: when you declare a type within a function, its mangleof contains the function's name. All the mixin is doing is declaring a type within the function (struct __FUNCTION), then parsing the owning function's name out of the type's mangleof.
>
> Cool! But basing on mangled name might be broken in the future release of DMD.
Only if DMD is generating incorrect mangles now. Mangles are in the spec; parsing them is completely valid, cross-platform and cross-compiler.
| |||
June 12, 2009 Re: __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> It's not foolproof, but I found it useful enough; maybe others will too.
>
> // Parsing mangles for fun and profit.
> char[] _getJustName(char[] mangle)
> {
> size_t idx = 1;
> size_t start = idx;
> size_t len = 0;
>
> while(idx < mangle.length && mangle[idx] >= '0' &&
> mangle[idx] <= '9')
> {
> int size = mangle[idx++] - '0';
>
> while(mangle[idx] >= '0' && mangle[idx] <= '9')
> size = (size * 10) + (mangle[idx++] - '0');
>
> start = idx;
> len = size;
> idx += size;
> }
>
> if(start < mangle.length)
> return mangle[start .. start + len];
> else
> return "";
> }
>
> // Eheheh, I has a __FUNCTION__.
> const char[] FuncNameMix = "static if(!is(typeof(__FUNCTION__)))"
> "{ struct __FUNCTION {} const char[] __FUNCTION__ ="
> "_getJustName(__FUNCTION.mangleof); }";
>
> To use, just mix into any function where you want to use __FUNCTION__,
> and it'll be declared as a const char[].
>
> void forble()
> {
> mixin(FuncNameMix);
> pragma(msg, __FUNCTION__); // shows "forble"
> }
>
> It doesn't seem to cause any noticeable bloat. The only reference I
> found to __FUNCTION in an executable compiled with -release was the
> contents of the FuncNameMix constant itself; I'm sure an "enum string"
> in D2 wouldn't be emitted like this.
>
> It doesn't work for nested functions, but that's just a little more
> parsing work. If you want a version that displays the FQN instead of
> just the function name, I have that too.
>
> For those wondering how this works, it's pretty simple: when you
> declare a type within a function, its mangleof contains the function's
> name. All the mixin is doing is declaring a type within the function
> (struct __FUNCTION), then parsing the owning function's name out of
> the type's mangleof.
Awesome, thanks!
| |||
June 14, 2009 Re: __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | It's good. But I think it should be implement by the DMD compiler, just like __FILE__ and __LINE__. __FUNCTION__ should be the base D language syntax same as __FILE__, __LINE__, in C99, they're all the compiler's things to get these and the compiler do these more easily than any library. | |||
June 14, 2009 Re: __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
Posted in reply to zsxxsz | On Sat, Jun 13, 2009 at 9:46 PM, zsxxsz<zhengshuxin@hexun.com> wrote:
> It's good. But I think it should be implement by the DMD compiler, just like __FILE__ and __LINE__. __FUNCTION__ should be the base D language syntax same as __FILE__, __LINE__, in C99, they're all the compiler's things to get these and the compiler do these more easily than any library.
>
I completely agree, but Walter and Andrei's argument against it is - where does it end? Do we need __PACKAGE__, __MODULE__, __TYPE__, __TEMPLATE__, etc. etc. etc.? And I agree with them too - but you know, it'd be nice to actually get some results on these things once in a while instead of a bunch of bullshit bikeshed discussions. Sheesh.
| |||
June 14, 2009 Re: __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | >"Jarrett Billingsley" <jarrett.billingsley@gmail.com> wrote in message
> >news:mailman.262.1244953393.13405.digitalmars-d@puremagic.com...
>On Sat, Jun 13, 2009 at 9:46 PM, zsxxsz<zhengshuxin@hexun.com> wrote:
>> It's good. But I think it should be implement by the DMD compiler, just
>> like
>> __FILE__ and __LINE__. __FUNCTION__ should be the base D language syntax
>> same as
>> __FILE__, __LINE__, in C99, they're all the compiler's things to get
>> these and the
>> compiler do these more easily than any library.
>>
>
>I completely agree, but Walter and Andrei's argument against it is - where does it end? Do we need __PACKAGE__, __MODULE__, __TYPE__, __TEMPLATE__, etc. etc. etc.? And I agree with them too - but you know, it'd be nice to actually get some results on these things once in a while instead of a bunch of bullshit bikeshed discussions. Sheesh.
>
I think a big part of the reasoning was that it would be better to just expand reflection to handle those things. But yea, it would be nice to have something in the meantime. I suppose it might not be too hard (for someone already used to working with the frontend source) to do a preprocessor that does that, or a custom patch (like I do for "warnings as warnings" and umm, you know, I actually forgot the other patch I'm using...).
| |||
June 14, 2009 Re: __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > On Sat, Jun 13, 2009 at 9:46 PM, zsxxsz<zhengshuxin@hexun.com> wrote: >> It's good. But I think it should be implement by the DMD compiler, just like >> __FILE__ and __LINE__. __FUNCTION__ should be the base D language syntax same as >> __FILE__, __LINE__, in C99, they're all the compiler's things to get these and the >> compiler do these more easily than any library. >> > > I completely agree, but Walter and Andrei's argument against it is - > where does it end? Do we need __PACKAGE__, __MODULE__, __TYPE__, > __TEMPLATE__, etc. etc. etc.? And I agree with them too - but you All we need is a __HERE__, which expands into a struct literal that provides module, filename, etc. fields. It even can be linked to the next enclosing scope to walk upwards nested functions and types. __FILE__ becomes __HERE__.filename, __LINE__ becomes __HERE__.line > know, it'd be nice to actually get some results on these things once > in a while instead of a bunch of bullshit bikeshed discussions. > Sheesh. | |||
June 14, 2009 Re: __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
Posted in reply to grauzone | On Sun, 14 Jun 2009 17:29:21 +0400, grauzone <none@example.net> wrote:
> Jarrett Billingsley wrote:
>> On Sat, Jun 13, 2009 at 9:46 PM, zsxxsz<zhengshuxin@hexun.com> wrote:
>>> It's good. But I think it should be implement by the DMD compiler, just like
>>> __FILE__ and __LINE__. __FUNCTION__ should be the base D language syntax same as
>>> __FILE__, __LINE__, in C99, they're all the compiler's things to get these and the
>>> compiler do these more easily than any library.
>>>
>> I completely agree, but Walter and Andrei's argument against it is -
>> where does it end? Do we need __PACKAGE__, __MODULE__, __TYPE__,
>> __TEMPLATE__, etc. etc. etc.? And I agree with them too - but you
>
> All we need is a __HERE__, which expands into a struct literal that provides module, filename, etc. fields. It even can be linked to the next enclosing scope to walk upwards nested functions and types.
>
> __FILE__ becomes __HERE__.filename,
> __LINE__ becomes __HERE__.line
>
IIRC, it was previously proposed it as __SCOPE__
| |||
June 14, 2009 Re: __FUNCTION__ implemented with mixins and mangles | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | On Sun, Jun 14, 2009 at 9:31 AM, Denis Koroskin<2korden@gmail.com> wrote:
> On Sun, 14 Jun 2009 17:29:21 +0400, grauzone <none@example.net> wrote:
>
>> Jarrett Billingsley wrote:
>>>
>>> On Sat, Jun 13, 2009 at 9:46 PM, zsxxsz<zhengshuxin@hexun.com> wrote:
>>>>
>>>> It's good. But I think it should be implement by the DMD compiler, just
>>>> like
>>>> __FILE__ and __LINE__. __FUNCTION__ should be the base D language
>>>> syntax same as
>>>> __FILE__, __LINE__, in C99, they're all the compiler's things to get
>>>> these and the
>>>> compiler do these more easily than any library.
>>>>
>>> I completely agree, but Walter and Andrei's argument against it is - where does it end? Do we need __PACKAGE__, __MODULE__, __TYPE__, __TEMPLATE__, etc. etc. etc.? And I agree with them too - but you
>>
>> All we need is a __HERE__, which expands into a struct literal that provides module, filename, etc. fields. It even can be linked to the next enclosing scope to walk upwards nested functions and types.
>>
>> __FILE__ becomes __HERE__.filename,
>> __LINE__ becomes __HERE__.line
>>
>
> IIRC, it was previously proposed it as __SCOPE__
Oh, but I want it to be called __LOCATION__! No, __CONTEXT__! :P
I really don't care WHAT it's called or what its semantics are. This is a simple problem. This should not be hard to solve. Bah.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply