program SeqStack;

const
  max = 10;             {Maximum size of Stack}

type
  itemtype = integer;   {Contents of Stack-the items}

  stack = record        {Stack Structure}
    items: array [1..max] of itemtype;   {the data items themselves}
    top: integer;                        {next position available at top}
  end;


{*****************************************
Procedure to Initialise a Stack
Pre: Stack not initialised
Post:Stack initialised with top position
     at 1 ready to accept the first item.
******************************************}
procedure init(var s:stack);
  begin
    s.top:=1;   {set the top available position to 1}
  end;


{*****************************************
Function to return True/False if stack is full
Pre: Stack initialised
Post:Stack unchanged
******************************************}
function isFull(s:stack): boolean;
begin
isFull:=s.top=max+1;    {top available position is out of the array}
end;

{*****************************************
Function to return True/False if stack is empty
Pre: Stack initialised
Post:Stack unchanged
******************************************}
function isEmpty(s:stack): boolean;
begin
isEmpty:=s.top=1;       {if top available position is still at 1}
end;


{*****************************************
Function to return number of items in Stack
Pre: Stack initialised
Post:Stack unchanged
******************************************}
function itemNo(s:stack): integer;
begin
itemNo:=s.top-1;        {equal to one less the top available position}
end;


{*****************************************
Procedure to Insert an item on top of Stack
Pre: Stack initialised and not full
Post:Stack has item inserted on top
******************************************}
procedure push(var s:stack;i:itemtype);
  begin
    if (isFull(s))                              {if stack is full}
     then writeln('Sorry - Stack is Full')      {then}
     else                                       {else}
       begin
         s.items[s.top]:=i;     {place item in top available position}
         s.top:=s.top+1;        {move top available position to the next one up}
       end;
  end;


{*****************************************
Procedure to Remove an item from top of Stack
Pre: Stack initialised and not empty
Post:Stack has item removed from top
******************************************}
procedure pop(var s:stack;var i:itemtype);
  begin
    if (isEmpty(s))                             {if stack is empty}
     then writeln('Sorry - Stack is Empty')     {then}
     else                                       {else}
       begin
         s.top:=s.top-1;        {move top available position to one down}
         i:=s.items[s.top];     {take out the item there - position ready}
       end;                                        {...to be over-written}
  end;


{*****************************************
               MAIN PROGRAM
******************************************}
Var
  TestStack:stack;
  top:itemtype;

BEGIN
  init(TestStack);
  push(TestStack,21);
  push(TestStack,24);
  push(TestStack,28);
  writeln('Number of items in Stack: ',itemNo(TestStack));
  pop(TestStack,top);
  writeln('The item on top of Stack was ',top);
  writeln('Number of items now in Stack: ',itemNo(TestStack));
END.
