Monday, August 13, 2012

AdaTutor - Simple Declarations and Simple Attributes

Variables and Constants

procedure Declarations_Demo is
   I, J, K : Integer;
   L, M    : Integer := 30;
   F, G    : Float;
   Factor  : constant := 1000;
   J := L + 10;          -- Simple assignment statements.
   F := 0.0;
   G := F + L;           -- ILLEGAL.  Can't accidentally mix types.
   G := F + Float(L);    -- Legal.  May deliberately convert types.
   K := Integer(F) + L;  -- Legal.
   Factor := 1000;       -- ILLEGAL.  Factor is a constant.
end Declarations_Demo;

This program doesn't do anything except demonstrate Ada declarations.  The statement I, J, K : Integer; brings three integer variables into existence.  The next statement creates two more integer variables and initializes both of them to 30.  Every time this procedure is called, L and M are brought into existence and initialized to 30.  This is different from a Fortran DATA statement, which initializes only once at compile time.

The statement F, G : Float; creates two variables of type Float.  The next statement names a constant.  Writing Factor is thereafter equivalent to writing 1000.  Unlike variables, constants must be initialized.

The first two executable statements are simple assignment statements.  The symbol := is read "becomes" or "gets."  It may not contain a space.  In the third executable statement, the compiler will reject the expression F + L because Ada won't let us accidentally mix different types (Float and Integer).

However, Ada lets us deliberately mix types.  The statement G := F + Float(L); is legal because it converts L from Integer to Float, adds it to F which is of type Float, and stores the result in G, also of type Float.  Likewise, the next statement is legal because it converts F to Integer, adds the Integer L, and stores the result in the Integer K. But note that when a Float is converted to Integer, it's rounded, not truncated.  (Later we'll learn how to truncate to integers.)  The last executable statement is illegal because a constant can't appear on the left side of an assignment statement.


with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Try_Me is
   N : Integer := 1;
   N := 2;
end Try_Me;
What number will be displayed the second time procedure Try_Me is called?
  1. The program will display 1.
  2. The program will display 2.

Enumeration Types

In Ada we can declare enumeration types, where we enumerate every possible value for a type. For example, if we declare

   type Rainbow_Color is (Red, Orange, Yellow, Green, Blue, Indigo,
   Rc : Rainbow_Color;
then Rc can have any of 7 values.  In the executable region we might write Rc := Red; and we could also test: if Rc = Red then ... end if;.  The enumerated values, enclosed in parentheses and separated by commas, must follow the rules for Ada identifiers, or they can be single characters enclosed in ' marks (called "tic" marks), thus:
      type Even_Digit is ('0', '2', '4', '6', '8');
It's illegal to write type Processor is (80486, Z80, 1750A); because two of the values aren't legal Ada identifiers.  However, it's OK to mix characters and identifiers in the same declaration, thus:
      type Mixed is (Big, Small, 'X', '9');
With the following declarations:
   type Rainbow_Color is (Red, Orange, Yellow, Green, Blue, Indigo,
   type Traffic_Light_Color is (Red, Amber, Green);
   Rc : Rainbow_Color;
   Tc : Traffic_Light_Color;
Rc could have any of 7 values, and Tc could have any of 3 values.  The compiler will have no trouble compiling
      Rc := Red;
      Tc := Red;

Because it knows that in Rc := Red;, Red must be the Rainbow_Color if it's stored into Rc, and in Tc := Red;, Red must be the Traffic_Light_Color if it's stored into Tc.  The compiler knows that the types across := must always match.  Naturally, it's illegal to write Rc := 2;, because of the mixed types.

Also, if we have a procedure Display that takes one parameter of type Rainbow_Color, the compiler could handle Display(Red); because it knows that Red must be the Rainbow_Color to fit the procedure.

But if we had a procedure Display that takes a Rainbow_Color and a Display that takes a Traffic_Light_Color, the statement Display(Red); would be ambiguous; the compiler wouldn't know which Display to call.  In that case we could specify the type by qualifying the name Red, writing Rainbow_Color'(Red).  Note the ' with the parentheses.  The call would be Display(Rainbow_Color'(Red));.  The statements Display(Violet); and Display(Amber); aren't ambiguous; the compiler will figure out which Display to call in these cases.

Declaring an enumeration type not only defines equality for objects of that type, but also an order for the values.  Thus we can check for <, >, <=, etc. For example, if we declare A, B: Rainbow_Color; and later write, in the executable region, A := Yellow; and B := Blue; then the test A < B will turn out to be True.  Yellow is considered less than Blue.

We can input and output enumeration types by instantiating the generic package Ada.Text_IO.Enumeration_IO. For example:

with Ada.Text_IO; use Ada.Text_IO; ...
package My_Rainbow_IO is new Enumeration_IO(Rainbow_Color);
use My_Rainbow_IO;

Here are two enumeration types built into Ada:

 type Boolean is (False, True);

 type Character is ((nul), (soh), (stx), ... , ' ', '!', '"', ... ,
                    '0', '1', '2', ... , 'A', 'B', 'C', ... );
Since the above two declarations are built into the Ada language, they shouldn't be repeated in your programs.  Note that type Boolean is just an enumeration type.  The relational operators =, >, <=, etc. all return results of type Boolean.

The definition of type Character can't be completely written out, because some characters are unprintable . Here we've denoted such characters with names in parentheses, and also used "..." for brevity.  However, the type Character contains all 256 possible 8-bit values.  (In Ada 83, it contains only the first 128 values, corresponding to the ASCII characters.)  Ada 95 also provides a type Wide_Character, containing all 65,536 16-bit values, and a package Ada.Wide_Text_IO.


  1. type Count is ("1", "2", "3", "Ab", "Cd", "Ef");
  2. type Count is ('1', '2', '3', 'Ab', 'Cd', 'Ef');
  3. type Count is (1, 2, 3, 'Ab', 'Cd', 'Ef');
  4. type Count is ('1', '2', '3', Ab, Cd, Ef);
Which one of the above type declarations is legal?

< prev   next >

No comments: