July 21, 2017
On Friday, 21 July 2017 at 11:19:47 UTC, Patrick Schluter wrote:
> In C there's no point in the X macro anymore since C99.
> Designated initializer allow to do it properly[1] now.
>
>     enum COLORS { red, blue, green, max };
>     char *cstring[max] = {[red]="red", [blue]="blue", [green]="green" };  /* C99 */

I don't see how this allows data for different arrays to be written in interleaved form and then extracted by column to initialize the separate arrays, as Walter's does.
July 21, 2017
On Friday, 21 July 2017 at 08:06:09 UTC, Stefan Koch wrote:
> My pleasure :)
>
> // ...
>
> mixin((){
>     // ...
>
>     enum Y = [
>         //  id   reg  mask   ty
>         X("AH",   4, mAX, TYuchar),
>         X("AL",   0, mAX, TYuchar),
>         X("AX",   8, mAX, TYushort),
>         X("BH",   7, mBX, TYuchar),
>         X("BL",   3, mBX, TYuchar),
>         // ...
>         X("ESI", 22, mSI, TYulong),
>         X("ESP", 20,   0, TYulong),
>         X("SI",  14, mSI, TYushort),
>         X("SP",  12,   0, TYushort),
>     ];
>
>
>     enum lns = itos(Y.length);
>
>     string pseudotab = "\nprivate __gshared static immutable string[" ~ lns ~ "] pseudotab = [";
>
>     foreach(i, r; Y)
>     {
>         pseudotab ~= `"` ~ r.id ~ `", `;
>     }
>
>     pseudotab ~= "];\n";
>
> }());

Quick questions: isn't it possible to do

    private __gshared const(char)*[24] pseudotab = Y.map!(x => x.id);

instead? That seems like the most obvious and easy to read option; and in contrast to the other solutions proposed, it's closer to the Rule of Least Power.
July 21, 2017
On Friday, 21 July 2017 at 12:27:35 UTC, Olivier FAURE wrote:
>
>     private __gshared const(char)*[24] pseudotab = Y.map!(x => x.id);
>

I meant

     private __gshared static immutable string[Y.length] pseudotab = Y.map!(x => x.id);

but you get my point.

Also, upon trying it, it doesn't seem to work (at least the immutable part doesn't), but I don't really understand why. All the variables in the expression are known at compile time.
July 21, 2017
On 2017-07-21 14:27, Olivier FAURE wrote:

> Quick questions: isn't it possible to do
>
>      private __gshared const(char)*[24] pseudotab = Y.map!(x => x.id);
>
> instead? That seems like the most obvious and easy to read option; and
> in contrast to the other solutions proposed, it's closer to the Rule of
> Least Power.

Yes, that's basically what my solution is doing [1].

[1] http://forum.dlang.org/post/oksd27$1li9$1@digitalmars.com

-- 
/Jacob Carlborg
July 21, 2017
On Thursday, 20 July 2017 at 21:17:45 UTC, Walter Bright wrote:
> Some time ago, I wrote about the X Macro in C:
>
>   https://digitalmars.com/articles/b51.html
>
> I used it from time to time in C code. It's one of the things I actually like about the C preprocessor. But in translating the aged C code to D it was time to make X work in D. Here's the C code, followed by the D translation.

This mechanism is used in LLVM in a number of places, where the list entries are used e.g. to populate tables and to define aggregate member fields.
For example:
https://github.com/llvm-mirror/compiler-rt/blob/master/lib/profile/InstrProfData.inc#L29-L51


July 21, 2017
On Thursday, 20 July 2017 at 22:02:32 UTC, Walter Bright wrote:
> On 7/20/2017 2:21 PM, Stefan Koch wrote:
>> Please tell me this is not going to get into dmd :)
>> templates are so much more expensive then macros.
>> (Well, for now :) )
>> 
>> Those templates can and should be replaced by CTFE.
>
> If you like, present the CTFE solution. Should be fun!

How about this (if I'm not mistaken, this's only one template instantiation per tuple-type&extracted-index):

```d

import std.typecons: tuple, Tuple;
import std.algorithm: map;
import std.array: array;

enum regm_t {
    AX, BX, CX, DX, DI, SI, None
}

enum tym_t {
    uchar_, ushort_, ulong_
}

enum Ydata = [
    tuple("AH",   4, regm_t.AX,   tym_t.uchar_),
    tuple("AL",   0, regm_t.AX,   tym_t.uchar_),
    tuple("AX",   8, regm_t.AX,   tym_t.ushort_),
    tuple("BH",   7, regm_t.BX,   tym_t.uchar_),
    tuple("BL",   3, regm_t.BX,   tym_t.uchar_),
    tuple("BP",  13, regm_t.None, tym_t.ushort_),
    tuple("BX",  11, regm_t.BX,   tym_t.ushort_),
    tuple("CH",   5, regm_t.CX,   tym_t.uchar_),
    tuple("CL",   1, regm_t.CX,   tym_t.uchar_),
    tuple("CX",   9, regm_t.CX,   tym_t.ushort_),
    tuple("DH",   6, regm_t.DX,   tym_t.uchar_),
    tuple("DI",  15, regm_t.DI,   tym_t.ushort_),
    tuple("DL",   2, regm_t.DX,   tym_t.uchar_),
    tuple("DX",  10, regm_t.DX,   tym_t.ushort_),
    tuple("EAX", 16, regm_t.AX,   tym_t.ulong_),
    tuple("EBP", 21, regm_t.None, tym_t.ulong_),
    tuple("EBX", 19, regm_t.BX,   tym_t.ulong_),
    tuple("ECX", 17, regm_t.CX,   tym_t.ulong_),
    tuple("EDI", 23, regm_t.DI,   tym_t.ulong_),
    tuple("EDX", 18, regm_t.DX,   tym_t.ulong_),
    tuple("ESI", 22, regm_t.SI,   tym_t.ulong_),
    tuple("ESP", 20, regm_t.None, tym_t.ulong_),
    tuple("SI",  14, regm_t.SI,   tym_t.ushort_),
    tuple("SP",  12, regm_t.None, tym_t.ushort_),
];

static auto Y(size_t idx, T...)(Tuple!(T)[] ts) pure nothrow {
    // I thought to try something like assumeUnique here
    // but was thinking of the Rust semantics in doing so
    // Not sure if this leads to spurious allocations at
    // the points where Y is used. Is there someway to tell them,
    // even if the target type is const or immutable
    // that this returned array is brand new with no other references
    // around?
    return ts
            .map!(x => x[idx])
            .array
            ;
}

enum {
    Xtab = 0,
    Xreg,
    Xmask,
    Xty,
}

// Register number to use in addressing mode
private __gshared const(char)*[24] pseudotab = Y!Xtab(Ydata);


// Register number to use in addressing mode
__gshared ubyte[24] pseudoreg = Y!Xreg(Ydata);


// Mask to use for registers affected
__gshared regm_t[24] pseudomask = Y!Xmask(Ydata);


// Table for type of pseudo register variable
private __gshared const(tym_t)[24] pseudoty = Y!Xty(Ydata);
```
July 21, 2017
On Friday, 21 July 2017 at 19:26:05 UTC, Johan Engelen wrote:
> On Thursday, 20 July 2017 at 21:17:45 UTC, Walter Bright wrote:
>> Some time ago, I wrote about the X Macro in C:
>>
>>   https://digitalmars.com/articles/b51.html
>>
>> I used it from time to time in C code. It's one of the things I actually like about the C preprocessor. But in translating the aged C code to D it was time to make X work in D. Here's the C code, followed by the D translation.
>
> This mechanism is used in LLVM in a number of places, where the list entries are used e.g. to populate tables and to define aggregate member fields.
> For example:
> https://github.com/llvm-mirror/compiler-rt/blob/master/lib/profile/InstrProfData.inc#L29-L51

And those in turn are generated from TableGen.
July 22, 2017
On Friday, 21 July 2017 at 20:44:13 UTC, Enamex wrote:
> On Thursday, 20 July 2017 at 22:02:32 UTC, Walter Bright wrote:
>> [...]
>
> How about this (if I'm not mistaken, this's only one template instantiation per tuple-type&extracted-index):
>
> [...]

tuple map and array are all pretty expensive.

please profile.
July 22, 2017
On Saturday, 22 July 2017 at 11:50:40 UTC, Stefan Koch wrote:
> tuple map and array are all pretty expensive.
>
> please profile.

Well a bit more compile time isn't the end of the world, and by far not the only metric (e.g. readability and maintainability also rank high). You're slightly obsessed with the template compile-time topic ;).

BTW, the term expensive is fairly subjective easily misunderstood. Sth. more specific would reduce the chance for confusion, e.g. "tuple map and array require longer to compile"
1 2
Next ›   Last »