dynamic_stack.h

00001 /* File:      dynamic_stack.h
00002 ** Author(s): Ernie Johnson
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00006 ** 
00007 ** XSB is free software; you can redistribute it and/or modify it under the
00008 ** terms of the GNU Library General Public License as published by the Free
00009 ** Software Foundation; either version 2 of the License, or (at your option)
00010 ** any later version.
00011 ** 
00012 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00013 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00015 ** more details.
00016 ** 
00017 ** You should have received a copy of the GNU Library General Public License
00018 ** along with XSB; if not, write to the Free Software Foundation,
00019 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020 **
00021 ** $Id: dynamic_stack.h,v 1.3 2005/01/14 18:30:55 ruim Exp $
00022 ** 
00023 */
00024 
00025 
00026 #ifndef DYNAMIC_STACK
00027 
00028 #define DYNAMIC_STACK
00029 
00030 
00031 
00032 /*-------------------------------------------------------------------------*/
00033 
00034 /* Dynamic Stack Structure
00035    ----------------------- */
00036 typedef struct {
00037   struct {
00038     void *top;             /* next available frame */
00039     void *base;            /* stack bottom */
00040     void *ceiling;         /* off-end pointer for determining fullness */
00041   } stack;
00042   struct {
00043     size_t frame;          /* size of a frame */
00044     size_t stackinit;      /* initial size of stack in number of frames */
00045     size_t stackcur;       /* current size of stack in number of frames */
00046   } size;
00047   char *name;
00048 } DynamicStack;
00049 
00050 #define DynStk_Top(DS)          ( (DS).stack.top )
00051 #define DynStk_Base(DS)         ( (DS).stack.base )
00052 #define DynStk_Ceiling(DS)      ( (DS).stack.ceiling )
00053 #define DynStk_FrameSize(DS)    ( (DS).size.frame )
00054 #define DynStk_InitSize(DS)     ( (DS).size.stackinit )
00055 #define DynStk_CurSize(DS)      ( (DS).size.stackcur )
00056 #define DynStk_Name(DS)         ( (DS).name )
00057 
00058 #define DynStk_NumFrames(DS)    \
00059    (((char *)DynStk_Top(DS) - (char *)DynStk_Base(DS)) / DynStk_FrameSize(DS))
00060 
00061 
00062 /* Top-of-Stack Manipulations
00063    -------------------------- */
00064 #define DynStk_NextFrame(DS)    \
00065    (void *)((char *)DynStk_Top(DS) + DynStk_FrameSize(DS))
00066 #define DynStk_PrevFrame(DS)    \
00067    (void *)((char *)DynStk_Top(DS) - DynStk_FrameSize(DS))
00068 
00069 
00070 /* Stack Maintenance
00071    ----------------- */
00072 extern void dsPrint(DynamicStack, char *);
00073 extern void dsInit(DynamicStack *, size_t, size_t, char *);
00074 extern void dsExpand(DynamicStack *, int);
00075 extern void dsShrink(DynamicStack *);
00076 
00077 #define DynStk_Init(DS,NumElements,FrameType,Desc)      \
00078    dsInit(DS,NumElements,sizeof(FrameType),Desc)
00079 
00080 #define DynStk_ResetTOS(DS)     DynStk_Top(DS) = DynStk_Base(DS)
00081 #define DynStk_IsEmpty(DS)      ( DynStk_Top(DS) == DynStk_Base(DS) )
00082 #define DynStk_IsFull(DS)       ( DynStk_Top(DS) >= DynStk_Ceiling(DS) )
00083 
00084 #define DynStk_WillOverflow(DS,NFrames)                         \
00085    ( (char *)DynStk_Top(DS) + NFrames * DynStk_FrameSize(DS)    \
00086      > (char *)DynStk_Ceiling(DS) )
00087 
00088 
00089 #define DynStk_ExpandIfFull(DS) {               \
00090    if ( DynStk_IsFull(DS) )                     \
00091      dsExpand(&(DS),1);                         \
00092  }
00093 
00094 #define DynStk_ExpandIfOverflow(DS,N) {         \
00095    if ( DynStk_WillOverflow(DS,N) )             \
00096      dsExpand(&(DS),N);                         \
00097  }
00098 
00099 
00100 /*
00101  * In the following macros, "Frame" is assigned a pointer to either
00102  * the next or the current frame on the stack.
00103  */
00104 
00105 /* Operations With Bounds Checking
00106    ------------------------------- */
00107 #define DynStk_Push(DS,Frame) {                 \
00108    DynStk_ExpandIfFull(DS);                     \
00109    DynStk_BlindPush(DS,Frame);                  \
00110  }
00111 
00112 #define DynStk_Pop(DS,Frame) {                  \
00113    if ( ! DynStk_IsEmpty(DS) )                  \
00114      DynStk_BlindPop(DS,Frame)                  \
00115    else                                         \
00116      Frame = NULL;                              \
00117  }
00118 
00119 #define DynStk_Peek(DS,Frame) {                 \
00120    if ( ! DynStk_IsEmpty(DS) )                  \
00121      DynStk_BlindPeek(DS,Frame);                \
00122    else                                         \
00123      Frame = NULL;                              \
00124  }
00125 
00126 
00127 /* Operations Without Bounds Checking
00128    ---------------------------------- */
00129 #define DynStk_BlindPush(DS,Frame) {            \
00130    Frame = DynStk_Top(DS);                      \
00131    DynStk_Top(DS) = DynStk_NextFrame(DS);       \
00132  }
00133 
00134 #define DynStk_BlindPop(DS,Frame) {             \
00135    DynStk_Top(DS) = DynStk_PrevFrame(DS);       \
00136    Frame = DynStk_Top(DS);                      \
00137  }
00138 
00139 #define DynStk_BlindPeek(DS,Frame)              \
00140    Frame = DynStk_PrevFrame(DS)
00141 
00142 /*-------------------------------------------------------------------------*/
00143 
00144 
00145 #endif

Generated on Wed Jul 26 13:30:40 2006 for XSB by  doxygen 1.4.5