1.2. Packages - JulTob/Ada GitHub Wiki

Packages

Large Ada programs are divided up into packages. These are collections of procedures, functions, variables and other declarations that serve a similar purpose. You can have packages to draw text on the screen, or packages to do accounts payable, or package to work with complex numbers.

Most Ada code is in packages.

A package is a compilation unit.

Ada focuses on scalability. As such, is very focused on libraries. So much so, that every subprogram is itself a library unit. These units call services from other libraries.

To make it easier for different people to work on different packages, and to make packages self-documenting, Ada packages are divided into two parts. The package specification (or package spec) contains everything that other programs need to use your package. It contains all variables they can access, all the subprograms they can call, etc. For subprograms, you only use the subprogram header, the procedure or function line, to let the programmers know the name of the subprogram and what the parameters are.

Print_Root.adb

with Sqrt, Simple_IO;    --Call to libraries

procedure Print_Root is
  use Simple_IO;
  X: float;
begin 
   get(x);
   put(sqrt(x));
end print_root;

Declarations introduce the subject entities. Statements compose the algorithmic action.

Declaration

All variables have to be declared before use. To declare a variable is to set a name (or identificator) for it and a type as follows:

Variable: Type;  --In the declarative part (before begin)
----------------------------------------------------------
Variable : constant Type;  --For constant parameters

A variable can only have values from its type’s set.

The declaration determines the scope.

We also declared the use of a library so we can use implicit scoping inside the function. Without it we should apply explicit scoping, as follows:

Simple_IO.Get(x);
Simple_IO.Put(sqrt(x));

Get allows us to read input from the console, and Out to write in the console.

Another program Example:

with Sqrt, Simple_IO;    --Call to libraries

procedure Print_Root is
  use Simple_IO;
  X: float;
begin 
   Put(“Roots of Input number”);
   New_Line(2);
   loop 
      Get(X);
      exit when X = 0.0;
      Put(“ Root of ); Put(X); Put(“ is “);
      if X < 0.0 then
         Put(“not calculable”);
      else
         Put(Sqrt(X));
      end if;
      New_Line;
   end loop 
   New_Line;
   Put(“Program finished”);
   New_Line;
end Print_Root;

Package Specifications

La especificación o declaración de un paquete ofrece una interfaz y, de forma opcional, permite definir algunos elementos privados, lo que facilita la "extensión de paquetes", mecanismo que permite construir paquetes derivados (child packages) a partir de otros preexistentes (parent packages). Los elementos privados de un paquete son visibles a los que derivan de él, pero no a otras unidades.

La especificación o declaración de un paquete ofrece una interfaz y, de forma opcional, permite definir algunos elementos privados, lo que facilita la "extensión de paquetes", mecanismo que permite construir paquetes derivados (child packages) a partir de otros preexistentes (parent packages). Los elementos privados de un paquete son visibles a los que derivan de él, pero no a otras unidades.

package_name.ads

package Package_Name is
  -- Public declarations
private
  -- Private declarations

end Package_Name;
package Pila_De_Enteros is

   type Pila is limited private;
   procedure Apilar (P : in out Pila;E: in Integer);
   procedure Desapilar (P : in out Pila);
   function Cima (P : Pila) return Integer;
   function Es_Vacía (P : Pila) return Boolean;
private
   type Nodo is record
      Info: Integer;
      Sig : Pila;
   end record;

   type Pila is access Nodo;

end Pila_De_Enteros;

Package Body

La especificación de un paquete requiere una implementación (body) si contiene declaraciones que requieran completarse (por ejemplo, la declaración de una función requiere su desarrollo).

Everything in this package is private.
Contains the implementation.

package_name.adb

package body Package_Name is
  -- Implementation
end Package_Name;
with Unchecked_Deallocation;

package body Pila_De_Enteros is
   procedure Libera is new Unchecked_Deallocation (Nodo, Pila);

   procedure Apilar (P : in out Pila;E: in Integer) is
   begin
      P := new Nodo'(E,P);
   end Apilar;

   procedure Desapilar (P : in out Pila) is
      Aux: Pila := P;
   begin
      P := P.Sig;
      Libera (Aux);
   end Desapilar;

   function Cima (P : Pila) return Integer is
   begin
      return P.Info;
   end Cima;

   function Es_Vacía (P : Pila) return Boolean is
   begin
      return P = null;
   end Es_Vacía;
end Pila_De_Enteros;

Paquetes

Los paquetes son unidades que agrupan entidades relacionadas, por ejemplo, la declaración de un tipo y sus operaciones primitivas, facilitando su interfaz y ocultando los detalles de su implementación. Un paquete es un mecanismo de encapsulamiento y ocultación de información especialmente útil para definir tipos abstractos de datos. Normalmente un paquete se divide en dos partes: la especificación (package specification) y el cuerpo (package body). La palabra reservada package se utiliza para definir ambas partes. Es posible declarar paquetes genéricos???, dotados de parámetros que permiten reutilizarlo en diferentes situaciones. Una vez compiladas la especificación y la implementación de un paquete, se puede hacer uso del mismo en otras unidades simplemente incluyendo el nombre del paquete en sus cláusulas de contexto, como se ve en el ejemplo.

with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Pila_De_Enteros;     use Pila_De_Enteros;



procedure Prueba is
   P: Pila;
begin
   for I in 1..5 loop  
      Apilar(P,I);
   end loop;
	  
   while not Es_Vacía(P) loop
      Put(Cima(P));
      New_Line;
      Desapilar(P);  
   end loop;
end Prueba;