/* File: stacks.c
 * Author: Jim Mayfield
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef void *stack_item_type;
#include "stacks.h"

#define MAX_STACK_SIZE	256

/* In this implementation of stacks, a stack is of fixed size. */
typedef struct stack_tag {
  int count;
  stack_item_type items[MAX_STACK_SIZE];
} stack_struct_type;

/* Create_stack allocates and returns a new empty stack. */
stack_type
create_stack(void)
{
  stack_type result;

  result = malloc(sizeof(stack_struct_type));
  result->count = 0;
  return(result);
}

/* Empty_stack is a predicate indicating whether the given stack is empty. */
BOOL
empty_stack(stack_type stack)
{
  return(stack->count == 0);
}

/* Full_stack is a predicate indicating whether the given stack is full. */
BOOL
full_stack(stack_type stack)
{
  return(stack->count == MAX_STACK_SIZE);
}

/* Push adds a new item to the top of the given stack.  The
   User is responsible for ensuring that there is room in the
   stack for the new item.  */
void
push(stack_item_type item, stack_type stack)
{
  assert(stack->count < MAX_STACK_SIZE);
  stack->items[stack->count] = item;
  stack->count++;
}

/* Pop returns the item at the top of the given stack.  As a
   side-effect, the item is removed from the stack.  The user
   is responsible for ensuring that the stack contains at least
   one item. */
stack_item_type
pop(stack_type stack)
{
  assert(stack->count > 0);
  return(stack->items[--(stack->count)]);
}
