Can Metaprogramming Help Here?
H. S. Teoh
hsteoh at quickfur.ath.cx
Fri Feb 26 19:37:18 UTC 2021
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.
More information about the Digitalmars-d-learn
mailing list