6









                                      
                            ESPECIFICACIONES DEL LENGUAJE
           _______________________________________________________________



          Este  cap¡tulo no pretende  aportar una descripci¢n  completa del
          lenguaje  Pascal,  sino solamente  indicar  las  restricciones de
          CDS/ISIS  Pascal  en  relaci¢n  con  el  Pascal  estandar,  o sus
          desviaciones  a  este  respecto.  Para  obtener  una  descripci¢n
          completa de Pascal el usuario debe referirse a un manual adecuado
          de programaci¢n de ese lenguaje.

          A. Constantes, Tipos y Variables

           Las declaraciones CONST y TYPE no son soportadas

           Unicamente pueden usarse tres tipos predefinidos:

          REAL   Valores numricos  reales.  Las  constantes  de  tipo real
             pueden ser enteros o n£meros decimales con un  signo opcional.
             No se soporta la notaci¢n exponencial.

           ARRAY[1..n] OF REAL

          Los l¡mites del arreglo deben ser constantes enteras,  y el nivel
          inferior debe ser 1. No se soportan arreglos de constantes.

           ARRAY[1..n] OF STRING

          Las versiones 2.34  y 3.0  aceptan arreglos de cadenas (strings).
          Por ejemplo: S:ARRAY[1..20] OF STRING;

          STRING Cadenas (strings)  de caracteres de longitud variable. Las
             cadenas  nulas  o  vac¡as  y  de  constantes  (p.ej.  '')  son
             soportadas.

          Todas  las variables deben ser  declaradas  en  una  cl usula VAR
          antes de ser usadas.

          B. Expresiones

          Las expresiones aritmticas,  booleanas y  de  cadenas  siguen la
          sintaxis estandar de Pascal (n¢tese que las expresiones booleanas
          se aceptan en  declaraciones condicionales,  aunque las variables
          de tipo BOOLEAN no pueden ser declaradas).

          Se soportan los siguientes operadores:



                                          6








           Unario   + -
           Suma    +
           Resta   -
           Multiplicaci¢n      *
           Divisi¢n   /
           Concatenaci¢n       | (operador de cadenas - string)
           Booleano   AND OR NOT
           Relacional  = <> <= >= < > (n¢tese que para que dos cadenas sean
                 identificadas como iguales, deben tener la misma longitud)

          C. Declaraciones

          Las siguientes declaraciones han sido  implementadas (a  menos de
          que   se   mencionen   restricciones   espec¡ficas,   todas   las
          declaraciones   implementadas   siguen  la  sintaxis   de  PASCAL
          estandar):

          Declaraci¢n de asignaci¢n:  El lado izquierdo y el  derecho de la
             asignaci¢n deben ser del mismo tipo.

          Declaraci¢n IF:  Para  el  uso  de  operadores  booleanos  en las
             versiones 2.34  y  3.0,  ver  nota  relativa  a  este  tipo de
             operadores.

          Declaraci¢n CASE:El selector de CASE puede ser una expresi¢n REAL
             o  STRING.  Cuando se  usen expresiones  STRING, las etiquetas
             CASE   correspondientes  pueden   ser   cadenas   (strings)  o
             caracteres  aislados.  Sin  embargo,  con  objeto  de  que  se
             comparen de  manera  apropiada,  la expresi¢n debe generar una
             cadena que tenga la misma  longitud que las  constantes de las
             etiquetas  de  CASE.   No  se  soportan  etiquetas  constantes
             m£ltiples de CASE.

          Declaraci¢n  FOR:  La variable de  control debe  ser una variable
             local.  No puede ser  un  par metro  ni  un  componente  de un
             arreglo.

          Declaraci¢n WHILE

          Declaraci¢n REPEAT ... UNTIL

          D. Procedimientos y Funciones

          Se soportan tanto las funciones REAL como STRING.  No se soportan
          las funciones ARRAY.

          Todos los  par metros  REAL  de  procedimientos  y  funciones son
          transferidos  por valor,  mientras que los  par metros STRING son
          transferidos por referencia.  Sin embargo,  el prefijo VAR de los
          par metros no debe ser declarado.  Aunque el compilador no genera
          un mensaje si  se  hace  una  asignaci¢n  a  un  par metro formal
          transferido   por   valor,    el   valor   del   par metro   real
          correspondiente en el procedimiento que genera la llamada no ser 
          afectado.




                                          7








          Del  mismo modo,  el compilador  no valida si  el par metro real,
          correspondiente a un par metro formal transferido por referencia,
          es una expresi¢n,  y el  procedimiento  le  asigna  un  valor. Es
          responsabilidad   del   programador   asegurar   que   cuando  un
          procedimiento asigne un  valor a un  par metro formal transferido
          por referencia, el par metro real correspondiente sea siempre una
          variable sola.

           Por ejemplo:

          Procedure A;
          Var x: Real;
              c: String;

            Procedure B(n: Real; s: string);
            Begin
              n:=5;
              s:=s|'.';
            End;

          Begin
          x:=1; c:='Agua';
          B(x,c);
          {el valor de x en este punto sigue siendo 1}
          {mientras que el valor de c es 'Agua.'}
          End;

          N¢tese  tambin  que  el  compilador  no  verifica  si  se asigna
          efectivamente  un  valor a una funci¢n dentro  del  cuerpo  de la
          funci¢n.  Si no  se  asigna  un  valor antes  de  que  termine la
          funci¢n, el valor que esta entrega es impredecible.

          No se soportan procedimientos ni funciones externas.

          E. Alcance de los identificadores

          El  mbito  de  los identificadores  de  las  variables  o  de las
          funciones se define del mismo  modo que en PASCAL  estandar (esto
          es,  una variable  declarada en  un procedimiento es local  a ese
          procedimiento y es desconocida en cualquier procedimiento externo
          a este).

          F. Archivos de texto

          Adem s  de  los  archivos  estandar  INPUT  (entrada)   y  OUTPUT
          (salida),  pueden  utilizarse dos archivos de  texto adicionales:
          INP  (para la  entrada)  y OUT (para la  salida).  INPUT y OUTPUT
          siempre  son asignados a las unidades  estandar  de  entrada y de
          salida.   Para  estos  archivos,  siempre  se  generan  en  forma
          autom tica las declaraciones  RESET  o  REWRITE.  INP  y  OUT son
          asignadas  impl¡citamente  a los  dispositivos  de  entrada  y de
          salida respectivamente,  pero pueden ser reasignados a travs del
          procedimiento predefinido ASSIGN (ver m s adelante).





                                          8








          Los procedimientos  estandar READ,  READLN, WRITE, WRITELN tienen
          la  misma sintaxis  que en Pascal estandar.  En las declaraciones
          WRITE y  WRITELN la opci¢n fieldwidth  (ancho del  campo) solo se
          soporta  para  expresiones REAL.  En este  caso,  se  aplican las
          siguientes reglas:

          WRITE[LN] ([OUT,] exp1 [: exp2 [: exp3]]);

          donde:  exp1  es el  valor a ser escrito,  exp2  es  el ancho del
          campo, y exp3 es la precisi¢n.

          Si solo  se  especifica  exp2,  el valor se  convierte  primero a
          entero (el valor escrito es en realidad TRUNC(exp1 : exp2). Si se
          especifican tanto exp2 como exp3, el valor es escrito en notaci¢n
          decimal.  Si no se especifica ni exp2 ni exp3 el valor se escribe
          en notaci¢n cient¡fica exponencial.

          La funci¢n EOF (End-Of-File, fin de archivo), puede ser usada con
          la entrada estandar o con el archivo INP.  Al igual que en Pascal
          estandar,  devuelve  un  valor  booleano,  y  su  sintaxis  es la
          siguiente:

          EOF[(INP)]

           La funci¢n EOLN (fin de l¡nea) no es soportada.

          G. Comentarios

          Se soportan los comentarios, mismos que deben ser delimitados por
          {}. Los delimitadores alternos (* *) no son soportados.

          H. Dise¤o e integraci¢n de llamadas de usuario [1]

          Una llamada del usuario es  dise¤ada  para ser  aplicada en forma
          espec¡fica  dentro  de  CDS/ISIS,  y  debe ser  declarada como un
          atributo en la declaraci¢n PROGRAM. A diferencia de los programas
          batch, las llamadas de usuario pueden declarar par metros a nivel
          del programa  que ser n  transferidos  al  programa  por CDS/ISIS
          cuando la llamada se active. Estos par metros son fijos para cada
          tipo de llamada, y son validados por el compilador.

          Las llamadas de usuario pueden ser escritas para aplicarse  a las
          funciones de CDS/ISIS que se describen a continuaci¢n.

           1. Llamadas de MENU

          Las llamadas de MENU son activadas cuando  el  usuario selecciona
          una opci¢n espec¡fica  de un men£  del sistema.  Una opci¢n de un
          men£ puede ser asociada  con una llamada de  MENU,  asign ndole a
          esa opci¢n el c¢digo de acci¢n E (vase la secci¢n "El  editor de
          men£s" en el Manual de referencia de CDS/ISIS).

          Las llamadas  de MENU tienen  un par metro,  y se especifican del
          modo siguiente:

          Program xxxxx (s1: string) [MENU];


                                          9









          El par metro s1 opera tanto para la entrada como para la salida:

          Durante la entrada al programa:  s1  es una cadena de un caracter
             que  contiene  el  identificador de  la  opci¢n  que gener¢ la
             llamada;

          Durante el regreso del programa:  el programador debe restablecer
             el valor de s1 a uno de los siguientes casos:

             blanco para desplegar nuevamente el men£ actual

          s  para ocasionar la selecci¢n autom tica de la opci¢n s del men£
             actual   (el  men£  no   es  desplegado  y   el  control  pasa
             directamente  al  programa  llamado,   como   si   se  hubiera
             seleccionado la opci¢n s desde el men£);  en este caso, s debe
             ser  el  identificador  externo  (o  sea  el  que  se  muestra
             efectivamente en  el  men£)  de  una  opci¢n  v lida  del men£
             actual.  Si  s no  es  una opci¢n  v lida,  se genera un aviso
             audible,  y se  despliega el  men£.  N¢tese que s debe  de ser
             diferente del valor recibido en  s1,  ya que en caso contrario
             se produce un ciclo (loop) infinito;

          .s    para producir la ejecuci¢n directa de la opci¢n s;  en este
             caso, s debe ser el identificador interno de una opci¢n v lida
             del men£ actual.  Esto es £til cuando se desea  realizar alg£n
             trabajo preliminar antes  de ejecutar la  opci¢n estandar (ver
             el ejemplo presentado m s adelante).

          N¢tese que si el programa que se elabor¢ autoteclea una cadena de
          caracteres  (ver  el  procedimiento  AUTOTYPE  m s  adelante), la
          acci¢n indicada  por el  par metro s1  a la  salida, es ejecutada
          antes de la cadena autotecleada.

             Program CHKPWD (s: string) [men£];
             var nombrebd: string;

            Function CHECA: string;
            var cnt: real;
                pw : string;
            begin
            clear;
            cursor(10,10); write ('indique clave de acceso ');
            cnt:=0;
            repeat
            attr(' ',5,10,25,6); readln(pw);
            cnt:=cnt+1; {cuenta n£mero de intentos}
            if pw<>'x12y' then
             begin cursor(12,25); writeln(chr(7), 'clave inv lida'); end;
            until (pw='x12y') or (cnt>2); {permite solo hasta dos intentos}
            if pw<>'x12y'
             then begin checa:=' '; pw:=inkey; end
             else checa:='.E';
            end;

            begin


                                         10








            nombrebd:=dbn;
           if nombrebd='' then {obliga al usuario a seleccionar una base de
          datos si no hay ninguna activa}
             begin
               clearmsg;   write('Nombre   de   la   base   de   datos? ');
          readln(nombrebd);
             if nombrebd <> '' then open(nombrebd);
             end;
            if dbn=''
            then s:=' '  {si no hay base de datos activa vuelve a desplegar
          el men£}
             else if dbn='CDS'
              then  s:=  checa  {si se  seleccion¢  la  base  de datos CDS,
          entonces verificar clave de acceso}
             else s:= '.E'  {ok para las dem s bases de datos}
            end.

          El ejemplo anterior ilustra como se podr¡a controlar el  acceso a
          la captura de datos a una base de datos de CDS/ISIS  por medio de
          una clave de acceso (password).

          Cuando esta salida de men£ est  asociada  a la opci¢n E  del men£
          principal xXISI,  solicitar  la clave de acceso x12y cada vez que
          la base de datos CDS sea seleccionada para captura.

           2. Llamadas FORMAT (Formato)

          Las llamadas  FORMAT se activan cuando  se procesa  un formato de
          despliegue de CDS/ISIS.  Puede usarse para suministrar datos a la
          rutina  estandar  de formateo (ver  "Lenguaje de  formateo" en el
          Manual  de  referencia  de  CDS/ISIS).  Las  llamadas  FORMAT son
          invocadas incluyendo  la  siguiente especificaci¢n  en el formato
          del usuario:

             &nombre(formato)

            donde:

          &    identifica  que esta  es  una invocaci¢n  a  una  llamada de
             formato

          nombre   es el nombre del programa  CDS/ISIS Pascal que  se desea
             ejecutar; y

          formato     es un formato de CDS/ISIS.

          Las salidas de formato tienen cuatro par metros, y se declaran de
          la manera siguiente:

          Program xxxx (s1: string; lw, occ: real; s2: string)[FORMAT];

            donde:

          xxxx   es el  nombre del  programa (que ser   entonces usado para
             invocar la  llamada desde el  formato,  como  se  mencion¢ m s
             arriba);


                                         11









          s1  es el resultado de la ejecuci¢n del formato especificado como
             par metro  al  invocar  la  llamada;   puede  ser  usado  para
             suministrar uno o m s par metros al programa del usuario, y es
             £til para poder dise¤ar llamadas de formato  generalizadas; la
             longitud m xima de esta cadena es de 255 caracteres;

          lw   es  el ancho  de la l¡nea (line width)  que se  encuentra en
             efecto cuando se ejecuta la llamada; puede ser £til en algunos
             casos,  para conocer este dato cuando el programa genera datos
             de longitud fija;

          occ   es  el  contador  de ocurrencias.  Este dato es cero  si la
             llamada fue  invocada fuera de un grupo repetible,  y es mayor
             que cero si la llamada se gener¢ dentro de un grupo repetible.
             En este caso, CDS/ISIS llamar  en forma reiterada a la llamada
             de  formato,  para  cada  ejecuci¢n  del  grupo  repetible. La
             primera vez lo  har   con occ=1,  la segunda  con occ=2, etc.,
             hasta que  el usuario entregue una cadena  vac¡a (en  s2) para
             indicar que ya no hay m s datos que procesar.

          s2   son los datos de  salida  que ser n enviados  al programa de
             formateo de CDS/ISIS.  El sistema CDS/ISIS operar  sobre estos
             datos del mismo  modo  que  si  se  tratara  de  un  campo del
             registro que se est  formateando. N¢tese que la longitud de s2
             no est  restringida.

          Si la  llamada de  formato del  usuario  se  dise¤a  para manejar
          campos repetibles,  debe verificarse el par metro  occ para saber
          si todas las ocurrencias deben tratarse  de una  sola vez (cuando
          occ=0,  la llamada solo se genera una  vez),  o una por una. Otra
          posibilidad  es  que se  establezcan restricciones al  uso  de la
          llamada,  tal como decidir que siempre debe  usarse  dentro de un
          grupo  repetible.  Por ejemplo,  la siguiente  llamada de formato
          puede  ser usada dentro  de  un grupo repetible  para numerar las
          ocurrencias de un  campo repetible (la etiqueta  del campo  a ser
          numerado se transfiere como par metro):

             Program NUMERA(s1: string; lw,occ: real; s2: string) [FORMAT];
             begin
             if nocc(val(s1)) >= occ
             then s2:=encint(occ,3) | '. '
             else s2:='';
             end.

          Un ejemplo del uso de esta llamada de  formato (para  numerar las
          ocurrencias del campo 70) se presenta a continuaci¢n:











                                         12








             Formato: (&numera('70'),v70/)
                         |            |
                         |            |
                         |    ________|
                         |    |
                         |    |
                         V    V
             Salida:     1. Jones, P.
                         2. Brown, J.
                         3. McKenzie, K.

          I. Notas relativas a las versiones 2.34 y 3.0

          1.  En las versiones  previas a la  2.34  se ten¡a un problema al
             realizar llamadas recursivas al interprete de Pascal (el valor
             de algunas variables pod¡a perderse al regreso de  una llamada
             previa).  Algunos ejemplos de llamadas recursivas son:  (a) un
             programa en  Pascal  que ejecuta un  formato que  contiene una
             salida  de  formato;  (b)  un programa en Pascal que invoca un
             men£ (con la funci¢n MENU),  el cual en alguna de sus opciones
             llama a un  programa  en  Pascal;  (c)  un  programa llamado a
             travs del procedimiento EXIT.

          Para resolver este problema,  en las nuevas  versiones se incluye
          la  declaraci¢n  USES  para  declarar  programas  que  van  a ser
          llamados en forma indirecta.

          2. Los procedimientos READ y READLN han sido modificados a partir
             de la versi¢n 2.34  para permitir la lectura de cadenas de m s
             de  255  caracteres,  siempre y cuando la cadena  no exceda el
             tama¤o del  rea disponible para ello.

          (1)Las versiones 2.34  y 3.0 implementan la norma ISO para el uso
          de  las expresiones booleanas en  las declaraciones  IF, mientras
          que las versiones anteriores  se  desv¡an de  este  estandar. Por
          ejemplo,  IF A=B and  C=D  THEN  ...  era  evaluado correctamente
          aunque seg£n la norma deb¡a haber producido un error de sintaxis,
          ya  que AND tiene  una  mayor  prioridad  que  los  operadores de
          comparaci¢n. Es posible que sea necesario modificar los programas
          en donde se usaron estas instrucciones  de este modo,  ya que con
          las nuevas versiones se tendr  un error de compilaci¢n.

          (2)Se opt¢ por designar como llamadas  de usuario  a la expresi¢n
          "user exits"  en  preferencia a 'salidas  de usuario',  ya que en
          realidad se trata de llamadas a funciones o  programas elaborados
          por el usuario,  y el concepto de 'salida' no tiene en espa¤ol la
          misma connotaci¢n.











                                         13




: