www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - enum to string

reply "Nick Sabalausky" <a a.a> writes:
Is there any way to do this (preferably in D1) with reflection? (ie, without 
having to manually create a conversion func/lookup for every value of every 
enum.)

----------------------
enum Shape
{
    Square, Circle
}
char[] foo(Shape s)
{
    // ?????
}

// Either one of these, I don't really care which
assert(foo(Shape.Square) == "Shape.Square");
assert(foo(Shape.Square) == "Square");
----------------------
Mar 10 2009
next sibling parent reply MIURA Masahiro <echochamber gmail.com> writes:
In D2:

enum Shape: string
{
    Square = "Square",
    Circle = "Circle",
}

void main()
{
    assert(cast(string) Shape.Square == "Square");
}
Mar 10 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"MIURA Masahiro" <echochamber gmail.com> wrote in message 
news:gp730i$30e8$1 digitalmars.com...
 In D2:

 enum Shape: string
 {
    Square = "Square",
    Circle = "Circle",
 }

 void main()
 {
    assert(cast(string) Shape.Square == "Square");
 }
So there's no built-in way to do this with compile-time reflection? I suppose I could work around it by creating a mixin that automatically generates both the enum and an enum->string routine.
Mar 10 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Tue, Mar 10, 2009 at 9:54 PM, Nick Sabalausky <a a.a> wrote:
 "MIURA Masahiro" <echochamber gmail.com> wrote in message
 news:gp730i$30e8$1 digitalmars.com...
 In D2:

 enum Shape: string
 {
 =A0 =A0Square =3D "Square",
 =A0 =A0Circle =3D "Circle",
 }

 void main()
 {
 =A0 =A0assert(cast(string) Shape.Square =3D=3D "Square");
 }
So there's no built-in way to do this with compile-time reflection? I suppose I could work around it by creating a mixin that automatically generates both the enum and an enum->string routine.
In D1, that's the way you have to do it. In D2, there is more reflection - I know you can use __traits(allMembers, Shape) to get the names? Or something like that? It's completely undocumented, of course. There's also std.typecons which has an enum generator that will create toString and I think fromString functions as well.
Mar 10 2009
parent Robert Fraser <fraserofthenight gmail.com> writes:
Jarrett Billingsley wrote:
  There's also std.typecons
 which has an enum generator that will create toString and I think
 fromString functions as well.
Which should be easily portable to D1.
Mar 12 2009
prev sibling next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Nick Sabalausky wrote:
 Is there any way to do this (preferably in D1) with reflection? (ie, without 
 having to manually create a conversion func/lookup for every value of every 
 enum.)
 
 ----------------------
 enum Shape
 {
     Square, Circle
 }
 char[] foo(Shape s)
 {
     // ?????
 }
 
 // Either one of these, I don't really care which
 assert(foo(Shape.Square) == "Shape.Square");
 assert(foo(Shape.Square) == "Square");
 ----------------------
The only way that I know of is to generate foo at the same time as Shape. Generally, you write a CTFE function that generates the enum and also generates the toString function. -- Daniel
Mar 10 2009
prev sibling parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
Nick Sabalausky wrote:
 Is there any way to do this (preferably in D1) with reflection? (ie, without 
 having to manually create a conversion func/lookup for every value of every 
 enum.)
 
 ----------------------
 enum Shape
 {
     Square, Circle
 }
 char[] foo(Shape s)
 {
     // ?????
 }
 
 // Either one of these, I don't really care which
 assert(foo(Shape.Square) == "Shape.Square");
 assert(foo(Shape.Square) == "Square");
 ----------------------
 
You got to give it to Walter: the code is pretty clean (for C++ code anyway) Add the attached code to src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif). This now works: import std.stdio; enum ABC { A, B, C }; void main(string[] args) { foreach(a; ABC.tupleof) { writefln(a); } } prints: A B C Of course, I'm way over my head here. I've just copied the code from struct.tupleof to make enum.tupleof and creating a tuple of StringExps insteadof DotVarExps, whatever they are.... L.
Mar 12 2009
next sibling parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a 
patch to the DMD source was not really what you expected. I just got so 
anxious!

L.
Mar 12 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"Lionello Lunesu" <lio lunesu.remove.com> wrote in message 
news:gpc4j3$30a0$2 digitalmars.com...
 Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a 
 patch to the DMD source was not really what you expected. I just got so 
 anxious!

 L.
Hey, solutions are solutions :) In fact I may very well try that out. I'm not particularly keen on using an ugly mixin to declare all my enums just so that I can use a simple reflection feature like that (which I'd mostly just be using for debugging info anyway).
Mar 12 2009
parent Lionello Lunesu <lio lunesu.remove.com> writes:
Nick Sabalausky wrote:
 "Lionello Lunesu" <lio lunesu.remove.com> wrote in message 
 news:gpc4j3$30a0$2 digitalmars.com...
 Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a 
 patch to the DMD source was not really what you expected. I just got so 
 anxious!

 L.
Hey, solutions are solutions :) In fact I may very well try that out. I'm not particularly keen on using an ugly mixin to declare all my enums just so that I can use a simple reflection feature like that (which I'd mostly just be using for debugging info anyway).
I'm really glad it's so easy to hack stuff into the compiler. Although I'm still strugling to get these new "string expression" to evaluate at compile time. The enum.tupleof is done at compile time, the foreach as well, but I cannot pragma(msg) the values, nor can they be mixin-ed.. Must be some constness flag somewhere? L.
Mar 12 2009
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Lionello Lunesu" <lio lunesu.remove.com> wrote in message 
news:gpc4es$30a0$1 digitalmars.com...
 Nick Sabalausky wrote:
 Is there any way to do this (preferably in D1) with reflection? (ie, 
 without
 having to manually create a conversion func/lookup for every value of 
 every
 enum.)

 ----------------------
 enum Shape
 {
     Square, Circle
 }
 char[] foo(Shape s)
 {
     // ?????
 }

 // Either one of these, I don't really care which
 assert(foo(Shape.Square) == "Shape.Square");
 assert(foo(Shape.Square) == "Square");
 ----------------------
You got to give it to Walter: the code is pretty clean (for C++ code anyway) Add the attached code to src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif). This now works: import std.stdio; enum ABC { A, B, C }; void main(string[] args) { foreach(a; ABC.tupleof) { writefln(a); } } prints: A B C Of course, I'm way over my head here. I've just copied the code from struct.tupleof to make enum.tupleof and creating a tuple of StringExps insteadof DotVarExps, whatever they are.... L.
Your attachment is zero-byte.
Mar 12 2009
next sibling parent Lionello Lunesu <lio lunesu.remove.com> writes:
 Your attachment is zero-byte.
  
Oops... Try this one..
Mar 12 2009
prev sibling parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
cr*p, I've pasted too little. Try this one instead..

I'll use a proper diff tool next time..
Mar 12 2009
parent reply BCS <ao pathlink.com> writes:
Reply to Lionello,

 cr*p, I've pasted too little. Try this one instead..
 
 I'll use a proper diff tool next time..
 
you client is messing with you, paste-bin the sucker or add it to a bugzilla item
Mar 12 2009
next sibling parent Lionello Lunesu <lio lunesu.remove.com> writes:
//src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif):

/* If e.tupleof
  */
if (ident == Id::tupleof)
{
	/* Create a TupleExp out of the fields of the struct e:
	 * (e.field0, e.field1, e.field2, ...)
	 */
	e = e->semantic(sc);	// do this before turning on noaccesscheck
	Expressions *exps = new Expressions;
	exps->reserve(sym->members->dim);
	for (size_t i = 0; i < sym->members->dim; i++)
	{
		EnumMember *em = ((Dsymbol *)sym->members->data[i])->isEnumMember();
		char* s = em->ident->toChars();
		Expression *fe = new StringExp(e->loc, s, strlen(s), 'c');
		exps->push(fe);
	}
	e = new TupleExp(e->loc, exps);
	Scope sss;
	e = e->semantic(&sss);
	return e;
}
Mar 12 2009
prev sibling parent reply Brad Roberts <braddr bellevue.puremagic.com> writes:
On Thu, 12 Mar 2009, BCS wrote:

 Reply to Lionello,
 
 cr*p, I've pasted too little. Try this one instead..
 
 I'll use a proper diff tool next time..
 
you client is messing with you, paste-bin the sucker or add it to a bugzilla item
Just to be sure the two don't get combined (I know you didn't say to do both, just making sure), please don't paste-bin stuff for bug reports. Either put it directly in a comment or attach it as a patch. While paste-bin's aren't super ephemeral, there's no good reason to have thing disconnected from the bug like that. That said, I don't think this really helps the desired usecase much. It's useful, don't get me wrong, but still requires code to build up the bi-directional translations. Or am I missing something? Seems to be happening to me a lot lately, so I'm very prepared to be wrong here too. :) Later, Brad
Mar 12 2009
parent reply "Lionello Lunesu" <lionello lunesu.remove.com> writes:
"Brad Roberts" <braddr bellevue.puremagic.com> wrote in message 
news:alpine.DEB.2.00.0903121755240.4513 bellevue.puremagic.com...
 That said, I don't think this really helps the desired usecase much.  It's
 useful, don't get me wrong, but still requires code to build up the
 bi-directional translations.  Or am I missing something?  Seems to be
 happening to me a lot lately, so I'm very prepared to be wrong here too.
 :)
You're not wrong :) The problem is that the foreach variable is not evaluatable to a compile-time string. I don't know why, but I'll figure it out tonight. I've also managed to convert an enum to an AssocArrayLiteralExp* (with the name/string as the key and the value/int as the value) but it seems that it cannot be foreached at compile time, even if it's a literal expression. But hell, I've spent about 1 hour browsing through dmd's code, so I'm pretty sure it's possible with a little more research. I want to get either one to work at compile-time. In the case of TupleExp, one could then use a string mixin to convert the string to a value. L. * I don't have the AA patch handy (I'm at work) but it's a good exercise: start with my original tupleof patch but create an AssocArrayLiteralExp instead of the TupleExp. You'll need two Expressions arrays, one for keys and one for values. EnumMember::ident is the name, EnumMember::value is the value expression. Pretty straightforward.
Mar 12 2009
parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Lionello Lunesu wrote:
 
 "Brad Roberts" <braddr bellevue.puremagic.com> wrote in message 
 news:alpine.DEB.2.00.0903121755240.4513 bellevue.puremagic.com...
 That said, I don't think this really helps the desired usecase much.  
 It's
 useful, don't get me wrong, but still requires code to build up the
 bi-directional translations.  Or am I missing something?  Seems to be
 happening to me a lot lately, so I'm very prepared to be wrong here too.
 :)
You're not wrong :) The problem is that the foreach variable is not evaluatable to a compile-time string. I don't know why, but I'll figure it out tonight. I've also managed to convert an enum to an AssocArrayLiteralExp* (with the name/string as the key and the value/int as the value) but it seems that it cannot be foreached at compile time, even if it's a literal expression. But hell, I've spent about 1 hour browsing through dmd's code, so I'm pretty sure it's possible with a little more research.
Can you foreach at compile-time? I thought you could only do that in CTFE (or templates?). Maybe that's why it's not working. How do you do it to pragma msg the members of a struct? I remember someone proposed "static foreach" some time ago...
Mar 13 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Ary Borenszweig wrote:
 Lionello Lunesu wrote:
 "Brad Roberts" <braddr bellevue.puremagic.com> wrote in message
 news:alpine.DEB.2.00.0903121755240.4513 bellevue.puremagic.com...
 That said, I don't think this really helps the desired usecase much. 
 It's
 useful, don't get me wrong, but still requires code to build up the
 bi-directional translations.  Or am I missing something?  Seems to be
 happening to me a lot lately, so I'm very prepared to be wrong here too.
 :)
You're not wrong :) The problem is that the foreach variable is not evaluatable to a compile-time string. I don't know why, but I'll figure it out tonight. I've also managed to convert an enum to an AssocArrayLiteralExp* (with the name/string as the key and the value/int as the value) but it seems that it cannot be foreached at compile time, even if it's a literal expression. But hell, I've spent about 1 hour browsing through dmd's code, so I'm pretty sure it's possible with a little more research.
Can you foreach at compile-time? I thought you could only do that in CTFE (or templates?). Maybe that's why it's not working. How do you do it to pragma msg the members of a struct? I remember someone proposed "static foreach" some time ago...
We have a sort-of static foreach. The trick is that the aggregate HAS to be a tuple. When in doubt, you can always fall back on the following construct: template Tuple(T...) { alias T Tuple; } template Range(int n) { static if( n <= 0 ) alias Tuple!() Range; else alias Tuple!(Range!(n-1), n-1) Range; } void blah() { // Note that static foreach ONLY works inside a function foreach( i ; Range!(n) ) { // do stuff with i, which should be a const int } } There have been times when directly accessing some CT construct would make the compiler choke, but going via an index worked fine. -- Daniel
Mar 13 2009
parent bearophile <bearophileHUGS lycos.com> writes:
Daniel Keep:
 template Range(int n)
If some of you needs a version that takes 1 or 2 or 3 arguments, for the start, stop and stride, take a look at my dlibs: http://www.fantascienza.net/leonardo/so/dlibs/templates.html Bye, bearophile
Mar 14 2009