www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Enums with Inline Subclass

reply mark_mcs <mark mnetcs.com> writes:
I spend most of my time in java land but try to sneak in some D 
code whenever possible. One pattern that comes in handy is to use 
Java enums as states in a finite state machine (good for XML 
parsers). Given that D supports enums with custom base types, I 
was curious to see if this pattern would translate.

The code looks like this:


interface A
{
     void process();
}

enum Test : A
{
     Value1 = new class A {
         override void process() { writeln("Value1"); }
     },
     Value2 = new class A {
         override void process() { writeln("Value2"); }
     }
}

void main()
{
     Test.Value1.process();
}


It's syntactically valid but you get linker errors. Seems the 
compiler doesn't generate the vtable for the inline classes:

undefined reference to `_D3app4Test12__anonclass16__vtblZ'
undefined reference to `_D3app4Test12__anonclass17__ClassZ

My question is: should this be possible? Is this a grammar bug or 
a codegen bug?
Nov 13 2019
next sibling parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Wednesday, 13 November 2019 at 20:46:25 UTC, mark_mcs wrote:
 I spend most of my time in java land but try to sneak in some D 
 code whenever possible. One pattern that comes in handy is to 
 use Java enums as states in a finite state machine (good for 
 XML parsers). Given that D supports enums with custom base 
 types, I was curious to see if this pattern would translate.

 The code looks like this:


 interface A
 {
     void process();
 }

 enum Test : A
 {
     Value1 = new class A {
         override void process() { writeln("Value1"); }
     },
     Value2 = new class A {
         override void process() { writeln("Value2"); }
     }
 }

 void main()
 {
     Test.Value1.process();
 }


 It's syntactically valid but you get linker errors. Seems the 
 compiler doesn't generate the vtable for the inline classes:

 undefined reference to `_D3app4Test12__anonclass16__vtblZ'
 undefined reference to `_D3app4Test12__anonclass17__ClassZ

 My question is: should this be possible? Is this a grammar bug 
 or a codegen bug?
That is some odd code you got there. I would not have expected it to work. Normally references to objects cannot be stored in an enum. But if you change the interface into a class, and define the anonymous classes with a name, then it works: import std; class I { void process() {} } class C : I { override void process() { writeln("C"); } } class D : I { override void process() { writeln("D"); } } // enum e = new C; // Unable to initialize enum with class or pointer to struct. Use static const variable instead. enum e3 : I { val1 = new C, val2 = new D, val3 = new class I { override void process() { writeln("E"); } } }; void main() { e3.val1.process; e3.val2.process; // e3.val3.process; // link error } Bastiaan.
Nov 13 2019
prev sibling next sibling parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Wednesday, 13 November 2019 at 20:46:25 UTC, mark_mcs wrote:
 I spend most of my time in java land but try to sneak in some D 
 code whenever possible. One pattern that comes in handy is to 
 use Java enums as states in a finite state machine (good for 
 XML parsers).
You might be interested in https://code.dlang.org/packages/state-machine Bastiaan.
Nov 14 2019
prev sibling parent Suleyman <sahmi.soulaimane gmail.com> writes:
On Wednesday, 13 November 2019 at 20:46:25 UTC, mark_mcs wrote:
 [...]
 My question is: should this be possible? Is this a grammar bug 
 or a codegen bug?
You should open an issue at https://issues.dlang.org/. This works: ``` class I {} static I obj; static this() { obj = new class I {}; } void main() {} ``` But this doesn't: ``` class I {} static immutable I obj = cast(immutable) new class I {}; void main() {} ```
Nov 14 2019