[ Table of Contents ]
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. |
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. ------------------------------------------------------------------ generic 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); private 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 begin if Stack.Index = Size then raise Stack_Full; -- raise exception end if; Stack.Index := Stack.Index + 1; Stack.Space(Stack.Index) := Item; exception 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 begin if Stack.Index = 0 then raise Stack_Empty; -- raise exception end if; Item := Stack.Space(Stack.Index); Stack.Index := Stack.Index - 1; exception 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; begin Put_Line("Testing Robust stack"); New_Line; 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"); New_Line; for I in 1..5 loop SS4.Pop(S4, Str4); Put_Line(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. Dave Carl Bill Adam Stack is empty. Can't Pop. Adam |
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
[ Back to top of page ]