Thread overview
CT regex in AA at compile time
Jan 07, 2020
Taylor Hillegeist
Jan 07, 2020
MoonlightSentinel
Jan 07, 2020
Taylor Hillegeist
Jan 07, 2020
Patrick Schluter
January 07, 2020
I'm trying to trick the following code snippet into compilation.

enum TokenType{
	//Terminal
	Plus,
	Minus,
	LPer,
	RPer,
	Number,
}

static auto Regexes =[
  TokenType.Plus:   ctRegex!(`^ *\+`),
  TokenType.Minus:  ctRegex!(`^ *\-`),
  TokenType.LPer:   ctRegex!(`^ *\(`),
  TokenType.RPer:   ctRegex!(`^ *\)`),
  TokenType.Number: ctRegex!(`^ *[0-9]+(.[0-9]+)?`)
];

but I can't get it to work. it says its an Error: non-constant expression.

I imagine this has to do with the ctRegex template or something. maybe there is a better way? Does anyone know?
January 07, 2020
On Tuesday, 7 January 2020 at 15:40:58 UTC, Taylor Hillegeist wrote:
> but I can't get it to work. it says its an Error: non-constant expression.
>
> I imagine this has to do with the ctRegex template or something. maybe there is a better way? Does anyone know?

This issue is unrelated to ctRegex, AA literals are non-constant expressions (probably due to their implementation). You can work around this by using module constructors or lazy initialisation inside of a function:

static Regex!char[TokenType] Regexes;

shared static this()
{
    Regexes = [
        TokenType.Plus:   ctRegex!(`^ *\+`),
        TokenType.Minus:  ctRegex!(`^ *\-`),
        TokenType.LPer:   ctRegex!(`^ *\(`),
        TokenType.RPer:   ctRegex!(`^ *\)`),
        TokenType.Number: ctRegex!(`^ *[0-9]+(.[0-9]+)?`)
    ];
}
January 07, 2020
On Tuesday, 7 January 2020 at 15:51:21 UTC, MoonlightSentinel wrote:
> On Tuesday, 7 January 2020 at 15:40:58 UTC, Taylor Hillegeist wrote:
>> but I can't get it to work. it says its an Error: non-constant expression.
>>
>> I imagine this has to do with the ctRegex template or something. maybe there is a better way? Does anyone know?
>
> This issue is unrelated to ctRegex, AA literals are non-constant expressions (probably due to their implementation). You can work around this by using module constructors or lazy initialisation inside of a function:
>
> static Regex!char[TokenType] Regexes;
>
> shared static this()
> {
>     Regexes = [
>         TokenType.Plus:   ctRegex!(`^ *\+`),
>         TokenType.Minus:  ctRegex!(`^ *\-`),
>         TokenType.LPer:   ctRegex!(`^ *\(`),
>         TokenType.RPer:   ctRegex!(`^ *\)`),
>         TokenType.Number: ctRegex!(`^ *[0-9]+(.[0-9]+)?`)
>     ];
> }

Thank you for bringing this to my attention.

also, the solution you used is very cool. I had no idea you could put shared static this()
just anywhere and have it execute just like it was in main! Does this work for dlls as well?
January 07, 2020
On 1/7/20 11:00 AM, Taylor Hillegeist wrote:
> On Tuesday, 7 January 2020 at 15:51:21 UTC, MoonlightSentinel wrote:
>> On Tuesday, 7 January 2020 at 15:40:58 UTC, Taylor Hillegeist wrote:
>>> but I can't get it to work. it says its an Error: non-constant expression.
>>>
>>> I imagine this has to do with the ctRegex template or something. maybe there is a better way? Does anyone know?
>>
>> This issue is unrelated to ctRegex, AA literals are non-constant expressions (probably due to their implementation).

Correct. A compile-time AA is much different in implementation/layout than a runtime AA. So you can't initialize them at compile time.

> also, the solution you used is very cool. I had no idea you could put shared static this()
> just anywhere and have it execute just like it was in main! Does this work for dlls as well?

dlls run static constructors upon loading. Thought I'm not too familiar with how it exactly works, I know that there can be some trickiness when using dlls on Windows.

See information about static constructors/destructors here: https://dlang.org/spec/class.html#static-constructor

No idea why it's in the class section, potentially it was only for classes at one point?

Information about using DLLs in windows with D is here: https://wiki.dlang.org/Win32_DLLs_in_D

-Steve
January 07, 2020
On Tuesday, 7 January 2020 at 15:40:58 UTC, Taylor Hillegeist wrote:
> I'm trying to trick the following code snippet into compilation.
>
> enum TokenType{
> 	//Terminal
> 	Plus,
> 	Minus,
> 	LPer,
> 	RPer,
> 	Number,
> }
>
> static auto Regexes =[
>   TokenType.Plus:   ctRegex!(`^ *\+`),
>   TokenType.Minus:  ctRegex!(`^ *\-`),
>   TokenType.LPer:   ctRegex!(`^ *\(`),
>   TokenType.RPer:   ctRegex!(`^ *\)`),
>   TokenType.Number: ctRegex!(`^ *[0-9]+(.[0-9]+)?`)
> ];
>
> but I can't get it to work. it says its an Error: non-constant expression.
>
> I imagine this has to do with the ctRegex template or something. maybe there is a better way? Does anyone know?

In that specific case: why don't you use an array indexed on TokenType? TokenType are consecutive integrals so indexing is the fastest possible access method.