/* Version 0.0
** From "Wayne's Little DSA Library" (DSA == Data Structures and
** Algorithms) Feel free to change, modify, or burn these sources, but if
** you modify them please don't distribute your changes without a clear
** indication that you've done so.  If you think your change is spiffy,
** send it to me and maybe I'll include it in the next release.
**
** Wayne Hayes, wayne@csri.utoronto.ca (preffered), or wayne@csri.toronto.edu
*/

/* array implementation of a stack, from Lewis & Denenberg, p 76. */

#include "misc.h"
#include "stack.h"
#include <assert.h>
#include <malloc.h>
#include <stdio.h>

STACK *StackAlloc(int maxSize)
{
    STACK *s = Malloc(sizeof(STACK));

    s->maxSize = maxSize;
    s->stack = Malloc((maxSize+1)*sizeof(foint));
    s->stack[0].i = 0;
    return s;
}

void StackFree(STACK *s)
{
    free(s->stack);
    free(s);
}


foint StackTop(STACK *s)
{
    if(s->stack[0].i == 0)
	Fatal("StackTop: empty stack");
    return s->stack[s->stack[0].i];
}

/* also returns top */
foint StackPop(STACK *s)
{
    foint top = StackTop(s);
    --s->stack[0].i;
    return top;
}

/* returns element pushed */
foint StackPush(STACK *s, foint new)
{
    if(s->stack[0].i == s->maxSize) /* dynamically increase it's size */
    {
	int newSize = 2 * s->maxSize;
	s->stack = Realloc(s->stack, (newSize+1)*sizeof(foint));
	s->maxSize = newSize;
    }
    ++s->stack[0].i;
    s->stack[s->stack[0].i] = new;
    return new;
}

/* returns the element n items below the top.  StackBelowTop(s, 0)
** gives the same result as StackTop(s)
*/
foint StackBelowTop(STACK *s, int n)
{
    if(s->stack[0].i - n < 1)
	Fatal("StackBelowTop: too far down");
    return s->stack[s->stack[0].i - n];
}

int StackSize(STACK *s)
{
    return s->stack[0].i;
}
