Loro - Un Sistema de Programación Didáctico

http://loro.sf.net

 

Especificación del lenguaje

Versión 0.9.2 – noviembre 25 de 2002

Carlos A. Rueda

 

1 Introducción

Loro es un lenguaje de programación de carácter didáctico con revisión estricta de tipos y reciclaje automático de memoria. Su soporte central es el diseño por contrato aplicado a la programación tanto imperativa como orientada a objetos. Este documento ofrece una definición descriptiva del lenguaje. Se asumen conocimientos previos de algún lenguaje de programación como Java o C++. Aunque no se utiliza un estilo estrictamente formal, tampoco se trata de un documento dirigido al lector principiante en programación.

 

Siendo parte integral de un proyecto abierto y en desarrollo, esta especificación no debe tomarse como definitiva. De hecho, el lenguaje está abierto a los ajustes que sean pertinentes para atender, hasta donde sea posible, las diferentes propuestas y revisiones que vayan surgiendo. Para obtener información actualizada al respecto, favor visitar la página del proyecto.

 

El apéndice (7.13) explica la notación utilizada e incluye la gramática concreta del lenguaje.

 

1.1 Aspectos léxicos

En general, el conjunto de caracteres de Loro es el conjunto Unicode. Las letras mayúsculas y minúsculas se toman como distintas en el lenguaje.

 

1.1.1 Espacios en blanco

El espacio simple, tabulador, y el cambio de línea corresponden a los espacios en blanco (espacios, para abreviar) cuya función es la de decidir la separación de los componentes léxicos (1.1.3) del lenguaje. Por lo menos un espacio es necesario para separar dos palabras clave o identificadores adyacentes, o entre una palabra clave o identificador y un número, pero no se requiere entre un número y una palabra clave dado que esto no representa ninguna ambigüedad. Los delimitadores y operadores no requieren espacios para separarlos de sus elementos adyacentes a ambos lados. Excepto en literales cadena, ningún componente léxico contiene espacios en blanco.

 

1.1.2 Comentarios

Un comentario es cualquier texto (secuencia de caracteres) delimitado según dos posibilidades:

Los comentarios pueden aparecer en cualquier punto en donde pueda venir un componente léxico y no requieren espacios en blanco a ningún lado para delimitarse. Estos comentarios son ignorados completamente durante compilación.

 

1.1.3 Componentes léxicos

Los componentes léxicos son las palabras clave, constantes literales, identificadores, operadores y delimitadores.

1.1.3.1 Palabras clave

Las palabras claves del lenguaje se muestran a continuación (nótese que las versiones sin tilde también están reservadas):

 

booleano

cadena

caracter

entero

real

algoritmo

bajando

caso

ciclo

cierto

clase

constante

constructor

continúe

crear

desde

descripción

en (*)

entonces

entrada

es_instancia_de

especificación

éste (*)

estrategia

existe

extiende

falso

fin

global (*)

haga

hasta

implementación

inicio

implementa (*)

interface (*)

mientras

nada

nulo

paquete

para

para_todo

paso

pos

pre

repita

retorne

salida

según

si

si_no

si_no_si

súper (*)

termine

utiliza

como

operación (*)

método (*)

objeto

implementa

lance

intente

atrape

siempre

 

   (*) No usados aún.

 

1.1.3.2 Constantes literales

Las constantes literales pueden ser números enteros, números reales, constantes booleanas, caracteres, cadenas y el literal nulo.

 

·       Un texto de documentación es similar a una cadena literal excepto que se encierra en pares de comillas sencillas (’’). Como su nombre lo indica, estas cadenas son utilizadas para documentar diversos elementos en un programa.

·       Un texto de implementación es similar a una cadena literal excepto que se encierra entre los símbolos {% y %}. Estas cadenas se utilizan para indicar lenguajes diferentes a Loro en la codificación de algoritmos. (8)

 

Secuencias de escape

Las siguientes secuencias de escape permiten indicar caracteres especiales dentro de los literales caracter y cadena:

 

Secuencia

Descripción

\n

cambio de línea

\r

retroceso a inicio de línea

\t

Tabulador

\b

Retroceso

\f

cambio de página

\\

diagonal invertida

\’

comilla sencilla

\”

comilla doble

\ddd

caracter octal (cada d es un dígito octal)

\udddd

caracter Unicode (cada d es un dígito hexadecimal)

 

1.1.3.3 Identificadores

Un identificador es una secuencia de letras y posiblemente dígitos comenzando con una letra, excluyendo las palabras clave (1.1.3.1). Por letra se entiende cualquiera de los caracteres Unicode correspondientes a letra, y también los caracteres $ y _ (“subguión”). No hay una longitud límite preestablecida para los identificadores. Un identificador también puede finalizarse con una o más comillas simples, en cuyo caso se interpreta como una variable semántica (3.2.1).

 

1.1.3.4 Operadores

Los operadores denotados con símbolos (no palabras clave) son los siguientes:

 

:=

?:

<=>

=>

||

&&

|

^

&

=

!=

<

>

<=

>=

<<

>>

>>>

+

-

*

/

%

!

~

#

@

 

 

 

1.1.3.5 Delimitadores

Los siguientes son componentes léxicos (no palabras clave) utilizados como delimitadores.

 

:

;

,

.

(

)

[

]

{

}

->

 

                                                                                                 

2 Fuentes

Un documento fuente (fuente, para abreviar) se refiere al conjunto de elementos (especificaciones, algoritmos, clases) (5) que pueden aparecer dentro de un programa fuente sometido a compilación. En este documento se utiliza el término unidad de compilación para cada uno de tales elementos.[1] Un documento fuente tiene el siguiente esquema:

 

[ paquete ]

( utiliza )*

( especificación | algoritmo | clase )+

 

Las unidades quedarán asociadas al paquete indicado si aparece, o bien al paquete anónimo si no se indica explícitamente un paquete (2.1). La sintaxis para indicar el paquete correspondiente es:

 

paquete id ( :: id )* ;

 

Todas las unidades del mismo paquete tienen accesibilidad inmediata entre sí. Unidades en otros paquetes deben referenciarse incluyendo el nombre de sus paquetes correspondientes. Los elementos utiliza dan una facilidad para abreviar la referencia a unidades ubicadas en otros paquetes. La sintaxis general es:

 

utiliza ( especificación | algoritmo | clase ) id ( :: id )* ;

 

2.1 Paquetes

 

En Loro, como en otros lenguajes, se utiliza un mecanismo de paquetes para establecer espacios de nombres para las unidades compiladas. En este sentido, cada unidad “reside” lógicamente en un cierto paquete. Salvo por el paquete anónimo (que no tiene un nombre explícito), todo paquete se identifica con un nombre particular. La sintaxis para un nombre de paquete es:

 

id ( :: id )*

 

es decir, una lista de identificadores simples separados por “::”. El nombre completo de una cierta unidad se establece indicando el nombre del paquete en que reside, el separador (“::”) y el nombre de la unidad como tal. Cada tipo de unidad establece un espacio de nombres diferente. Por esta razón, los elementos utiliza, dentro de un documento fuente, incluyen la indicación del tipo de unidad correspondiente.

3 Declaraciones

Todos los identificadores que aparezcan en una unidad de compilación (5) tienen que introducirse mediante declaraciones correspondientes. Una declaración puede ser explícita o implícita.

 

3.1 Declaraciones explícitas

En esta categoría están las definiciones de unidades,  las declaraciones de variables y las etiquetas.

 

3.1.1 Definición de unidades

La definición de una unidad (5) establece una declaración explícita para el nombre correspondiente. En el caso de clases y algoritmos, la vigencia de este nombre comienza justo a continuación del encabezado principal correspondiente con el fin de permitir la recursión. Esto no aplica para las especificaciones.

 

Para permitir la recursión mutua (y también por conveniencia), es posible utilizar un identificador para referir a una unidad (es decir, especificación, algoritmo o clase) que se define más adelante dentro de un mismo fuente. (Una implementación podría extender esta facilidad para abarcar múltiples fuentes.)

 

3.1.2 Declaración de variables

Una variable siempre tiene que declararse explícitamente y antes de cualquier uso. Toda declaración de variable involucra una asociación de un tipo de dato (4) para el identificador de la variable, y también una descripción verbal. Las declaraciones de variables siempre tienen una vigencia local dentro del ámbito en que se hace la declaración. Esta vigencia comienza justo a continuación de la declaración y va hasta el final del ámbito en que se hace la declaración. El ámbito está determinado por cada construcción que permita declaraciones de variables como se explica en otras partes de este documento. Dentro de este ámbito no puede declararse otra variable con el mismo nombre.

 

3.1.3 Etiquetas

 

Una etiqueta es un identificador para una acción de iteración (6.3). Se declaran a través de la sintaxis correspondiente a cada caso de iteración con la forma básica:

 

/ id /

 

Las acciones termine (6.5) y continúe (6.6), que operan sobre iteraciones, pueden cualificarse agregando el identificador de la iteración sobre la que deben actuar. Por defecto, estas acciones actúan sobre la iteración más inmediata. A través del mecanismo de las etiquetas se hace posible que actúen sobre una iteración no inmediata en un anidamiento de iteraciones.

 

No se permite que dos iteraciones anidadas (una dentro del cuerpo de acciones de la otra) tengan la misma etiqueta.

 

3.2 Declaraciones implícitas

Ciertos identificadores son introducidos a través de declaraciones implícitas. En este caso se encuentran las variables semánticas y ciertos atributos para arreglos y cadenas.

 

3.2.1 Variables semánticas

 

Una variable semántica (o lógica) representa un cierto valor fijo en un momento dado dentro de la ejecución de un programa.

 

Este mecanismo, que permite capturar el valor que tiene una expresión en un momento dado, puede utilizarse para relacionar valores antes y después de un cierto fragmento de código, lo que es particularmente útil en la escritura de pre y poscondiciones.

 

Este valor fijo puede corresponder también a una función matemática que, o bien no se quiere expresar, o bien no se puede expresar utilizando la semántica del mismo lenguaje. Por ejemplo, la función matemática que toma un argumento entero positivo n y produce el n-ésimo número primo podría representarse con una variable semántica.

 

Una variable semántica sólo puede aparecer dentro del contexto de las afirmaciones (6.7) y no requiere declaración explícita previa como las otras variables regulares del lenguaje. Para dar soporte adecuado a esto, la primera aparición de una variable lógica debe ser en una expresión de igualdad: expresión = x’. Para efectos de compilación, el tipo de x’ se deduce de manera automática puesto que toma exactamente el tipo de la expresión. En ejecución, el valor de x’ será el que resulte de la evaluación de la expresión. En consecuencia, la expresión no puede contener variables semánticas que no hayan sido definidas previamente (en particular, si tanto x' como y' son variables sin definir previamente, entonces la expresión x' = y' será inválida).

 

Nótese que la expresión booleana exp1 = x’, para introducir la variable semántica x’, captura la noción de que existe un valor x’ tal que la expresión dada exp1 es igual a x’; por lo tanto, siempre se evaluará con resultado cierto. Complementariamente, si x’ ya se encuentra definida previamente, entonces exp2 = x’ podrá resultar en cierto o en falso dependiendo de si los valores correspondientes son iguales en el momento de la evaluación.

 

3.2.2 Atributos automáticos

En el caso de arreglos y cadenas, los siguientes identificadores se declaran implícitamente para denotar atributos:

 

Identificador

Tipo

Descripción

inf

entero

Límite inferior en rango de indización

sup

entero

Límite superior en rango de indización

longitud

entero

Tamaño total del arreglo o cadena

 

Si x es un arreglo o cadena, siempre se cumple que x.longitud = x.supx.inf + 1. Ver 7.6 y 7.10.

4 Tipos

 

4.1 Tipos en Loro

Loro ofrece los siguientes tipos de datos: