Re: Capture parameter identifier name in a template?

2014-08-14 Thread Rémy Mouëza via Digitalmars-d-learn

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_CAPw, OBJ_MIN_CAP);
vm.defRTConst(PROTO_SLOT_IDXw, PROTO_SLOT_IDX);
vm.defRTConst(FPTR_SLOT_IDXw, FPTR_SLOT_IDX);
vm.defRTConst(ATTR_CONFIGURABLEw  , ATTR_CONFIGURABLE);
vm.defRTConst(ATTR_WRITABLEw  , ATTR_WRITABLE);
vm.defRTConst(ATTR_ENUMERABLEw, ATTR_ENUMERABLE);
vm.defRTConst(ATTR_DELETEDw   , ATTR_DELETED);
vm.defRTConst(ATTR_GETSETw, ATTR_GETSET);
vm.defRTConst(ATTR_DEFAULTw   , 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.




Re: Capture parameter identifier name in a template?

2014-08-14 Thread Rémy Mouëza via Digitalmars-d-learn
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_CAPw, OBJ_MIN_CAP);
 vm.defRTConst(PROTO_SLOT_IDXw, PROTO_SLOT_IDX);
 vm.defRTConst(FPTR_SLOT_IDXw, FPTR_SLOT_IDX);
 vm.defRTConst(ATTR_CONFIGURABLEw  , ATTR_CONFIGURABLE);
 vm.defRTConst(ATTR_WRITABLEw  , ATTR_WRITABLE);
 vm.defRTConst(ATTR_ENUMERABLEw, ATTR_ENUMERABLE);
 vm.defRTConst(ATTR_DELETEDw   , ATTR_DELETED);
 vm.defRTConst(ATTR_GETSETw, ATTR_GETSET);
 vm.defRTConst(ATTR_DEFAULTw   , 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.



Re: Capture parameter identifier name in a template?

2014-08-12 Thread ketmar via Digitalmars-d-learn
On Tue, 12 Aug 2014 17:36:40 +
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.


signature.asc
Description: PGP signature


Re: Capture parameter identifier name in a template?

2014-08-12 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Aug 12, 2014 at 05:36:40PM +, 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_CAPw, OBJ_MIN_CAP);
 vm.defRTConst(PROTO_SLOT_IDXw, PROTO_SLOT_IDX);
 vm.defRTConst(FPTR_SLOT_IDXw, FPTR_SLOT_IDX);
 vm.defRTConst(ATTR_CONFIGURABLEw  , ATTR_CONFIGURABLE);
 vm.defRTConst(ATTR_WRITABLEw  , ATTR_WRITABLE);
 vm.defRTConst(ATTR_ENUMERABLEw, ATTR_ENUMERABLE);
 vm.defRTConst(ATTR_DELETEDw   , ATTR_DELETED);
 vm.defRTConst(ATTR_GETSETw, ATTR_GETSET);
 vm.defRTConst(ATTR_DEFAULTw   , 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.


Re: Capture parameter identifier name in a template?

2014-08-12 Thread Dicebot via Digitalmars-d-learn
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_CAPw, OBJ_MIN_CAP);
vm.defRTConst(PROTO_SLOT_IDXw, PROTO_SLOT_IDX);
vm.defRTConst(FPTR_SLOT_IDXw, FPTR_SLOT_IDX);
vm.defRTConst(ATTR_CONFIGURABLEw  , ATTR_CONFIGURABLE);
vm.defRTConst(ATTR_WRITABLEw  , ATTR_WRITABLE);
vm.defRTConst(ATTR_ENUMERABLEw, ATTR_ENUMERABLE);
vm.defRTConst(ATTR_DELETEDw   , ATTR_DELETED);
vm.defRTConst(ATTR_GETSETw, ATTR_GETSET);
vm.defRTConst(ATTR_DEFAULTw   , 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);
}