close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Version 1 (modified by Víctor de Buen Remiro, 16 years ago) (diff)

--

NameBlock

El tamaño de los programas en Tol ha estado creciendo durante los últimos años, y al mismo ritmo que ha aumentado el número de lineas de código, han proliferado también el número de funciones y variables, casi todas ellas en el ámbito global. El resultado de este crecimiento incontrolado es un concurrido ámbito global que complica el nombrado de los elementos de Tol y disminuye la organización de los programas.

Con el objetivo de evitar esta tendencia se ha desarrollado en Tol un nuevo tipo de datos NameBlock que dé las funcionalidades típicas de los espacios de nombres (namespace) como el de C++, por ejemplo, aunque con ciertas diferencias pues no se trata tan sólo de un ámbito de nombres sino también de un contenedor de objetos que pueden ser privados ó públicos.

Esta característica está disponible desde la versión 1.1.6, aunque se presenta aún como sistema en pruebas y no es definitivamente oficial hasta la 1.1.7, momento en el que se recomienda su uso intensivo.

Definiciones

  • Un bloque de nombres o NameBlock es un tipo de datos especial que se crea partiendo de un conjunto al que llamaremos base del NameBlock, y que implica un ámbito de localización de objetos.
  • A sus elementos les llamaremos miembros y pueden ser tanto variables como funciones o estructuras.
  • Los habrá que permanezcan ocultos fuera del ámbito y les llamaremos miembros privados.
  • El resto, llamados miembros públicos, podrán ser accesibles desde el exterior, a pesar de ser siempre todos locales por construcción, sin necesidad de explicitar las llaves {...}.

sintaxis Enviado por vdebuen el Vie, 03/23/2007 - 20:06.

Debido a que no deja de haber ciertas semejanzas con el tipo de datos Set, como contenedor de objetos que es, existirá la tentación de usar un NameBlock como si fuera un conjunto, pero hay que tener en cuenta que existen grandes diferencias, como se puede observar a continuación.

Reglas sintácticas

  1. Reglas de declaración de un NameBlock
  • 1.1. La sintaxis de definición de un NameBlock admite únicamente tres posibles formas BNF, de las cuales se dan más detalles en los apartados posteriores:

o 1.1.1.A partir de una expresión similar a la de un conjunto definido directamente con ...? :

                <nameblock_declaration> ::= "NameBlock" <variable_id> "=" 
                "[["
                  [{ 
                    <public_member_expression> | 
                    <private_member_expression> "," | ";" }] 
                  <public_member_expression> 
                  [{
                    "," | ";" 
                    <public_member_expression> | 
                    <private_member_expression> } ] 
                "]]"

o 1.1.2.Como alias de otro NameBlock

                <nameblock_declaration> ::= "NameBlock" <variable_id> "="
                  <member_expression>

                <member_expression> ::=
                  <variable_id> |
                  <variable_id>"::"<public_member_expression>

o 1.1.3.Como resultado de una función que devuelva NameBlock anidado

                <nameblock_declaration> ::= "NameBlock" <variable_id> "="
                  <member_expression>

                <member_expression> ::=
                  <variable_id> |
                  <variable_id>"::"<public_member_expression>
  • 1.2. Declaración de miembros:

o 1.2.1 El prefijo subrayador simple _ especifica los miembros privados de un NameBlock.

                <private_member_expression> ::=
                  <type_id> "_"<alphanumeric_char><variable_id> 
                  ["=" <object_expression>]
o 1.2.2 El prefijo subrayador+punto _. se reserva para miembros de sólo lectura como por ejemplo _.autodoc.description. Estos miembros no son plenamente accesibles, por lo que son realmente un caso particular de miembro privado. Sin embargo, sí se puede obtener una copia de su contenido a través del operador
lo cual impide su modificación por medios externos al NameBlock.
                <read-only_member_expression> ::=
                  <type_id> "_"<alphanumeric_char><.variable_id> 
                  ["=" <object_expression>]
o 1.2.3. Un NameBlock puede o no tener miembros privados pero ha de tener al menos un miembro público, con excepción del NameBlock Unknown del sistema que es el vacío.
                <public_member_expression> ::=
                  <type_id>   <alphanumeric_char><variable_id> 
                  ["=" <object_expression>]
Ejemplo de uso inválido:
                NameBlock BadNS_1.2.3.a = Unknown;
                NameBlock BadNS_1.2.3.b = [[Real _a=0]];
Veámoslo con un ejemplo:
          NameBlock MyNS_1.2 =  
          [[
            Text _.autodoc.description = "NameBlock de ejemplo del punto 1.2";
          //Public members
            Struct mystr { Real x_; Text t_ };
            Set real2mystr(Real x) 
            { 
              mystr(x,""+FormatReal(x,"%.15lg"))
            };
          //Private member
            Real _fun_aux(Real x) { x*4 };
          //Public members
            Real fun_a(Real x) { _fun_aux(x)+1 };
            Real fun_b(Real x) { _fun_aux(x)-1 };
          //Private members
            Real _aux_1 = 1;
            Real _aux_2 = 2;
            Set  _aux_3 = real2mystr(2);
          //Read only members
            Real _.exported_1 = _aux_1+_aux_2;
            Real _.exported_2 = _aux_1-_aux_2*_aux_3->x_
          ]];
  • 1.3. Restricciones sobre la creación de miembros
o 1.3.1 Un NameBlock no puede tener varios miembros con el mismo nombre. Ejemplo de uso inválido:
                NameBlock BadNS_1.3.1 = 
                [[
                  Set _a = { [[Real x=0]] };
                  Set _b = { [[Real x=1]] };
                  _a[1],
                  _b[1]
                ]] 
o 1.3.2. Un NameBlock no puede tener miembros sin nombre. Ejemplo de uso inválido:
                NameBlock BadNS_1.3.2 = [[Real 0]];
o 1.3.4. Un NameBlock no puede tener sólo sentencias que no devuelvan una variable, una función o una estructura, como por ejemplo el Write, o el While. Ejemplo de uso inválido:
                NameBlock BadNS_1.3.4 = 
                [[
                  WriteLn("Hola")
                ]];
o 1.3.5. Un NameBlock no puede tener miembros que sean globales o accesibles al mismo nivel que el propio NameBlock o a nivel superior. Ejemplo de uso inválido:
                Real x=0;
                NameBlock BadNS_1.3.5 = [[Real x]];