The X Macro using D

Nicholas Wilson via Digitalmars-d digitalmars-d at puremagic.com
Fri Jul 21 04:30:48 PDT 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.
>
> (I suppose it could be done with C++ templates, but I'll leave 
> that to Andrei or Eric Niebler <g>.)
>
> ================ C Version ================
>
> // Macro trick to generate several parallel tables
>
> #define Y \
>         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("BP",13,0,TYushort)   \
>         X("BX",11,mBX,TYushort) \
>         X("CH",5,mCX,TYuchar)   \
>         X("CL",1,mCX,TYuchar)   \
>         X("CX",9,mCX,TYushort)  \
>         X("DH",6,mDX,TYuchar)   \
>         X("DI",15,mDI,TYushort) \
>         X("DL",2,mDX,TYuchar)   \
>         X("DX",10,mDX,TYushort) \
>         X("EAX",16,mAX,TYulong) \
>         X("EBP",21,0,TYulong)   \
>         X("EBX",19,mBX,TYulong) \
>         X("ECX",17,mCX,TYulong) \
>         X("EDI",23,mDI,TYulong) \
>         X("EDX",18,mDX,TYulong) \
>         X("ESI",22,mSI,TYulong) \
>         X("ESP",20,0,TYulong)   \
>         X("SI",14,mSI,TYushort) \
>         X("SP",12,0,TYushort)
>
> // Table for identifiers
> static const char *pseudotab[] =
> {
> #define X(id,reg,m,ty)  id,
>         Y
> #undef X
> };
>
> // Register number to use in addressing mode
> unsigned char pseudoreg[] =
> {
> #define X(id,reg,m,ty)  reg,
>         Y
> #undef X
> };
>
> // Mask to use for registers affected
> regm_t pseudomask[] =
> {
> #define X(id,reg,m,ty)  m,
>         Y
> #undef X
> };
>
> // Table for type of pseudo register variable
> static unsigned char pseudoty[] =
> {
> #define X(id,reg,m,ty)  mTYvolatile | ty,
>         Y
> #undef X
> };
>
> ================ D Version ================
>
> /* 4 parallel tables using "X Macro" technique
>  */
>
> template Y(alias X)
> {
>     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!("BP",  13,   0, TYushort),
>         X!("BX",  11, mBX, TYushort),
>         X!("CH",   5, mCX, TYuchar),
>         X!("CL",   1, mCX, TYuchar),
>         X!("CX",   9, mCX, TYushort),
>         X!("DH",   6, mDX, TYuchar),
>         X!("DI",  15, mDI, TYushort),
>         X!("DL",   2, mDX, TYuchar),
>         X!("DX",  10, mDX, TYushort),
>         X!("EAX", 16, mAX, TYulong),
>         X!("EBP", 21,   0, TYulong),
>         X!("EBX", 19, mBX, TYulong),
>         X!("ECX", 17, mCX, TYulong),
>         X!("EDI", 23, mDI, TYulong),
>         X!("EDX", 18, mDX, TYulong),
>         X!("ESI", 22, mSI, TYulong),
>         X!("ESP", 20,   0, TYulong),
>         X!("SI",  14, mSI, TYushort),
>         X!("SP",  12,   0, TYushort),
>     ];
> }
>
> // Table for identifiers
>
> template Xtab(alias A, alias B, alias C, alias D) { enum Xtab = 
> A; }
>
> private __gshared const(char)*[24] pseudotab = Y!Xtab;
>
>
> // Register number to use in addressing mode
>
> template Xreg(alias A, alias B, alias C, alias D) { enum Xreg = 
> B; }
>
> __gshared ubyte[24] pseudoreg = Y!Xreg;
>
>
> // Mask to use for registers affected
>
> template Xmask(alias A, alias B, alias C, alias D) { enum Xmask 
> = C; }
>
> __gshared regm_t[24] pseudomask = Y!Xmask;
>
>
> // Table for type of pseudo register variable
>
> template Xty(alias A, alias B, alias C, alias D) { enum Xty = 
> mTYvolatile | D; }
>
> private __gshared const(tym_t)[24] pseudoty = Y!Xty;

I wonder if you could use one of the SoA implementations (e.g 
from here: 
https://wiki.dlang.org/Transforming_slice_of_structs_into_struct_of_slices) to the same effect.


More information about the Digitalmars-d mailing list