www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Converting C/C++ Code to D (#define extern)

reply exiquio <exiquio gmail.com> writes:
Good day to all.

I am writing an chess engine based upon an established C++ engine as a 
interesting, yet practical excersise.

While translating a header file (I am not proficiant in C\C++) I ran into 
some things I find difficult findinf a way to do in D. Here are a few 
examples of what I am talking about (w/ no particular order):

CODE:

#define PawnListStart(pos,side) PieceListStart(pos,PawnOfColour(side))
#define KnightListStart(pos,side) PieceListStart(pos,KnightOfColour(side))
#define BishopListStart(pos,side) PieceListStart(pos,BishopOfColour(side))
#define RookListStart(pos,side) PieceListStart(pos,RookOfColour(side))
#define QueenListStart(pos,side) PieceListStart(pos,QueenOfColour(side))


#define MovePiece(pos,from,to) do {                 \
    PieceList(pos,to) = PieceList(pos,from);            \
    PrevPiece(pos,NextPiece(pos,to)) = to;      \
    NextPiece(pos,PrevPiece(pos,to)) = to;      \
  } while(0)


extern uint8 PawnRank[2][128];
extern attack_data_t AttackData_[256];
extern attack_data_t *AttackData;

END CODE

Forgive me for being ignorant and thanks in advance.
Sep 26 2006
next sibling parent reply Serg Kovrov <kovrov no.spam> writes:
Hi exiquio, you wrote:
 #define PawnListStart(pos,side) PieceListStart(pos,PawnOfColour(side))
 #define KnightListStart(pos,side) PieceListStart(pos,KnightOfColour(side))
 #define BishopListStart(pos,side) PieceListStart(pos,BishopOfColour(side))
 #define RookListStart(pos,side) PieceListStart(pos,RookOfColour(side))
 #define QueenListStart(pos,side) PieceListStart(pos,QueenOfColour(side))
 
 
 #define MovePiece(pos,from,to) do {                 \
     PieceList(pos,to) = PieceList(pos,from);            \
     PrevPiece(pos,NextPiece(pos,to)) = to;      \
     NextPiece(pos,PrevPiece(pos,to)) = to;      \
   } while(0)

It is a good example of C-macros used when inline functions should be. Just define functions that do this stuff.
 result_type PawnListStart(pos_type pos, side_type side)
 {
   return PieceListStart(pos, PawnOfColour(side));
 }
 ...
 void MovePiece(pos_type pos, from_type from, to_type to)
 {
   do
   {
     PieceList(pos, to) = PieceList(pos,from);
     PrevPiece(pos, NextPiece(pos, to)) = to;
     NextPiece(pos, PrevPiece(pos, to)) = to;
   }
   while(0);
 }

Although later is somewhat suspicious - how loop meant to break?. Perhaps there is another macro called as function, that has a break statement. You could investigate what exactly it should do and rewrite it more clear. -- serg.
Sep 26 2006
next sibling parent reply Serg Kovrov <kovrov no.spam> writes:
Serg Kovrov wrote:
 do
 {
   PieceList(pos, to) = PieceList(pos,from);
   PrevPiece(pos, NextPiece(pos, to)) = to;
   NextPiece(pos, PrevPiece(pos, to)) = to;
 }
 while(0);

 Although later is somewhat suspicious - how loop meant to break?. 
 Perhaps there is another macro called as function, that has a break 
 statement. You could investigate what exactly it should do and rewrite 
 it more clear.

How stupid of me =)
 do {...} while(0);

-- serg.
Sep 26 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Serg Kovrov wrote:
 Serg Kovrov wrote:
 do
 {
   PieceList(pos, to) = PieceList(pos,from);
   PrevPiece(pos, NextPiece(pos, to)) = to;
   NextPiece(pos, PrevPiece(pos, to)) = to;
 }
 while(0);

 Although later is somewhat suspicious - how loop meant to break?. 
 Perhaps there is another macro called as function, that has a break 
 statement. You could investigate what exactly it should do and rewrite 
 it more clear.

How stupid of me =)
 do {...} while(0);


I remember a long while ago I read something about writing macro functions like this. I forgot why you have to add do while(0) but it's a trick to make the macro a /little bit/ more robust ...
Sep 26 2006
parent Serg Kovrov <kovrov no.spam> writes:
Hi Hasan Aljudy, you wrote:
 I remember a long while ago I read something about writing macro 
 functions like this. I forgot why you have to add do while(0) but it's a 
 trick to make the macro a /little bit/ more robust ...

You right, it is exactly robustness issue. I think I understand now why - to use such multi-line macro with 'bracesless' (that is, one line) case of statements if/for/while. It is ugly-looking, but perhaps useful hack. PS. good thing, we can learn here not just D stuff, but in fact other languages tricks as well =) -- serg.
Sep 26 2006
prev sibling next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Serg Kovrov wrote:
 Hi exiquio, you wrote:

 #define MovePiece(pos,from,to) do {                 \
     PieceList(pos,to) = PieceList(pos,from);            \
     PrevPiece(pos,NextPiece(pos,to)) = to;      \
     NextPiece(pos,PrevPiece(pos,to)) = to;      \
   } while(0)


 Although later is somewhat suspicious - how loop meant to break?. 
 Perhaps there is another macro called as function, that has a break 
 statement. You could investigate what exactly it should do and rewrite 
 it more clear.
 

That's a C preprocessor trick so that a call to the macro can pretend to be a regular function call. It allows you to introduce a local variable, or have an if-else or loop in the macro. E.g. #define MaybeDoIt(cond) if (cond) \ { int ret; \ ret = prepareToDoIt(); \ doIt(); \ } If you write it like that you can't call it like "MaybeDoIt(false);". The ';' on the end is syntactically incorrect. Many C/C++ compilers would barf on it. So you wrap it in a do while which needs a ';' at the end: #define MaybeDoIt(cond) do{\ if (cond) \ { int ret; \ ret = prepareToDoIt(); \ doIt(); \ } \ while(0) In this case it's really not necessary, though. No loops, if-elses, or local variables are introduced so it could just be: #define MovePiece(pos,from,to) \ PieceList(pos,to) = PieceList(pos,from); \ PrevPiece(pos,NextPiece(pos,to)) = to; \ NextPiece(pos,PrevPiece(pos,to)) = to Then you would call it like "MovePiece(a,b,c);" from your code. Either way this should just be made into a regular function. (Which D will inline if it feels like it). --bb
Oct 02 2006
prev sibling parent Brad Roberts <braddr puremagic.com> writes:
Bill Baxter wrote:
 Serg Kovrov wrote:
 Hi exiquio, you wrote:

 #define MovePiece(pos,from,to) do {                 \
     PieceList(pos,to) = PieceList(pos,from);            \
     PrevPiece(pos,NextPiece(pos,to)) = to;      \
     NextPiece(pos,PrevPiece(pos,to)) = to;      \
   } while(0)


 Although later is somewhat suspicious - how loop meant to break?. 
 Perhaps there is another macro called as function, that has a break 
 statement. You could investigate what exactly it should do and rewrite 
 it more clear.

That's a C preprocessor trick so that a call to the macro can pretend to be a regular function call. It allows you to introduce a local variable, or have an if-else or loop in the macro. E.g. #define MaybeDoIt(cond) if (cond) \ { int ret; \ ret = prepareToDoIt(); \ doIt(); \ } If you write it like that you can't call it like "MaybeDoIt(false);". The ';' on the end is syntactically incorrect. Many C/C++ compilers would barf on it. So you wrap it in a do while which needs a ';' at the end: #define MaybeDoIt(cond) do{\ if (cond) \ { int ret; \ ret = prepareToDoIt(); \ doIt(); \ } \ while(0) In this case it's really not necessary, though. No loops, if-elses, or local variables are introduced so it could just be: #define MovePiece(pos,from,to) \ PieceList(pos,to) = PieceList(pos,from); \ PrevPiece(pos,NextPiece(pos,to)) = to; \ NextPiece(pos,PrevPiece(pos,to)) = to Then you would call it like "MovePiece(a,b,c);" from your code. Either way this should just be made into a regular function. (Which D will inline if it feels like it). --bb

But you can't do: if (cond) MovePiece(a, b, c); and have it behave as you'd expect with your suggested definition but it would work as expected in the original form. do/while loops form a valid block, and that's the key difference. Later, Brad
Oct 02 2006
prev sibling next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Nice, I'm sure the D code will be a lot cleaner. Have you found relevant 
links on digital mars? These I found useful:

http://www.digitalmars.com/d/htomodule.html
http://www.digitalmars.com/d/ctod.html
http://www.digitalmars.com/d/cpptod.html
http://www.digitalmars.com/d/pretod.html

If you're willing to share I would be interested in the end result.

exiquio wrote:
 Good day to all.
 
 I am writing an chess engine based upon an established C++ engine as a 
 interesting, yet practical excersise.
 
 While translating a header file (I am not proficiant in C\C++) I ran into 
 some things I find difficult findinf a way to do in D. Here are a few 
 examples of what I am talking about (w/ no particular order):
 
 CODE:
 
 #define PawnListStart(pos,side) PieceListStart(pos,PawnOfColour(side))
 #define KnightListStart(pos,side) PieceListStart(pos,KnightOfColour(side))
 #define BishopListStart(pos,side) PieceListStart(pos,BishopOfColour(side))
 #define RookListStart(pos,side) PieceListStart(pos,RookOfColour(side))
 #define QueenListStart(pos,side) PieceListStart(pos,QueenOfColour(side))
 
 
 #define MovePiece(pos,from,to) do {                 \
     PieceList(pos,to) = PieceList(pos,from);            \
     PrevPiece(pos,NextPiece(pos,to)) = to;      \
     NextPiece(pos,PrevPiece(pos,to)) = to;      \
   } while(0)
 
 
 extern uint8 PawnRank[2][128];
 extern attack_data_t AttackData_[256];
 extern attack_data_t *AttackData;
 
 END CODE
 
 Forgive me for being ignorant and thanks in advance.

Sep 26 2006
prev sibling parent exiquio <exiquio gmail.com> writes:
Thanks for the replying. I never really used newsgroups before, and this D 
ng is pretty impressive. I look forward to adding on to the community. I 
will share the final program (the UCI chess engine, and hopefully a UCI 
GUI) when it is working. I will probably post it to dsource.org. I believe 
in "free" software in the GNU since. I believe that D is an incledible 
language, so I think that even my amatuer code will be of some use.
Sep 26 2006