3.9 The raise Statement

[ Table of Contents ] Prev ] Chapter Overview ] Next ] [ Glossary/Index ]

The previous section suggests that for a proper understanding of exceptions, one has to learn how to declare, raise  and handle them. This section contains an example package that declares two user-defined exceptions, includes raise statements in the normal executable parts of two nested procedures that raise the exceptions, and also includes appropriate exception handlers in those same procedures. A raise statement is a simple statement.

General Form

raise Exception_Name;

Robust Generic Stack Example

In this example we improve upon the generic stack package of the previous chapter. We make the generic stack more robust by declaring, raising and handling exceptions called Stack_Full and Stack_Empty. Thus, if the client tries to Push onto a full stack or Pop from an empty one, the program takes an alternate path and displays an appropriate message, rather than allowing the  program to crash (because Stack.Index would go out of range).

The right side of this diagram depicts a generic ADT package called Robust_Stack, whose body contains the declaration of two exceptions called Stack_Full and Stack_Empty. The test procedure on the left declares a subtype of String, a generic instance of Robust_Stack called SS4, and a stack object called S4.

Im3-10.gif (7039 bytes)

Note the five-sided graphic symbol used to represent the declaration of one or more exceptions.

Source Code Listing

------------------------- Robust_Stack ---------------------------
--  This generic package provides a template that can be the basis 
--  for stacks with different sizes and which store items of 
--  different types. It is also robust, in that it handles 
--  exceptions raised when the client tries to Push onto a full  
--  stack or Pop from an empty one. 
  Size : Positive;  
  type Item_Type is private;
package Robust_Stack is
  type Stack_Type is private;
  procedure Push(Stack : in out Stack_Type;
                 Item  : in Item_Type);
  procedure Pop (Stack : in out Stack_Type;
                 Item  : out Item_Type);
  type Space_Type is array (1..Size) of Item_Type;
  type Stack_Type is record
    Index : Integer range 0..Size := 0;
    Space : Space_Type;
  end record;
end Robust_Stack;
with Ada.Text_IO;
use  Ada.Text_IO;
package body Robust_Stack is

  Stack_Full, Stack_Empty : exception;       -- declare exceptions
  procedure Push(Stack : in out Stack_Type;
                 Item  : in Item_Type) is
    if Stack.Index = Size then
      raise Stack_Full;                      -- raise exception 
    end if;
    Stack.Index := Stack.Index + 1;
    Stack.Space(Stack.Index) := Item;
    when Stack_Full =>                       -- handle exception
      Put_Line("Stack is full. Can't Push.");  
  end Push;                   
  procedure Pop (Stack : in out Stack_Type;
                 Item  : out Item_Type) is
    if Stack.Index = 0 then
      raise Stack_Empty;                     -- raise exception
    end if;
    Item := Stack.Space(Stack.Index);
    Stack.Index := Stack.Index - 1;
    when Stack_Empty =>                      -- handle exception
      Put_Line("Stack is empty. Can't Pop.");    
  end Pop;                   
end Robust_Stack;
----------------------- Test_Robust_Stack ------------------------
--  This test procedure tries one too many Pushes, which raises 
--  the Stack_Full exception, then tries one too many Pops which 
--  raises the Stack_Empty exception. 
with Ada.Text_IO;
use  Ada.Text_IO;
with Robust_Stack;
procedure Test_Robust_Stack is          
  subtype String_4 is String(1..4);
  Str4 : String_4;
  package SS4 is new Robust_Stack
          (Size => 4, Item_Type => String_4);
  S4 : SS4.Stack_Type;
    Put_Line("Testing Robust stack");
    Put_Line("Pushing Adam"); SS4.Push(S4,"Adam"); 
    Put_Line("Pushing Bill"); SS4.Push(S4,"Bill"); 
    Put_Line("Pushing Carl"); SS4.Push(S4,"Carl"); 
    Put_Line("Pushing Dave"); SS4.Push(S4,"Dave"); 
    Put_Line("Pushing Eric"); SS4.Push(S4,"Eric");
    for I in 1..5 loop
      SS4.Pop(S4, Str4);
    end loop;
end Test_Robust_Stack;

The above program produces the following output:

     Testing robust stack

     Pushing Adam
     Pushing Bill
     Pushing Carl
     Pushing Dave
     Pushing Eric
     Stack is full. Can't Push.

     Stack is empty. Can't Pop.

Note that we did not use blocks to enclose the exception handlers in this case, because we are happy to have control passed back to the test procedure following the occurrence of an exception.

Related Topics

2.11 Generic Units 3.8 Exception Handling
A.2 Simple and Compound Statements

[ Back to top of pagePrev ] Next ]