ADT Stack

unit Stack;

interface

   type
      ElementType = integer;

      StackType = ^StackRecord;

      StackRecord = record
                       Data : ElementType;
                       Next : StackType;
                    end;

   var
      (* Assigned TRUE if an error occurs during Push or Pop *)
      StackError: boolean;

   procedure Create (var S : StackType);
  (*
   * post: S is initialized and empty
   *)

   procedure Destroy (var S : StackType);
  (*
   * post: Memory allocated for S is released
   *)

   function Empty (var S : StackType) : boolean;
  (*
   * post: Returns TRUE if S is empty, FALSE otherwise
   *)

   procedure Push (var S    : StackType;
                       Item : ElementType);
  (*
   * post: Item is added to the top of S
   *)

   procedure Pop (var S    : StackType;
                  var Item : ElementType);
  (*
   * pre:  not Empty (S)
   * post: S has its top element removed;
   *       Item holds that element
   *)


implementation
   procedure NewNode (var Node : StackType;
                          Item : ElementType;
                          Link : StackType);
   begin
       new (Node);
       Node^.Data := Item;
       Node^.Next := Link;
   end; (* NewNode *)

   procedure InsertFront (var Head : StackType;
                              Item : ElementType);
   begin
       NewNode (Head, Item, Head);
   end; (* InsertFront *)

   procedure DeleteFront (var Head : StackType);

   var   Temp : StackType;
   begin
       Temp := Head;
       Head := Head^.Next;
       dispose (Temp);
   end; (* DeleteFront *)

   procedure Create (var S : StackType);
   begin
       S := nil;
       StackError := FALSE;
   end; (* Create *)

   procedure Destroy (var S : StackType);
   begin
       while not Empty(S) do 
       begin
           DeleteFront (S);
       end; (* while *)
   end; (* Destroy *)

   function Empty (var S : StackType) : boolean;
   begin
       Empty := (S = nil);
   end; (* Empty *)

   procedure Push (var S    : StackType;
                       Item : ElementType);
   begin
       InsertFront (S, Item);
       StackError := FALSE;
   end; (* Push *)

   procedure Pop (var S    : StackType;
                  var Item : ElementType);
   begin
       StackError := Empty (S);
       if not StackError then 
       begin
           Item := S^.Data;
           DeleteFront (S);
       end; (* if *)
   end; (* Pop *)

end. (* unit Stack *)