The X Macro using D

Enamex via Digitalmars-d digitalmars-d at puremagic.com
Fri Jul 21 13:44:13 PDT 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);
```


More information about the Digitalmars-d mailing list