On Wed, Feb 24, 2021 at 08:10:30PM +0000, Mike Brown via Digitalmars-d-learn 
wrote:
[...]
> Thank you for the reply. Im struggling extending this to get the
> nesting working.
> 
> I'm trying something like:
> 
> string entry(string i, string[] inherit = []) {
>       return i;
> }
> 
> alias token_type2 = PrimeEnum!(
>       entry("unknown"),
>       entry("newline"),
>       entry("identifier"),
>       entry("var", ["identifier"]),
>       entry("userDefined", ["identifier"])
> );
> 
> Its worth noting that multiple inherited bases are needed too.
> 
> But I can't get those functions contexts linking, can I pass a
> function pointer as lazy into the PrimeEnum!() template?
> 
> Would it be easier to just parse the text at once into a single
> templating function?
[...]

Ah, so sorry, I completely overlooked the nesting part.  PrimeEnum as I
defined it in my first reply does not handle this at all, so it will
need to be extended.

Since we're dealing with a tree structure here, I think the best way is
to express the tree structure explicitly in a compile-time data
structure. Thanks to CTFE, this works pretty much exactly the same as
normal runtime data structures; the only difference is that they will be
processed at compile-time.

Here's a rough sketch of how I'd do it:

        class Entry {
                string ident;
                Entry[] subentries;
                this(string _id, Entry[] _subs = []) {
                        ident = _id;
                        subentries = _subs;
                }
        }

        Entry[] makeIdentTrees() {
                return [
                        new Entry("endOfFile"),
                        new Entry("unknown"),
                        new Entry("newline"),
                        new Entry("identifier", [
                                new Entry("userDefined"),
                                new Entry("var"),
                                new Entry("uses"),
                                ... // you get the idea
                        ],
                        new Entry("operator", [
                                new Entry("copyAssignment"),
                                ... // etc.
                        ]));
                ]
        }

You'd then write a recursive function that traverses this tree, using a
compile-time array of prime numbers, and compute the enum values that
way.  Format that into D code as a string, and use mixin to actually
create the enum.  The function can be written just like any runtime D
code, as long as it does not use any CTFE-incompatible language
features.

        string genEnum(Entry[] entries) {
                string code;
                ... // traverse tree and generate D code here
                return code;
        }

        // Create the enum
        mixin(genEnum(makeIdentTrees()));


T

-- 
A mathematician learns more and more about less and less, until he knows 
everything about nothing; whereas a philospher learns less and less about more 
and more, until he knows nothing about everything.

Reply via email to