Thread overview
Capture parameter identifier name in a template?
Aug 12, 2014
ketmar
Aug 12, 2014
H. S. Teoh
Aug 12, 2014
Dicebot
Aug 14, 2014
Rémy Mouëza
Aug 14, 2014
Rémy Mouëza
August 12, 2014
In my JavaScript VM, I have a function whose purpose is to expose D/host constants to the JavaScript runtime code running inside the VM. This makes for somewhat redundant code, as follows:

vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);

I'm just wondering if there's a way to template defRTConst so that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured by the template, making it so that I don't also need to pass the name as a string. I expect the answer to be no, but maybe someone with more knowledge of D template magic knows better.
August 12, 2014
On Tue, 12 Aug 2014 17:36:40 +0000
Maxime Chevalier-Boisvert via Digitalmars-d-learn
<digitalmars-d-learn@puremagic.com> wrote:

> I'm just wondering if there's a way to template defRTConst so that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT)
seems that this is the work for mixins.


August 12, 2014
On Tue, Aug 12, 2014 at 05:36:40PM +0000, Maxime Chevalier-Boisvert via Digitalmars-d-learn wrote:
> In my JavaScript VM, I have a function whose purpose is to expose D/host constants to the JavaScript runtime code running inside the VM. This makes for somewhat redundant code, as follows:
> 
> vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
> vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
> vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
> vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
> vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
> vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
> vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
> vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
> vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);
> 
> I'm just wondering if there's a way to template defRTConst so that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured by the template, making it so that I don't also need to pass the name as a string.  I expect the answer to be no, but maybe someone with more knowledge of D template magic knows better.

I know it's possible to get function (runtime) parameter names using
__traits(), but I'm not sure if that can be done for compile-time
parameters. See: std.traits.ParameterIdentifierTuple.


T

-- 
It said to install Windows 2000 or better, so I installed Linux instead.
August 12, 2014
On Tuesday, 12 August 2014 at 17:36:41 UTC, Maxime Chevalier-Boisvert wrote:
> In my JavaScript VM, I have a function whose purpose is to expose D/host constants to the JavaScript runtime code running inside the VM. This makes for somewhat redundant code, as follows:
>
> vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
> vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
> vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
> vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
> vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
> vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
> vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
> vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
> vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);
>
> I'm just wondering if there's a way to template defRTConst so that the name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured by the template, making it so that I don't also need to pass the name as a string. I expect the answer to be no, but maybe someone with more knowledge of D template magic knows better.

Something like this?

enum ATTRS
{
	ATTR_GETSET,
	ATTR_ENUMERABLE,
	ATTR_CONFIGURABLE
}

void foo(ATTRS attr)
{
	import std.conv;
	foo_impl(attr, to!string(attr));
}

void foo_impl(ATTRS attr, string name)
{
	import std.stdio;
	writefln("name = %s, attr = %d", name, attr);
}

void main()
{
	foo(ATTRS.ATTR_GETSET);
}
August 14, 2014
Using __traits (identifier, ...) and a template alias seems to work for me:

import std.stdio;

/// Two kinds of enums:

/// A named enum.
enum VmParams {
    OBJ_MIN_CAP,
    PROTO_SLOT_IDX,
    FPTR_SLOT_IDX,
}

/// An anonymous one.
enum {
    ATTR_CONFIGURABLE = 3,
    ATTR_WRITABLE,
    ATTR_ENUMERABLE,
    ATTR_DELETED,
    ATTR_GETSET,
    ATTR_DEFAULT
}

/// A dummy Vm class for example purpose.
class Vm {
    /// Stores values.
    int [string] table;

    /// The "classic" runtime const API.
    void defRTConst (string id, int val) {
        table [id] = val;
    }

    /// Using an alias with the identifier trait.
    void rtConst (alias p) () {
        table [__traits (identifier, p)] = p;
    }

    /// Initializes our .table member.
    this () {
        /// Using the allMembers traits we can process all the members of a
        /// named enum.
        foreach (member; __traits (allMembers, VmParams)) {
            int value = mixin ("VmParams." ~ member);
            this.defRTConst (member, value);
        }

        /// Without duplicating the name and its value.
        rtConst!ATTR_CONFIGURABLE;
        rtConst!ATTR_WRITABLE;
        rtConst!ATTR_ENUMERABLE;
        rtConst!ATTR_DELETED;
        rtConst!ATTR_GETSET;
        rtConst!ATTR_DEFAULT;

        /* rtConst won't work with local variables:
        //  auto foo = ATTR_DEFAULT;
        //  rtConst!foo;
        The code above raises a compiler error:
            Error: template instance rtConst!(foo) cannot use local 'foo' as parameter to non-global template rtConst(alias p)()
        */
    }
}

void main ()  {
    Vm vm = new Vm;
    vm.table.writeln;

    /// output:
    /// ["OBJ_MIN_CAP":0, "ATTR_WRITABLE":4, "ATTR_ENUMERABLE":5, "ATTR_GETSET":7, "PROTO_SLOT_IDX":1, "FPTR_SLOT_IDX":2, "ATTR_CONFIGURABLE":3, "ATTR_DELETED":6, "ATTR_DEFAULT":8]
}


On 08/12/2014 07:36 PM, Maxime Chevalier-Boisvert wrote:
> In my JavaScript VM, I have a function whose purpose is to expose D/host
> constants to the JavaScript runtime code running inside the VM. This
> makes for somewhat redundant code, as follows:
>
> vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
> vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
> vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
> vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
> vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
> vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
> vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
> vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
> vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);
>
> I'm just wondering if there's a way to template defRTConst so that the
> name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured
> by the template, making it so that I don't also need to pass the name as
> a string. I expect the answer to be no, but maybe someone with more
> knowledge of D template magic knows better.

August 14, 2014
I have just checked it and yes, it works with a constant that is not an enum: `const int FOO` defined in the module namespace or `static int BAR` defined in the dummy Vm class.

On 08/14/2014 02:08 PM, Maxime Chevalier-Boisvert wrote:
> Thanks. Does it also work with a constant that's not an enum, e.g.: const int FOO?
>
> On 08/14/2014 01:23 PM, Rémy Mouëza wrote:
>> Using __traits (identifier, ...) and a template alias seems to work for me:
>>
>> import std.stdio;
>>
>> /// Two kinds of enums:
>>
>> /// A named enum.
>> enum VmParams {
>>      OBJ_MIN_CAP,
>>      PROTO_SLOT_IDX,
>>      FPTR_SLOT_IDX,
>> }
>>
>> /// An anonymous one.
>> enum {
>>      ATTR_CONFIGURABLE = 3,
>>      ATTR_WRITABLE,
>>      ATTR_ENUMERABLE,
>>      ATTR_DELETED,
>>      ATTR_GETSET,
>>      ATTR_DEFAULT
>> }
>>
>> /// A dummy Vm class for example purpose.
>> class Vm {
>>      /// Stores values.
>>      int [string] table;
>>
>>      /// The "classic" runtime const API.
>>      void defRTConst (string id, int val) {
>>          table [id] = val;
>>      }
>>
>>      /// Using an alias with the identifier trait.
>>      void rtConst (alias p) () {
>>          table [__traits (identifier, p)] = p;
>>      }
>>
>>      /// Initializes our .table member.
>>      this () {
>>          /// Using the allMembers traits we can process all the members
>> of a
>>          /// named enum.
>>          foreach (member; __traits (allMembers, VmParams)) {
>>              int value = mixin ("VmParams." ~ member);
>>              this.defRTConst (member, value);
>>          }
>>
>>          /// Without duplicating the name and its value.
>>          rtConst!ATTR_CONFIGURABLE;
>>          rtConst!ATTR_WRITABLE;
>>          rtConst!ATTR_ENUMERABLE;
>>          rtConst!ATTR_DELETED;
>>          rtConst!ATTR_GETSET;
>>          rtConst!ATTR_DEFAULT;
>>
>>          /* rtConst won't work with local variables:
>>          //  auto foo = ATTR_DEFAULT;
>>          //  rtConst!foo;
>>          The code above raises a compiler error:
>>              Error: template instance rtConst!(foo) cannot use local
>> 'foo' as parameter to non-global template rtConst(alias p)()
>>          */
>>      }
>> }
>>
>> void main ()  {
>>      Vm vm = new Vm;
>>      vm.table.writeln;
>>
>>      /// output:
>>      /// ["OBJ_MIN_CAP":0, "ATTR_WRITABLE":4, "ATTR_ENUMERABLE":5,
>> "ATTR_GETSET":7, "PROTO_SLOT_IDX":1, "FPTR_SLOT_IDX":2,
>> "ATTR_CONFIGURABLE":3, "ATTR_DELETED":6, "ATTR_DEFAULT":8]
>> }
>>
>>
>> On 08/12/2014 07:36 PM, Maxime Chevalier-Boisvert wrote:
>>> In my JavaScript VM, I have a function whose purpose is to expose D/host
>>> constants to the JavaScript runtime code running inside the VM. This
>>> makes for somewhat redundant code, as follows:
>>>
>>> vm.defRTConst("OBJ_MIN_CAP"w, OBJ_MIN_CAP);
>>> vm.defRTConst("PROTO_SLOT_IDX"w, PROTO_SLOT_IDX);
>>> vm.defRTConst("FPTR_SLOT_IDX"w, FPTR_SLOT_IDX);
>>> vm.defRTConst("ATTR_CONFIGURABLE"w  , ATTR_CONFIGURABLE);
>>> vm.defRTConst("ATTR_WRITABLE"w      , ATTR_WRITABLE);
>>> vm.defRTConst("ATTR_ENUMERABLE"w    , ATTR_ENUMERABLE);
>>> vm.defRTConst("ATTR_DELETED"w       , ATTR_DELETED);
>>> vm.defRTConst("ATTR_GETSET"w        , ATTR_GETSET);
>>> vm.defRTConst("ATTR_DEFAULT"w       , ATTR_DEFAULT);
>>>
>>> I'm just wondering if there's a way to template defRTConst so that the
>>> name of an identifier I'm passing (e.g.: ATTR_DEFAULT) can be captured
>>> by the template, making it so that I don't also need to pass the name as
>>> a string. I expect the answer to be no, but maybe someone with more
>>> knowledge of D template magic knows better.
>>