// file:    Stack.java
// author:  Robert Keller 
// purpose: Illustrating one way to construct a stack
//          The stack automatically adjusts its storage requirement.

import java.io.*;

// Stack in this case means a stack of int's
// The number of items stored is bounded only by the amount of memory

class Stack
{
int number;                     // number of items in the stack
int limit;                      // limit on number of items in the stack
int increment;                  // incremental number to be added
int array[];                    // stack contents
static int default_limit = 10;  // default limit

// Stack constructor

Stack(int limit)
  {
  this.limit = limit;           // set instance variable to argument value
  increment = limit;            // use limit for increment
  array = new int[limit];       // create array
  number = 0;                   // stack contains no items initially
  }


// Constructor with limit unspecified, uses default

Stack()
  {
  this(default_limit);
  }


// Put an item onto the stack

void push(int x)
  {
  ensure();
  array[number++] = x;          // put element at position number and increment
  }


// Remove the top item from the stack and return it

int pop()
  {
  return array[--number];       // decrement number and take element
  }


// Test whether the stack is empty

boolean empty()
  {
  return number == 0;           // see if number is 0
  }


// ensure() ensures that there is enough space for a push()

void ensure()
  {
  if( number >= limit )				// full?
    {
    int newArray[] = new int[limit+increment];  // create new array
    for( int i = 0; i < limit; i++ )
      {
      newArray[i] = array[i];                   // copy elements in stack
      }
    array = newArray;                           // replace array with new one
    limit += increment;                         // augment the limit
    }  
  }


// Test program, enter limit > 0 and cycles on command line

public static void main(String arg[])
  {
  // take arguments from command line (2 required)

  if( arg.length < 2 )
    {
    System.err.println("Two arguments are required, limit and cycles");
    System.exit(1);
    }
  int limit = new Integer(arg[0]).intValue();
  int cycles = new Integer(arg[1]).intValue();

  if( limit < 1 )
    {
    System.err.println("limit must be at least 1");
    System.exit(1);
    }

  Stack s = new Stack(limit);
  for( int i = 0; i < cycles; i++ )
    {
    s.push(i);
    }
  while( !s.empty() )
    {
    System.out.println(s.pop());
    }
  }
}

