From: spc@pineal.math.fau.edu
Newsgroups: alt.hackers
Subject: Re: Ugly macros (or whatever that thread is called)
Date: 26 Jan 93 07:53:30 GMT
Organization: are you crazy?


ObHack: I guess posting here ... 8-)

ObUglyMacroHack:

  When trying to do object oriented programming under ANSI-C (no weenie
using C++ here 8-), I needed to manipulate several stacks (each a different
type, one integer, one float, etc ...).  So, I wrote the following C code
(at the end of this message).

  -spc (love playing around with that C preprocessor)

===============[ header file ]=========================================

/***************************************************************************
*
* Because the ## in a macro definition does not expand any argument macros,
* we simply can't do a _MKPROTO(x,y)    x ## y, because then
* _MKPROTO(T_PREFIX,_push) would improperly evaluate to T_PREFIX_push, which
* is what we DON'T want, therefore, we have to do a bit of nesting to get
* what we want.
*
* That's why this looks so strange ...
*
*****************************************************************************/

#define _MKKPROTO(x,y)  x ## y
#define _MKPROTO(x,y)   _MKKPROTO(x,y)

void    _MKPROTO(T_PREFIX,_push)        (T_TYPE);
T_TYPE  _MKPROTO(T_PREFIX,_pop)         (void);
void    _MKPROTO(T_PREFIX,_drop)        (void);
void    _MKPROTO(T_PREFIX,_swap)        (void);
void    _MKPROTO(T_PREFIX,_dup)         (void);
void    _MKPROTO(T_PREFIX,_over)        (void);

/*************************************************************/

==============[ C source file ]=================================

#include "that.header.file.h"

#define DX(x)           x

/*********************************************************************/

void _MKPROTO(T_PREFIX,_push)(T_TYPE v)
{
  struct dictionary *pdc = _MKPROTO(T_PREFIX,_parent);
  T_TYPE            *pv;

  if (pdc->dc_Stackptr == 0)
  {
    _Error(__FILE__,__LINE__,"%s stack overflow",pdc->dc_Node.ln_Name);
    _Stackerr = TRUE;
    return;
  }
  pdc->dc_Stackptr--;
  pv = (T_TYPE *)(pdc->dc_Stack);
  pv[pdc->dc_Stackptr] = v;
}

/********************************************************************/

T_TYPE _MKPROTO(T_PREFIX,_pop)(void)
{
  struct dictionary *pdc = _MKPROTO(T_PREFIX,_parent);
  T_TYPE            *pv;
  T_TYPE             v;

  if (pdc->dc_Stackptr == pdc->dc_Stacktop)
  {
    _Error(__FILE__,__LINE__,"%s stack underflow",pdc->dc_Node.ln_Name);
    _Stackerr = TRUE;
    return(T_RETV);
  }
  pv = (T_TYPE *)(pdc->dc_Stack);
  v  = pv[pdc->dc_Stackptr];

  pdc->dc_Stackptr++;
  return(v);
}

/*******************************************************************/
void _MKPROTO(T_PREFIX,_drop)(void)
{
  struct dictionary *pdc = _MKPROTO(T_PREFIX,_parent);

  if (pdc->dc_Stackptr == pdc->dc_Stacktop)
  {
    _Error(__FILE__,__LINE__,"%s stack underflow",pdc->dc_Node.ln_Name);
    return;
  }
  pdc->dc_Stackptr++;
}

/*****************************************************************/

void _MKPROTO(T_PREFIX,_swap)(void)
{
  T_TYPE v1;
  T_TYPE v2;

  _Stackerr = FALSE;
  v1 = _MKPROTO(T_PREFIX,_pop)();
  if (_Stackerr) return;
  v2 = _MKPROTO(T_PREFIX,_pop)();
  if (_Stackerr) return;
  _MKPROTO(T_PREFIX,_push)(v1);
  if (_Stackerr) return;
  _MKPROTO(T_PREFIX,_push)(v2);
}

/******************************************************************/

void _MKPROTO(T_PREFIX,_dup)(void)
{
  T_TYPE v;

  _Stackerr = FALSE;
  v = _MKPROTO(T_PREFIX,_pop)();
  if (_Stackerr) return;
  _MKPROTO(T_PREFIX,_push)(v);
  _MKPROTO(T_PREFIX,_push)(v);
}

/****************************************************************/

void _MKPROTO(T_PREFIX,_over)(void)
{
  T_TYPE v1;
  T_TYPE v2;

  _Stackerr = FALSE;

  v1 = _MKPROTO(T_PREFIX,_pop)();
  if (_Stackerr) return;
  _MKPROTO(T_PREFIX,_dup)();
  if (_Stackerr) return;
  v2 = _MKPROTO(T_PREFIX,_pop)();
  if (_Stackerr) return;

  _MKPROTO(T_PREFIX,_push)(v1);
  if (_Stackerr) return;
  _MKPROTO(T_PREFIX,_push)(v2);
}
Newsgroups: alt.hackers