jueves, 18 de noviembre de 2010

*Lenguaje Ada

Materia: Lenguajes de Programación - PUNTOS EXTRA
Hora: Martes m1 - m3

 
Hola a todos en está entrada les hablaré un poco acerca del Lenguaje Ada.

 
El lenguaje Ada es un Lenguaje que fué diseñado por el Departamento de Defensa de los Estados Unidos (DoD) en mayo de 1979, con un solo proposito: calidad del producto, es decir, la confianza que los usuarios van a poder depositar en el programa.

 
Es posible escribir cualquier programa en Ada, pero ha sido utilizado principalmente para desarrollar software de control, de tiempo real y de misión crítica. Ada es un lenguaje de programación imperativo (tradicional), orientado a objetos, concurrente y distribuido.

 
Su nombre se eligió en conmemoración a Lady Ada Augusta Byron, Condesa de Lovelace, hija de Lord Byron, considerado como el primer programador de la historia.

 
* Sus características principales son:

 
- Legibilidad

 
Su sintaxis fué inspirada en Pascal, es bastante legible, incluso para personas que no conozcan el lenguaje.
Debido a su uso para crear programas profesionales, los culales se leen muchas más veces de las que se escriben, la legibilidadd es mucho más importante que la rápidez de escritura. Además, Ada es un lenguage "case insensitive", es decir, sus identificadores y palabras claves son equivalentes sin importar el uso de mayúsculas y minúsculas.

 
- Tipado Fuerte

 
Asigna en cada objeto un conjunto de valores claramente definido, impidiendo la confusión entre conceptos lógicamente distintos. Esto hace que el compilador detecte más errores que en otros lenguajes.

 
- Construcción de grandes programas

 
Para crear programas mantenibles y transportables, de cualquier tamaño, se necesitan mecanismos de encapsulado para compilar por separado y para gestionar bibilotecas.

 
- Manejo de excepciones

 
Es necesario proporcionar medios para que, en un programa construido en capas y por partes, se limita las consecuencias de los errores presentados en cualquiera de sus partes ya que los programas no suelen ser totalmente correctos.

 
- Abstracción de datos

 
Se separan los detalles de la representación de los datos y las especificaciones de las operaciones lógicas sobre ellos para obtener mayor transportabilidad y mejor mantenimiento.

 
- Procesamiento paralelo

 
Se evita tener que añadir estos mecanismos por medio de llamadas al sistema operativo, consiguiendo mayor fiabilidad y transportabilidad.

 
- Unidades genéricas

 
Debido a que en muchos casos, parte de un programa es independiente del tipo de valores a manipular.
Para ello necesitamos un mecanismo que permita crear partes de un programa similares, a partir de una plantilla, es muy útil para crear bibliotecas.

 
La estructura básica de un programa en Ada es:

 

 
[Clausulas_de_Contexto]
procedure Identificador is
[Declaraciones]
begin
Sentencias_del_Programa
end Identificador;
Y un ejemplo común de la sintaxis de un lenguaje es el programa "Hola mundo":

 
with Ada.Text_IO;
procedure Hola_Mundo is
begin
Ada.Text_IO.Put_Line("¡Hola, mundo!");
end Hola_Mundo;

 
La cláusula with establece una dependencia con el paquete Ada.Text_IO y hace disponible toda la funcionalidad relacionada con la Entrada/Salida de textos. Después se define un procedimiento como programa principal. En Ada no tiene que tener un nombre especial, sino estar fuera de cualquier paquete. Al compilar se indica el programa principal.

 
* Sintaxis en Ada

 
- El alfabeto de Ada está compuesto por:
  • Letras mayúsculas: A, ..., Z y minúsculas: a, ..., z.
  • Dígitos: 0, ..., 9.

 
-Caracteres especiales.

 
En Ada 95 se admiten caracteres como 'Ñ', 'Ç' y vocales acentuadas, porque se permiten los 256 caracteres comprendidos en ISO Latin-1.

 
El alfabeto de minúsculas puede usarse en vez de o junto con el alfabeto de mayúsculas, pero se considera que los dos son idénticos (con la excepción de cadenas de caracteres y literales tipo carácter).

 

 

 
Las palabras reservadas de Ada son equivalentes tanto en mayúsculas como en minúsculas y son:

 
abort, abs, abstract, accept, access, aliased, all, and, array, at, begin, body, case, constant, declare, delay, delta, digits, do, else, elsif, end, entry, exception, exit, for, function, generic, goto, if, in, is, limited, loop, mod, new, not, null, of, or, others, out, package, pragma, private, procedure, protected, raise, range, record, rem, renames, requeue, return, reverse, select, separate, subtype, tagged, task, terminate, then, type, until, use, when, while, with y  xor.

 

 
Los Tipos de Datos en Ada se clasifican de la siguiente manera:

 

 
               Jerarquía de Tipos en Ada

 

 

 
- Los atributos son operaciones predefinidas que se pueden aplicar a tipos, objetos y otras entidades. Por ejemplo estos son algunos atributos aplicables a Tipos:

 

 
  • Last: Integer'Last es el máximo valor que puede tomar la variable de tipo Integer. También es el último valor de un tipo enumerado o del índice de un vector.

 
  • First: Integer'First es el mínimo valor que puede tomar la variable de tipo Integer. También es el primer valor de un tipo enumerado o del índice de un vector.

 
  • Range: Vector'Range indica el rango que ocupa la variable Vector, es decir, equivale a Vector'First..Vector'Last. En el caso de más de una dimensión, el valor Matriz'Range(1) indica el rango de la primera dimensión.
  • Succ: TColor'Succ(ROJO) indica el siguiente valor a ROJO que toma el tipo TColor, si no existe, se eleva la excepción Constraint_Error.

 
  • Pred: TDía'Pred(VIERNES) indica el anterior valor a VIERNES que toma el tipo TDía, si no existe, se eleva la excepción Constraint_Error.

 
  • Pos: El atributo Pos indica la posición ocupada por un determinado valor en un tipo enumeración. Por ejemplo: TColor'Pos(ROJO). La primera posición se considera 0.

 
  • Val: El atributo Val indica el valor que ocupa una determinada posición en un tipo enumeración. Por ejemplo: COLOR'Val(1).

 
  • Para identificar unívocamente un valor de un tipo enumeración se emplea TColor' (ROJO) y TIndicador'(ROJO) para distinguir el valor ROJO del tipo TColor o TIndicador.
- Algunos atributos aplicables a Objetos

 

 
  • Size: tamaño en bits de un objeto.

 
  • Valid: si tiene una representación válida para su tipo. Útil cuando se obtienen valores desde el «mundo exterior» mediante Unchecked_Conversion u otro mecanismo.

 
  • First, Last: aplicados a arrays dan el primer y el último índices del array.

 
  • Range: Vector'Range indica el rango que ocupa la variable Vector, es decir, equivale a Vector'First..Vector'Last. En el caso de más de una dimensión, el valor Matriz'Range(1) indica el rango de la primera dimensión
* Variables

 

 
- Una variable se introduce en el programa mediante una declaración, que se podría denotar así:

 
declaración_variable ::= identificador { , identificador } : tipo [ := expresión ] ;

 
Por ejemplo: V: Boolean := TRUE;

 
* Constantes

 
- Una constante es un objeto que se inicializa a un valor cuando se declara y posteriormente no puede cambiar, se declara igual que una variable, pero añadiendo la palabra reservada constant.

 
Ejemplo: PI: constant Float := 3.14159_26536;

 
Un tipo especial de constante es el número nombrado para el cual no es necesario especificar un tipo y que es equivalente a usar el literal correspondiente

 
* Sentencia IF

 
sentencia_selección ::=

 
if condición then secuencia_de_sentencias
[ { elsif condición then secuencia_de_sentencias } ]
[ else secuencia_de_sentencias ]
end if ;

 
                                                          flujo

 

 
* Sentencia Case

sentencia_selección_por_casos ::=

case expresión is
alternativa_caso { alternativa_caso }
end case ;
alternativa_caso ::=
when elección {
elección } => secuencia_de_sentencias
elección ::= expresión_simple
rango_discreto
others

                                                  flujo
 
* Sentencia Bucle

-LOOP 

sentencia_bucle_simple ::=

[ identificador_bucle : ] loop
secuencia_de_sentencias
end loop [ identificador_bucle ] ;

 

 
-FOR

sentencia_bucle_iterativo ::=

[ identificador_bucle : ] for parámetros_for loop
secuencia_de_sentencias
end loop [ identificador_bucle ] ;
parámetros_for ::= identificador in [ reverse ] rango_discreto

 
-WHILE

sentencia_bucle_iterativo ::=

[ identificador_bucle : ] while condición loop
secuencia_de_sentencias
end loop [ identificador_bucle ] ;

 
* Sentencia exit


 
Termina el bucle nombrado en la sentencia o, si no aparece, el bucle más próximo que la contiene. Su notación sintáctica es:

sentencia_exit ::= exit [ nombre_bucle ] [ when condición ] ;

 
* Sentencia return

 
Termina la ejecución del subprograma más próximo que la contiene, tanto en procedimientos como en funciones donde, además, se utiliza para devolver el resultado de dicha función. Su notación sintáctica es:

sentencia_return ::= return [ expresión ] ;

* Sentencia abort

 
Se utiliza sólo para tareas. Implica la terminación incondicional de las tareas que se especifiquen. Su notación sintáctica es: sentencia_abort ::= abort nombre_tarea { , nombre_tarea } ;

 
En el Lenguaje Ada los subprogramas se dividen en dos categorías:

- Procedimientos: son llamados como sentencias y no devuelven resultado.

- Funciones: son llamadas como componentes de expresiones y devuelven un resultado


 
Ahora hablaremos un poco más a fondo sobre ellos:

* Procedimientos

 
La llamada a un Procedimiento en Ada constituye por sí misma una sentencia. Su especificación se puede describir de la siguiente manera:

especificación_procedimiento ::=
procedure identificador
[ ( especificación_parámetro { ; especificación_parámetro } ) ]
especificación_parámetro ::= identificador { , identificador } : [ modo ] tipo
[ := expresión ]
modo ::= in
out
in out

 
Y el cuerpo del procedimiento sería:

cuerpo_procedimiento ::=
especificación_procedimiento is
[ parte_declarativa ]
begin
secuencia_de_sentencias
[ exception
manejador_de_excepción { manejador_de_excepción } ]
end [ identificador ]

 
- Los parámetros que se le pueden pasar a un procedimiento pueden ser de tres modos diferentes:

  • in: el parámetro formal es una constante y permite sólo la lectura del valor del parámetro real asociado.
  • in out: el parámetro formal es una variable y permite la lectura y modificación del valor del parámetro real asociado.
  • out: el parámetro formal es una variable y permite únicamente la modificación del valor del parámetro real asociado.
* Funciones

 
Una función es una forma de subprograma a la que se puede invocar como parte de una expresión. Su especificación se puede describir de la siguiente manera:

especificación_función ::=
function ( identificador
símbolo_operador )
[ ( especificación_parámetro { ; especificación parámetro } ) ]
return tipo
especificación_parámetro ::= identificador { , identificador } : [ in ] tipo
[ := expresión ]

 
La especificación de la función es necesaria para mostrar al exterior toda la información necesaria para poder invocarla. El cuerpo de la función sería:

cuerpo_función ::=
especificación_función is
[ parte_declarativa ]
begin
secuencia_de_sentencias
[ exception
manejador_de_excepción { manejador_de_excepción } ]
end [ identificador
símbolo_operador ] ;

 
Los parámetros formales de una función se comportan como constantes locales cuyos valores son proporcionados por los parámetros reales correspondientes.

 
La sentencia return se utiliza para indicar el valor devuelto por la llamada a la función y para devolver el control a la expresión que llamó a la función, el cuerpo de la función puede contener varias sentencias return y la ejecución de cualquiera de ellas terminará la función devolviendo el control a la sentencia que la había invocado.

Toda llamada a una función produce una nueva copia de cualquier objeto declarado dentro de ella, incluyendo los parámetros. Cuando la función finaliza, desaparecen sus objetos. Por lo tanto, es posible utilizar llamadas recursivas a una misma función.

 
Un parámetro formal de una función puede ser de cualquier tipo, incluyendo vectores o registros, pero debe declararse antes.

* Parámetros nombrados

 
Se puede alterar el orden de los parámetros en la llamada utilizando la notación nombrada, es decir, se especifica en la llamada el nombre del parámetro real seguido del símbolo => y después el parámetro formal.

 
* Parámetros por defecto

 
Se pueden establecer parámetros formales, tanto en procedimientos como en funciones, que tengan valores por defecto y, por tanto, se pueden observar en la llamada al subprograma.

Por ejemplo: procedure Prueba_Por_Defecto (A : in Integer := 0; B: in Integer := 0);

 
Se puede llamar de estas formas:

1- Prueba_Por_Defecto (5, 7); -- A = 5, B = 7
2- Prueba_Por_Defecto (5); -- A = 5, B = 0
3- Prueba_Por_Defecto; -- A = 0, B = 0
4- Prueba_Por_Defecto (B => 3); -- A = 0, B = 3
5- Prueba_Por_Defecto (1, B => 2); -- A = 1, B = 2

 
En la primera se utiliza una llamada "normal", la que es con notación posicional, en la segunda, se utiliza posicional y por defecto, la tercera utiliza todos los parámetros por defecto, en la cuarta nombrada y por defecto, y, por último, la quinta utiliza notación posicional y nombrada.

En el Lenguaje Ada se puede utilizar un identificador con más de un significado, y a esto es lo que se conoce como sobrecarga.


 
- Sobrecarga de literales de enumeración

  
Se pueden emplear identificadores iguales en distintos tipos enumeración.

 
- Sobrecarga de operadores


 
Se puede utilizar una función para definir una operación y sobrecargar cualquiera de los operadores ya establecidos excepto /= (que toma su valor a partir del operador =, pero que puede redefinirse si el valor de retorno no es de tipo Boolean).

 
Las reglas a cumplir a la hora de sobrecargar un operador son:

 
  • No cambiar la sintaxis.
  • No cambiar el número de parámetros de un operador (recuérdese que + y - pueden ser unarios o binarios).
  • La precedencia se mantiene.
 Una recomendación muy importante es no definir un operador para un nuevo tipo dándole un significado distinto al del operador predefinido, por ejemplo el símbolo de  + siempre va a representar conceptos relacionados con la adición; *, multiplicación; and, conjunción, etc.

 
- Sobrecarga de subprogramas

 
 Un subprograma sobrecargará un significado ya existente siempre que su especificación sea diferente, es decir, pueden existir dos subprogramas con el mismo identificador siempre que se distingan por el número o tipo de sus parámetros

Ada tiene cinco bibliotecas predefinidas independientes para operaciones de entrada/salida. Y son:

- Direct I/O: se usa para acceso directo a archivos que contienen unicamente elementos del mismo tipo.

- Sequential I/O: se usa para el acceso secuencial a archivos que unicamente contienen elementos de un tipo especificado.


- Storage I/O: nos permite almacenar un único elemento en un buffer de memoria.
- Stream I/O:  es el paquete de entrada/salida más flexible. Todos los atributos de E/S pueden sobreescribirse con subprogramas definidos por el usuario y es posible definir nuestros propios tipos de Stream I/O usando técnicas avanzadas de orientación a objetos.


- Text I/O:  es el tipo de entrada/salida más usada, en ella todos los datos del archivo se representan en formato de texto legible. 

* Biblioteca predefinida


Existen varios paquetes predefinidos para la entrada/salida en Ada:

- Paquete Ada.Direct_IO
- Paquete Ada.Sequential_IO
- Paquete Ada.Storage_IO
- Paquete Ada.Streams
                    - Paquete Ada.Streams.Stream_IO
- Paquete Ada.Text_IO, con sus paquetes genéricos anidados: Complex_IO, Decimal_IO, Enumeration_IO, Fixed_IO, Float_IO, Integer_IO y Modular_IO.
                     -Paquete Ada.Text_IO.Editing
- Paquete Ada.Float_Text_IO
- Paquete Ada.Integer_Text_IO













Bueno esto es todo sobre mi entrada acerda del Lenguaje Ada, espero les sea útil.

Saludos :)  

 

 

 

1 comentario:

  1. Muy bien, cinco puntos extra. Se me hace raro que no estés publicando para el laboratorio; ahí te hace más falta.

    ResponderEliminar