Jump to page: 1 2
Thread overview
__FUNCTION__ implemented with mixins and mangles
Jun 12, 2009
davidl
Jun 12, 2009
Robert Fraser
Jun 14, 2009
zsxxsz
Jun 14, 2009
Nick Sabalausky
Jun 14, 2009
grauzone
Jun 14, 2009
Denis Koroskin
Jun 14, 2009
grauzone
Jun 15, 2009
zsxxsz
Jun 15, 2009
Ary Borenszweig
Jun 15, 2009
Nick Sabalausky
Jun 15, 2009
BCS
Jun 15, 2009
davidl
Jun 15, 2009
BCS
Jun 15, 2009
Robert Fraser
Jun 15, 2009
zsxxsz
Jun 15, 2009
Sjoerd van Leent
June 12, 2009
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
在 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
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
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
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
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
>"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
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
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
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.
« First   ‹ Prev
1 2