                  Revisin 1 de la Traduccin <14-02-1998>
*****************************************************************************
NOTAS - N.T.> significa Nota del Traductor
      - No se traducen las palabras que forman parte del RPL del Sistema

                                  CONTENIDO

      1. Introduccin.........................................   1

      2. Principios de RPL....................................   2
         2.1   Orgenes.......................................   2
         2.2   Control Matemtico.............................   3
         2.3   Definiciones Formales..........................   5
         2.4   Ejecucin......................................   6
               2.4.1    EVAL..................................   8
               2.4.2    Objetos de la Clase Datos.............   9
               2.4.3    Objetos de la Clase Identificador.....   9
               2.4.4    Objetos de la Clase Procedimiento.....  10
               2.4.5    Esquivar Objeto y SEMI................  10
               2.4.6    Punteros RPL..........................  11
         2.5   Manejo de la Memoria...........................  11
         2.6   RPL de Usuario y RPL del Sistema...............  13
         2.7   Programacin en RPL del Sistema................  14
         2.8   Programa de Ejemplo en RPL.....................  16
               2.8.1    El Fichero Fuente.....................  16
               2.8.2    Compilar del Programa.................  18

      3. Estructuras de los Objetos...........................  19
         3.1   Tipos de Objetos...............................  19
               3.1.1    Objeto Identificador..................  19
               3.1.2    Objeto Identificador Temporal.........  19
               3.1.3    Objeto Puntero ROM....................  20
               3.1.4    Objeto Entero Binario.................  20
               3.1.5    Objeto Nmero Real....................  20
               3.1.6    Objeto Nmero Real Extendido..........  21
               3.1.7    Objeto Nmero Complejo................  22
               3.1.8    Objeto Nmero Complejo Extendido .....  22
               3.1.9    Objeto Formacin......................  23
               3.1.10   Objeto Formacin Encadenada...........  23
               3.1.11   Objeto Cadena de Caracteres...........  25
               3.1.12   Objeto Cadena Hexadecimal (Hex).......  25
               3.1.13   Objeto Carcter.......................  25         
               3.1.14   Objeto Unidad.........................  26
               3.1.15   Objeto Cdigo.........................  26
               3.1.16   Objeto Cdigo Primitiva...............  27
               3.1.17   Objeto Programa.......................  27
               3.1.18   Objeto Lista..........................  28
               3.1.19   Objeto Simblico......................  28
               3.1.20   Objeto Directorio.....................  29
               3.1.21   Objeto Grfico........................  29
         3.2   Terminologa y Abreviaciones...................  30

      4. Enteros Binarios.....................................  32
         4.1   Enteros Binarios Incorporados..................  32
         4.2   Manipulacin de Enteros Binarios...............  34
               4.2.1    Funciones Aritmticas.................  34
               4.2.2    Funciones de Conversin...............  35
      
      5. Constantes Carcter..................................  36

      6. Cadenas Hex y de Caracteres..........................  37



                                  - i -



         6.1   Cadenas de Caracteres..........................  37
         6.2   Cadenas Hex....................................  39
      
      7. Nmeros Reales.......................................  41
         7.1   Reales Incorporados............................  41
         7.2   Funciones de Nmeros Reales....................  41      

      8. Nmeros Complejos....................................  46
         8.1   Nmeros Complejos Incorporados.................  46
         8.2   Palabras de Conversin.........................  46
         8.3   Funciones de Complejos.........................  46

      9. Formaciones..........................................  48

     10. Objetos Compuestos...................................  49

     11. Objetos Etiquetados..................................  51

     12. Objetos Unidades.....................................  52

     13. Variables Temporales y Entornos Temporales...........  54
         13.1  Estructura del Area de Entornos Temporales....  55
         13.2  Variables Temporales con Nombre versus Sin
               Nombre.........................................  57
         13.3  Palabras Proporcionadas para las Variables 
               Temporales.....................................  59
         13.4  Sugerencias para la Codificacin...............  60

     14. Chequeo de Argumentos................................  61
         14.1  Nmero de Argumentos...........................  62
         14.2  Despachar segn el Tipo de Argumento...........  63
         14.3  Ejemplos.......................................  66

     15. Estructuras de Control de Bucles.....................  68
         15.1  Bucles Indefinidos.............................  68
         15.2  Bucles Definidos...............................  70
               15.2.1   Palabras Proporcionadas...............  70
               15.2.2   Ejemplos..............................  71

     16. Generacin y Captura de Errores......................  73
         16.1  Captura: ERRSET y ERRTRAP......................  73
         16.2  Accin de ERRJMP...............................  73
         16.3  La Palabra de Proteccin.......................  74
         16.4  Palabras de Error..............................  75

     17. Test y Control.......................................  76
         17.1  Banderas y Tests...............................  76
               17.1.1   Tests de Objetos en General...........  77
               17.1.2   Comparaciones de Enteros Binarios.....  78
               17.1.3   Tests de Nmeros Decimales............  79
         17.2  Palabras que Operan en el "Runstream"..........  80
         17.3  If/Then/Else...................................  83
         17.4  Palabras CASE..................................  84

     18. Operaciones de la Pila...............................  87

     19. Operaciones de Memoria...............................  89
         19.1  Memoria Temporal...............................  89




                                  - ii -



         19.2  Variables y Directorios........................  89
               19.2.1   Directorios...........................  91
         19.3  El Directorio Oculto...........................  92
         19.4  Utilidades Adicionales de Memoria..............  93

     20. Manejo de la Pantalla y Grficos.....................  94
         20.1  Organizacin de la Pantalla....................  94
         20.2  Preparacin de la Pantalla.....................  95
         20.3  Control del Refresco de la Pantalla............  96
         20.4  Borrar la Pantalla.............................  97
         20.5  Control de los Indicadores.....................  97
         20.6  Coordenadas de la Pantalla.....................  98
               20.6.1   Coordenadas de la Ventana.............  98
         20.7  Mostrar Texto..................................  99
               20.7.1   Areas Estndar para Mostrar Texto.....  99
               20.7.2   Mensajes Temporales................... 101
         20.8  Objetos Grficos............................... 102
               20.8.1   Advertencias.......................... 102
               20.8.2   Herramientas Grficas................. 103
               20.8.3   Dimensiones de los Grobs.............. 104
               20.8.4   Grobs Incorporados.................... 104
               20.8.5   Utilidades para Mostrar Mens......... 105
         20.9  Desplazar la Pantalla.......................... 105

     21. Control del Teclado.................................. 109
         21.1  Ubicacin de las Teclas........................ 109
         21.2  Esperar una Tecla.............................. 110
         21.3  InputLine...................................... 111
               21.3.1   Ejemplo de InputLine.................. 112
         21.4  El Bucle Externo Parametrizado................. 113
               21.4.1   Utilidades del Bucle Externo 
                        Parametrizado......................... 114
               21.4.2   Examen del Bucle Externo 
                        Parametrizado......................... 115
               21.4.3   Controlar Errores con las Utilidades.. 116
               21.4.4   La Pantalla........................... 116
               21.4.5   Control de Errores.................... 117
               21.4.6   Asignaciones de Teclas Fsicas........ 117
               21.4.7   Asignaciones de Teclas de Mens....... 119
               21.4.8   Evitar Entornos Suspendidos........... 120
               21.4.9   Especificar una Condicin de Salida... 120
               21.4.10  Ejemplo de ParOuterLoop............... 121

     22. Comandos del Sistema................................. 123


















                                 - iii -

Traduccin del documento original en Ingls: RPLMAN.doc



                          GUIA DE PROGRAMACION RPL



      1. Introduccin

      La calculadora HP 48 se dise para ser un bloc matemtico
      personalizable para ser usado por estudiantes y profesionales de campos
      tcnicos. En muchos aspectos es un descendiente de la HP 41,
      proporcionando una capacidad de computacin mucho ms amplia y
      sofisticada que la HP 41 pero conservando su orientacin
      RPN/una-funcin-por-tecla.

      La HP 48 usa la, as llamada, arquitectura Saturno, as denominada por
      el nombre del cdigo de la CPU original diseada para el ordenador de
      mano HP 71B. Tambin usa un sistema operativo/lenguaje a la medida
      llamado RPL, que se dise para proporcionar capacidades de matemtica
      simblica, ejecutndose desde ROM en un entorno con RAM limitada
      (todava hoy, es el nico sistema simblico que se puede ejecutar en
      ROM). La combinacin de hardware y firmware especializados hace
      relativamente difcil el desarrollo de software de aplicaciones para la
      HP48 y, en consecuencia, la HP48 no esta situada como un vehculo
      fundamental para aplicaciones externas. La orientacin del producto y
      de su lenguaje de programacin del usuario es hacia la personalizacin
      sencilla por el usuario principal.

      A pesar de estas barreras, el precio y la configuracin fsica de la
      HP48 la hacen una plataforma deseable para muchos desarrolladores de
      software, especialmente aquellos que quieren llegar a los clientes de
      los mercados normales de la HP48. El lenguaje de usuario es adecuado
      para programas sencillos, pero para sistemas elaborados, la deliberada
      proteccin de errores y otros gastos pueden dar lugar a penalizaciones
      substanciales comparado con los programas que usan todo la gama de
      llamadas del sistema.

      En este documento, proporcionaremos una descripcin del diseo y las
      convenciones del lenguaje RPL. Este material debera proporcionar
      suficientes detalles para permitir la creacin de programas RPL y otros
      objetos, usando las herramientas asociadas de compilacin para IBM-PC.
      Se incluye documentacin de un gran nmero de objetos del RPL del
      sistema que son utilidades tiles para el desarrollo de programas.



















                                  Pgina 1






      2. Principios de RPL

      (El siguiente material esta extrado de "RPL: Un Lenguaje de Control
      Matemtico" por W.C. Wickes, publicado en "Entornos de Programacin",
      Instituto para la Investigacin de Forth Aplicado, Inc., 1988)
      

      2.1 Orgenes      

      En 1984, se inici un proyecto en la divisin de Hewlett-Packard en
      Corvallis para desarrollar el software de un nuevo sistema operativo
      para el desarrollo de una lnea de calculadoras y dar soporte a una
      nueva generacin de hardware y software. Anteriormente todas las
      calculadoras HP se implementaron enteramente en lenguaje ensamblador,
      un proceso que se iba haciendo cada vez ms pesado e ineficiente a
      medida que aumentaba la memoria de las calculadoras. Los objetivos para
      el nuevo sistema operativo fueron los siguientes:

         +  Proporcionar control de la ejecucin y manejo de la memoria,
            incluyendo memoria conectable;

         +  Proporcionar un lenguaje de programacin para un rpido
            desarrollo de prototipos y aplicaciones;

         +  Para soportar un variedad de calculadoras de negocio y tcnicas;

         +  Para ejecutarse idnticamente en RAM y ROM;

         +  Para minimizar el uso de memoria, especialmente RAM;

         +  Para ser transportable a varias CPU's;

         +  Para ser extensible; y

         +  Para soportar operaciones de matemtica simblica.


      Se tuvieron en cuenta varios lenguajes y sistemas operativos ya
      existentes pero ninguno cumpla con todos los objetivos del diseo. Por
      consiguiente se desarroll un nuevo sistema, el cual mezcla la
      interpretacin entrelazada de Forth con el enfoque funcional de Lisp.
      El sistema operativo resultante, conocido de modo no oficial como RPL
      (de Reverse-Polish Lisp), hizo su primera aparicin pblica en junio de
      1986 en la calculadora Business Consultant 18C. Ms tarde, RPL ha sido
      la base de las calculadoras HP-17B, HP-19B, HP-27S, HP-28C y HP-28S y
      HP 48S y HP 48SX. La HP-17B, 18C y la 19B se disearon para
      aplicaciones de negocios; ellas y la calculadora cientfica HP-27S
      ofrecen una lgica de clculo "algebraica" y el sistema operativo
      subyacente es invisible para el usuario. Las familias HP 28/HP 48 de
      calculadoras cientficas usan una lgica RPN y muchas de la facilidades
      del sistema operativo estn disponibles directamente como comandos de
      la calculadora.
       






                                  Pgina 2






      2.2   Control Matemtico


      Los objetivos oficiales del sistema operativo listados arriba se fueron
      mezclando, a lo largo del ciclo de desarrollo del RPL, con un objetivo
      menos formal de creacin de un lenguaje de control matemtico que
      extendera la facilidad de uso y la naturaleza interactiva de una
      calculadora al reino de las operaciones de la matemtica simblica. En
      este contexto, una calculadora se distingue de un ordenador por:

         +  tamao muy compacto;

         +  "encendido instantneo" --sin calentamiento o carga de software; 

         +  teclas dedicadas para las operaciones comunes en lugar de
            teclados qwerty.
   
         +  "accin instantnea" cuando se pulsa una tecla de funcin.


      La HP-28, que fue desarrollada por el mismo equipo que cre el sistema
      operativo RPL, fue la primera realizacin de este objetivo de fondo; la
      HP 48 es la ltima y ms madura implementacin.

      Buena parte del diseo del RPL se puede derivar a partir de considerar
      la manera en que se evalan ordinariamente las expresiones matemticas.
      Considera, por ejemplo, la expresin

                                1+2seno(3x)+4

      Como sabe cualquier entusiasta del RPN, la expresin aqu escrita no se
      corresponde con en su orden de izquierda a derecha con el orden en el
      que una persona o una mquina podra realmente llevar a cabo el
      clculo. Por ejemplo, la primera suma se tiene que posponer hasta que
      se ejecuten varios pasos. Reescribiendo la expresin en la forma RPN,
      obtenemos una representacin que tambin es ejecutable en el orden
      escrito:

                 1   2   3   x   *   seno   *   +   4   +

      Para traducir esta secuencia a un lenguaje de control, necesitamos
      formalizar varios conceptos. Primero, usamos el trmino genrico objeto
      para referirnos a cada paso de la secuencia, tales como 1, 2, o seno.
      Incluso en este sencillo ejemplo, hay tres clases de objetos:

         1. Objetos de Datos. La ejecucin de un objeto tal como 1, 2 o 3 en
            el ejemplo, simplemente devuelve el valor del objeto.

         3. Nombres. El smbolo x debe ser el nombre de algn otro objeto;
            cuando se ejecuta x, el objeto nombrado substituye al smbolo.









                                  Pgina 3




         3. Procedimientos. Los objetos tales como *, seno y + representan
            operaciones matemticas, que se aplican, por ejemplo, a objetos
            de datos para crear nuevos objetos de datos.

      El concepto de objeto est estrechamente ligado al concepto de
      ejecucin, en el que se puede pensar como la activacin de un objeto.
      Un objeto individual se caracteriza por su tipo de objeto, que
      determina su accin cuando se ejecuta y su valor, que lo distingue de
      otro objeto del mismo tipo.

      La evaluacin de una expresin en estos trminos se convierte en la
      ejecucin secuencial de una serie de objetos (los objetos que
      representan la forma RPN de una expresin). Son necesarias dos
      construcciones para hacer la ejecucin coherente: una pila de objetos y
      un puntero del intrprete. La primera construccin proporciona un lugar
      del cual los objetos procedimiento pueden tomar sus argumentos y al
      cual pueden devolver sus objetos resultado. Una pila LIFO (Last In,
      First Out = Ultimo en Entrar, Primero en Salir) como la usada en Forth
      es ideal para este propsito y se incluye una pila as en RPL. El
      puntero del intrprete no es ms que un contador de programa que indica
      el siguiente objeto a ejecutar. El puntero del intrprete se debe
      distinguir del contador de programa de la CPU, que indica la siguiente
      instruccin de la CPU.

      Una expresin matemtica considerada como una secuencia de objetos
      sugiere una clasificacin adicional de objetos en atmicos o
      compuestos. Un objeto atmico es un objeto que no se puede separar en
      objetos independientes; son ejemplos un sencillo objeto de datos como 1 
      o 2 o quizs un objeto como * o + que se implementan normalmente en
      lenguaje mquina. Un objeto compuesto es una coleccin de otros
      objetos. En Forth, una palabra secundaria es un ejemplo de objeto
      compuesto. RPL proporciona al menos tres tipos de objetos compuestos:
      secundarios, que son procedimientos definidos como una secuencia de
      objetos sin restriccin; simblicos, que son secuencias de objetos que
      deben equivaler lgicamente a expresiones algebraicas; y listas, que
      contienen objetos reunidos para cualquier propsito lgico que no sea
      la ejecucin secuencial.

      El punto final en esta breve derivacin de las matemticas-a-RPL es
      observar que la definicin de objetos compuestos nos lleva al concepto
      de interpretacin entrelazada y de una pila de retornos. Esto es, es
      fcil imaginar en el ejemplo, que el nombre del objeto x podra
      representar un objeto compuesto que a su vez representa otra expresin.
      En ese caso, se podra esperar que la ejecucin de x haga saltar al
      puntero del intrprete a la secuencia de objetos referenciada por x,
      mientras que la posicin del objeto que sigue a x en la original se
      almacena de modo que la ejecucin pueda luego volver all. Este proceso
      debe poderse repetir indefinidamente, por lo que RPL proporciona una
      pila LIFO para los objetos de retorno.

      La introduccin precedente podra, en algunos aspectos, haber sido
      tambin una introduccin para la derivacin de Forth, si se ignoran
      cuestiones de aritmtica de punto flotante versus enteros. En concreto,
      ambos sistemas usan la interpretacin entrelazada y una pila de datos
      LIFO para el intercambio de objetos. Sin embargo, hay varias
      diferencias importantes entre Forth y RPL:





                                  Pgina 4




         +  RPL soporta la ejecucin entrelazada tanto indirecta como directa
            de una manera completamente uniforme.

         +  RPL soporta la colocacin dinmica de sus objetos.

         +  El cdigo RPL es, en general, completamente relocalizable.


      2.3   Definiciones Formales


      Esta seccin presentar las definiciones abstractas de RPL que son
      independientes de cualquier CPU o implementacin concretas.

      La estructura fundamental en RPL es el objeto. Cualquier objeto est
      formado por un par: la direccin del prlogo y el cuerpo del objeto.

                        +---------------+
                        |  -> Prlogo   |
                        +---------------+
                        |     Cuerpo    |
                        +---------------+

      Las dos partes estn contiguas en memoria con la parte de la direccin
      del prlogo en la memoria inferior. La direccin del prlogo es la de
      una rutina en cdigo mquina que ejecuta el objeto; el cuerpo son datos
      usados por el prlogo. Los objetos se clasifican por tipo; cada tipo se
      asocia con un prlogo nico. As los prlogos sirven para el doble
      propsito de ejecutar un objeto y de identificar su tipo. 

      Un objeto o es atmico o es compuesto. Un objeto compuesto o es nulo o
      no es nulo; un compuesto que no es nulo tiene una cabeza que es un
      objeto y una cola que es un compuesto.

      Adems de ejecutarse, todos los objetos RPL se pueden copiar, comparar,
      incluir en objetos compuestos y saltarse. La ltima propiedad implica
      que la longitud en memoria de cualquier objeto est predeterminada o se
      puede calcular a partir del objeto. En los objetos atmicos tales como
      los nmero reales, el tamao es fijo. En los objetos atmicos ms
      complicados como una formacin numrica, el tamao se puede calcular a
      partir de las dimensiones de la formacin que se almacenan en el cuerpo
      del objeto formacin. (Las formaciones RPL no son compuestos -- los
      elementos no tienen prlogos individuales y por tanto, no son objetos).
      Los objetos compuestos pueden incluir un campo longitud o pueden
      terminar con un objeto marcador.

      Un puntero es una direccin en el espacio de memoria de la CPU y puede
      ser un puntero de posicin o un puntero de objeto. Un puntero de
      posicin direcciona cualquier parte de la memoria, mientras que un
      puntero de objeto apunta a un objeto, especficamente al puntero de
      posicin del prlogo al principio de un objeto.




   





                                  Pgina 5




      RPL requiere, adems de los contadores de programa de la CPU, cinco
      variables para su funcionamiento fundamental:

         +  El puntero del intrprete I.

         +  El puntero del objeto actual O.

         +  El puntero de la pila de datos D.

         +  El puntero de la pila de retornos R.

         +  La cantidad de memoria libre M.


      En la definicin ms general de RPL, I es un puntero de objeto que
      apunta al objeto compuesto que est en la cima de una pila de objetos
      compuestos llamada "runstream". R apunta al resto de la pila
      "runstream". En las implementaciones prcticas, esta definicin se
      simplifica permitiendo que I apunte a cualquier objeto embebido en un
      compuesto, mientras que R es un puntero de posicin que apunta a la
      cima de una pila de punteros de objeto, cada uno de los cuales apunta a
      un objeto embebido.

      En RPL es fundamental que los objetos se puedan ejecutar directa o
      indirectamente con resultados equivalentes. Esto significa que un
      objeto se puede representar en cualquier sitio por un puntero al objeto
      as como tambin por el objeto mismo.


      2.4   Ejecucin


      La ejecucin de un objeto RPL consiste en la ejecucin por la CPU del
      prlogo del objeto, donde el cdigo del prlogo puede acceder al cuerpo
      del objeto mediante el puntero de objeto O. La ejecucin del puntero de
      objeto es la ejecucin por la CPU del destinatario del puntero. Esta
      ejecucin interpretativa se controla por el interpretador interno o
      bucle interno, quin determina la secuencia de objetos/punteros de
      objeto a ejecutar.

      Los objetos RPL se ordenan por sus propiedades generales de ejecucin
      en tres clases:

      *  Los objetos que simplemente se devuelven ellos mismos a la pila de
      datos cuando se ejecutan se llaman objetos de la clase datos. Son
      ejemplos los nmeros reales, las cadenas de caracteres y las
      formaciones.

      *  Los objetos que sirven de referencia a otros objetos se llaman
      objetos de la clase identificador. RPL define tres tipos de objetos de
      clase identificador: identificador (nombre global), identificador
      temporal (nombre local) y puntero ROM (nombre XLIB)

      *  Los objetos que contienen cuerpos a los que puede pasar el flujo de
      la ejecucin se llaman objetos de la clase procedimiento. Hay tres
      tipos de objetos de la clase procedimiento: programas (tambin llamados
      "secundarios" o una "definiciones colon" en la terminologa Forth),
      objetos cdigo y objetos cdigo primitiva.



                                  Pgina 6







      El bucle interno RPL y el diseo de prlogos permite la ejecucin
      directa e indirecta de objetos indistintamente (nota: hay una solicitud
      de patente por los conceptos descritos a continuacin). El bucle
      interno consta del siguiente pseudo-cdigo:

                             O = [I]
                             I = I + delta
                             PC = [O] + delta

      donde [x] significa el contenido de la direccin x y "delta" es el
      tamao de una direccin de memoria. Este bucle es el mismo que en
      Forth, excepto que la ejecucin de la CPU salta a [O]+delta en vez de a
      [O]. Esto es as porque todos los prlogos de RPL empiezan con su
      propia direccin, lo que es la caracterstica que hace posible la
      ejecucin directa adems de la indirecta. Los prlogos se parecen a
      esto:
       

   PROLOG   ->PROLOG                            Auto-direccin
            IF O + delta != PC THEN GOTO REST   Test para ejecucin directa
            O = I - delta                       Corrige O
            I = I + len                         Corrige I
   REST     (resto del prlogo)

       Aqu "len" es el tamao (longitud) del cuerpo del objeto.

      Cuando se ejecuta un objeto directamente, el bucle interno no pone O ni
      I correctamente. Sin embargo, el prlogo sabe si se est ejecutando
      directamente comparando la direccin del PC con O y puede actualizar
      las dos variables en consecuencia. El prlogo es tambin responsable de
      preservar la interpretacin entrelazada incluyendo un retorno al bucle
      interno al finalizar.
 
      Esta interpretacin flexible es intrnsecamente ms lenta que la
      ejecucin slo-indirecta (como Forth), debido al gasto necesario para
      hacer la comprobacin de directo/indirecto. En las implementaciones
      prcticas del RPL, es posible desplazar casi por completo este gasto al
      caso de la ejecucin directa, de modo que la penalizacin en la
      ejecucin del caso indirecto sea despreciable, incluyendo objetos
      primitivas en lenguaje ensamblador que nunca se ejecutan directamente.
      El truco est en reemplazar el ltimo paso del bucle interno con PC =
      [O] al modo Forth y, para los prlogos de los objetos ejecutables
      directamente, reemplazar la auto-direccin al principio de cada prlogo
      con una seccin de cdigo ejecutable de tamao igual a "delta". Los
      cdigos compilados de esta seccin deben tambin ser la direccin de un
      meta-prlogo que maneje el caso de la ejecucin directa. En las
      implementaciones con la CPU Saturno, la seccin de cdigo consiste en
      la instruccin M=M-1 (decrementar la memoria disponible es comn a
      todos los prlogos de objetos ejecutables directamente) ms una
      instruccin NOP de relleno para alcanzar el tamao "delta".








                                  Pgina 7





      La virtud de la ejecucin directa es que permite el manejo sencillo de
      los objetos sin nombre que se crean durante la ejecucin. En el curso
      de las manipulaciones algebraicas simblicas es comn crear, usar y
      descartar cualquier nmero de resultados temporales intermedios; la
      necesidad de compilar y almacenar estos objetos con alguna forma de
      nombre para la referencia indirecta y luego descompilarlos para
      recuperar memoria, hara inmanejable todo el proceso. En RPL tales
      objetos se pueden colocar en la pila, copiar, embeber en objetos
      compuestos, ejecutar y borrar. Por ejemplo, un objeto compuesto que
      representa la expresin x + y se puede aadir a un segundo objeto que
      representa 2z, devolviendo el objeto resultante x + y + 2z; ms aun,
      cualquiera de estos objetos se podran incluir en un objeto programa
      para llevar a cabo la adicin repetidamente.

      Aunque RPL es fundamentalmente un lenguaje sufijo sin sintaxis en el
      que los procedimientos toman sus argumentos de la pila y devuelven los
      resultados a la pila, proporciona operaciones que operan en el
      "runstream" para proporcionar operaciones prefijo y para permitir
      alteraciones en la ejecucin entrelazada normal. La primera entre las
      operaciones en el "runstream" es la operacin de encomillar, que toma
      el siguiente objeto del "runstream" y lo sube (coloca) en la pila de
      datos para posponer su ejecucin. El propsito de esta operacin es
      similar al QUOTE de Lisp, pero toma su nombre RPL, ' (tick), de su
      equivalente Forth. RPL tambin tiene operaciones para subir y bajar
      objetos de la pila de retornos. (Sin embargo, los parmetros de los
      bucles DO loop no se almacenan en la pila de retornos, sino que se usa
      en su lugar un entorno especial).

      2.4.1 EVAL  Un objeto en la pila de datos se puede ejecutar
      indirectamente mediante la palabra RPL EVAL, que baja un objeto de la
      pila y ejecuta su prlogo. El objeto del sistema EVAL se debe
      distinguir del comando del RPL de Usuario EVAL. Este ltimo es
      equivalente al EVAL del sistema excepto por las listas, los objetos
      simblicos y los objetos etiquetados. Con un objeto etiquetado el EVAL
      de Usuario ejecuta el objeto contenido en el cuerpo del objeto
      etiquetado. Con las listas y los simblicos, el EVAL de Usuario los
      enva a la palabra del sistema COMPEVAL, que ejecuta el objeto como si
      fuera un programa (ver ms abajo).
   





















                                  Pgina 8





      2.4.2 Objetos de la Clase Datos  Los tipos de objetos en esta clase
      son:
            Objeto Entero Binario   (nota: el entero binario del RPL de
                                    Usuario es realmente un objeto cadena hex
                                    en trminos del RPL del sistema).
            Objeto Real
            Objeto Real Extendido
            Objeto Complejo
            Objeto Complejo Extendido
            Objeto Formacin
            Objeto Formacin Encadenada
            Objeto Cadena de Caracteres
            Objeto Cadena Hex
            Objeto Carcter
            Objeto Grfico
            Objeto Unidad
            Objeto Lista
            Objeto Simblico ("objeto algebraico")
            Objeto Datos de Biblioteca
            Objeto Directorio
            Objeto Etiquetado
            Objeto Externo

      Todos los objetos de la clase de datos tienen la propiedad que, cuando
      se ejecutan, simplemente se colocan ellos mismos en la cima de la pila
      de datos.


      2.4.2 Objetos de la Clase Identificador   Los tipos de objetos en esta
      clase son:

            Objeto Puntero ROM (nombre XLIB)
            Objeto Identificador (nombre global)
            Objeto Identificador Temporal (nombre local)

      Los objetos en la clase identificador comparten la propiedad de servir
      para proporcionar referencias para otros objetos. Los objetos
      identificadores representan la resolucin de las variables globales y
      los Objetos Punteros ROM representan la resolucin de los comandos
      almacenados en bibliotecas. Los objetos identificadores temporales, por
      otro lado, proporcionan referencias para los objetos temporales en
      entornos temporales.

      La ejecucin de un objeto puntero ROM (por el prlogo DOROMP) conlleva
      localizar y luego ejecutar la parte del objeto ROM-WORD referenciada.
      La no localizacin es una condicin de error.

      La ejecucin de un objeto identificador (por un prlogo DOIDNT)
      conlleva localizar y luego ejecutar la parte del objeto variable global
      referenciada. La no localizacin devuelve el objeto identificador
      mismo.

      La ejecucin de un objeto identificador temporal (por el prlogo DOLAM)
      conlleva localizar el objeto temporal referenciado y subirlo a la pila
      de datos. La no localizacin es una condicin de error.





                                  Pgina 9






      2.4.4 Objetos de la Clase Procedimiento   Los tipos de objeto en esta
      clase son:

            Objeto Cdigo
            Objeto Cdigo Primitiva
            Objeto Programa

      Los objetos de la clase procedimiento comparten la propiedad de la
      ejecutabilidad, esto es, la ejecucin de un objeto de la clase
      procedimiento implica pasar el control al procedimiento ejecutable o al
      cdigo asociado con el objeto.

      Los objetos cdigo contienen secuencias en lenguaje ensamblador para su
      ejecucin directa por la CPU, pero por lo dems son objetos normales,
      relocalizables. Los objetos cdigo primitiva no tienen ningn prlogo
      en el sentido usual; el campo direccin del prlogo apunta directamente
      al cuerpo del objeto que contiene una secuencia en lenguaje
      ensamblador. Estos objetos slo pueden existir en ROM permanente y no
      se pueden ejecutar nunca directamente. Cuando se ejecuta un objeto
      cdigo o un objeto cdigo primitiva, se pasa el control (ajustando el
      PC) al conjunto de instrucciones en lenguaje mquina contenidas en el
      cuerpo del objeto. En el caso de un objeto cdigo primitiva, esta
      transferencia de control la hace el mecanismo de ejecucin (EVAL o el
      bucle interno) mismo. En el caso de un objeto cdigo, el prlogo pasa
      el control poniendo el PC al principio de la seccin de lenguaje
      mquina contenida en el cuerpo del objeto. Observa de nuevo que el
      prlogo de un objeto cdigo primitiva (que es su cuerpo) no necesita
      contener la lgica para comprobar si la ejecucin es directa o
      indirecta (ni contener cdigo para actualizar I o O) ya que, por
      definicin, nunca se ejecuta directamente.

      La ejecucin de un programa es la ejecucin secuencial de los objetos y
      punteros de objeto que comprenden el cuerpo del programa. La ejecucin
      es entrelazada por cuanto los objetos en un programa pueden ser a su
      vez secundarios o punteros a secundarios. Cuando el bucle interno se
      encuentra un programa embebido lo ejecuta antes de reanudar la
      ejecucin del actual.

      El final de un programa est marcado con el objeto SEMI (de "semicolon" 
      (punto y coma en ingls) -- un ";" es el delimitador de terminacin
      reconocido por el compilador RPL para marcar el fin de la definicin de
      un programa). La ejecucin de SEMI baja el puntero de objeto de la cima
      de la pila de retornos y contina la ejecucin en ese punto.

      2.4.5 Esquivar Objeto y SEMI  Una de las premisas bsicas del RPL es
      que cualquier objeto RPL que se pueda ejecutar directamente (lo que
      incluye todos los tipos de objetos excepto los objetos cdigo
      primitiva) deben ser esquivables, o sea, deben tener una estructura que
      permita esquivarlos. El salto de objetos se da por todo el sistema RPL
      pero sobre todo durante la ejecucin directa por el bucle interno
      cuando el puntero del intrprete I debe apuntar al siguiente objeto
      despus del que se est ejecutando directamente.







                                 Pgina 10





      Existen tanto objetos RPL como utilidades para realizar este funcin de
      saltarse objetos. Adems, los objetos se tienen que esquivar a s
      mismos cuando se ejecutan directamente. El mecanismo de esquivar los
      objetos atmicos es sencillo y claro ya que el tamao del objeto o bien
      se sabe o es fcilmente calculable. En el caso de los objetos
      compuestos (programa, lista, unidad, simblico) el tamao no se puede
      calcular fcilmente y la funcin de esquivar aqu es algo ms
      complicada, usndose una recursin implcita. Estos objetos compuestos
      no llevan una informacin conocida del tamao o que sea fcilmente
      calculable y por tanto deben tener un delimitador en la cola, a saber,
      un puntero de objeto al objeto cdigo primitiva SEMI. Observa que SEMI
      desempea una funcin explcita en el objeto programa (el objeto
      compuesto clase procedimiento); en los objetos compuestos de la clase
      datos (listas, unidades y objetos simblicos), slo sirve como
      delimitador de la cola.


      2.4.6 Punteros RPL   Un puntero es una direccin y puede ser o bien un
      puntero de posicin (de localizacin) o un puntero de objeto. Un
      puntero de posicin direcciona cualquier segmento del mapa de memoria
      mientras que un puntero de objeto direcciona especficamente un objeto.
      Observa que, por ejemplo, la parte de direccin del prlogo de un
      objeto es un puntero de posicin.
   
      2.5   Manejo de la Memoria

      La uniformidad de la ejecucin directa e indirecta no solo significa
      que los objetos as como los punteros de objeto se pueden incluir en el
      flujo de la ejecucin, sino tambin que los punteros de objeto pueden
      reemplazar lgicamente a los objetos. En particular, las pilas RPL de
      datos y de retornos son explcitamente pilas de punteros de objeto.
      Esto significa, por ejemplo, que un objeto en la pila de datos se puede
      copiar (con el DUP p.ej.) al costo de solo "delta" bytes de memoria,
      independientemente del tamao del objeto. Es ms, las duplicacin y
      otras operaciones similares de la pila son muy rpidas.

      Desde luego, los objetos referenciados en las pilas deben existir en
      algn lugar de la memoria. Muchos, incluyendo todos los objetos del
      sistema que proporcionan el manejo del sistema y un lenguaje de
      aplicacin, estn definidos en ROM y se pueden referenciar con un
      puntero sin ninguna otra implicacin a tener en cuenta. Los objetos
      creados en RAM pueden existir en dos lugares. Aquellos que no tienen
      nombre se almacenan en un rea de objetos temporales, donde se
      mantienen mientras estn referenciados por un puntero en cualquier
      sitio del sistema (esto implica que si un objeto temporal se mueve, se
      deben actualizar todos los punteros que haya apuntando a l). Nombrar
      un objeto es almacenarlo como un par con un campo de nombre en una
      lista encadenada llamada el rea de objetos de usuario. Estos objetos
      se mantienen indefinidamente, hasta que se borran explcitamente o son
      reemplazados. Un objeto con nombre se accede por medio de un objeto
      identificador, que consiste en un objeto con un campo de nombre como su
      cuerpo. La ejecucin de un identificador provoca la bsqueda, en el
      rea de objetos de usuario, de un objeto almacenado con el mismo
      nombre, que entonces se ejecuta. 






                                 Pgina 11





      Esta resolucin en tiempo de ejecucin es de por s ms lenta que la
      resolucin durante el tiempo de compilacin usada por los objetos ROM,
      pero permite un sistema dinmico y flexible en el que no importa el
      orden en que se compilan los objetos.

      El proceso de nombrar objetos almacenndolos con nombres en el rea de
      objetos de usuario se ve aumentado por la existencia de los entornos
      locales, en los que los objetos se pueden unir a nombres (variables
      lambda) que son locales al procedimiento que se ejecuta actualmente. La
      unin se abandona cuando el proceso completa su ejecucin. Esta
      caracterstica simplifica las manipulaciones complicadas de la pila
      permitiendo que los objetos de la pila tengan nombres y se referencien
      entonces por el nombre dentro del alcance de un procedimiento de
      definicin.

      RPL permite que cualquier objeto almacenado en el rea de objetos del
      usuario se pueda borrar sin corromper nada del sistema. Esto requiere
      ciertas convenciones de diseo:

         +  Cuando se almacena un objeto RAM en le rea de objetos de
            usuario, se almacena una copia nueva del objeto, no un puntero al
            objeto.

         +  Los punteros a objetos RAM no estn permitidos en los objetos
            compuestos. Cuando se crea un objeto compuesto a partir de
            objetos de la pila, los objetos RAM se copian y embeben
            directamente en el compuesto. Cuando un objeto almacenado se
            representa por su nombre en un compuesto, es el objeto
            identificador el que se embebe, no un puntero de posicin como en
            Forth.

         +  Si un objeto almacenado est siendo referenciado por cualquier
            puntero en las pilas en el momento en que se borra, se copia al
            rea de objetos temporales y se actualizan en consecuencia todos
            los punteros que le apuntaban. Esto significa que la memoria
            asociada con un objeto no se recupera hasta que se elimine la
            ltima referencia a l.

      El uso de objetos temporales con mltiples referencias significa que un
      objeto temporal puede que no se borre de la memoria inmediatamente
      cuando se elimine solo una referencia a l. En las actuales
      implementaciones de RPL, no se realiza ninguna recuperacin de memoria
      hasta que el sistema se queda sin memoria (M=0), en cuyo momento se
      borran todos los objetos no referenciados del rea de objetos
      temporales. El proceso, llamado "recogida de basura" puede durar
      bastante tiempo, por lo que la ejecucin del RPL no procede de modo
      uniforme.

      De la discusin anterior se ve claro que RPL no es tan rpido en
      general como Forth debido a los gastos extra en la interpretacin y al
      esquema tan elaborado de manejo de memoria. Mientras que la mxima
      velocidad de ejecucin es siempre deseable, el diseo del RPL enfatiza
      su papel como un lenguaje de control matemtico interactivo en el que
      la flexibilidad, facilidad de uso y la capacidad de manipulacin de
      informacin de procedimiento son de la mxima importancia. En muchos
      casos, estos atributos del RPL conducen a una resolucin ms rpida de
      los problemas que en Forth, que se ejecuta ms rpido pero es ms
      difcil de programar.


                                 Pgina 12




      
      RPL tambin proporciona objetos que son intermedios entre aquellos que
      estn fijos en ROM y aquellos que se mueven en la RAM. Una biblioteca
      es una coleccin de objetos, organizados en una estructura permanente
      que permite una resolucin en el tiempo de anlisis y en el tiempo de
      ejecucin por medio de tablas incluidas en la biblioteca. Un nombre
      XLIB es un objeto de la clase identificador que contiene un nmero de
      biblioteca y un nmero de un objeto dentro de la biblioteca. La
      ejecucin de un nombre XLIB ejecuta el objeto almacenado. Las
      identidades y la posicin de las bibliotecas se determinan en la
      configuracin del sistema. Una biblioteca en particular se puede
      asociar con su propio directorio RAM, de modo que, por ejemplo, una
      biblioteca puede contener frmulas permanentes para las que se
      mantienen en RAM los valores de sus variables.


      2.6   RPL de Usuario y RPL del Sistema

      No hay ninguna diferencia fundamental entre el lenguaje de programacin
      de la HP 48, al que llamaremos "RPL de usuario" y el "RPL del sistema"
      en el que est implementada la funcionalidad de la HP 48. Los programas
      en el lenguaje de usuario son ejecutados por el mismo bucle interno del
      intrprete que los programas del sistema, con la misma pila de
      retornos. La pila de datos que se muestra en la HP 48 es la misma que
      la usada por los programas del sistema. La diferencia entre el RPL de
      usuario y el RPL del sistema es solo una cuestin de amplitud: el RPL
      de usuario es un subconjunto del RPL del sistema. El RPL de usuario no
      proporciona acceso directo a todos los tipos de objetos de la clase de
      datos disponibles; el uso de los procedimientos incorporados est
      limitado a aquellos proporcionados como comandos.

      Un "comando" es un objeto de la clase procedimiento almacenado en una
      biblioteca, junto con una cadena de texto que sirve de nombre del
      comando. El nombre se usa para compilar y descompilar el objeto. Cuando
      el analizador de la lnea de comandos encuentra un texto en la lnea de
      comandos igual al nombre de un comando, compila un puntero de objeto si
      el comando est en una biblioteca en la ROM permanente de la HP 48. De
      lo contrario compila el correspondiente nombre XLIB. Tambin, los
      objetos comando incorporados estn precedidos en ROM por un campo de
      seis nibbles que es el cuerpo de un nombre XLIB. Cuando el
      descompilador encuentra un puntero de objeto, busca este campo en el
      ROM al frente del objeto; si encuentra un campo vlido, usa entonces la
      informacin que hay all para localizar el texto del nombre del comando
      a mostrar. Si no, descompila el propio objeto.

      Los comandos se distinguen de otros objetos procedimiento por ciertas
      convenciones en su diseo. Estructuralmente, todos los comandos son
      objetos programa, siendo el primer objeto dentro de ellos uno de los
      objetos "de despacho" (de envo) del sistema CK0, CK1&Dispatch,
      CK2&Dispatch, CK3&Dispatch, CK4&Dispatch y CK5&Dispatch (ver la seccin
      13). CK0, que lo usan los comandos sin ningn argumento, puede ir
      seguido de cualesquiera objetos adicionales. CK1&Dispatch .. 
      CK&Dispatch deben ir seguidos de una secuencia de pares de objetos; el
      primero de cada par identifica una combinacin de tipos de argumentos
      de la pila y el segundo especifica el objeto a ejecutar para cada
      combinacin correspondiente. El ltimo par est seguido del objeto
      marcador de fin de programa (SEMI).




                                 Pgina 13






      Las otras convenciones para los objetos comando gobiernan su
      comportamiento. En concreto, deberan:

      *  eliminar cualquier objeto temporal de la pila, retornando slo los
         resultados especificados;

      *  hacer cualquier comprobacin de mrgenes necesaria para asegurar que
         no ocurran errores que puedan causar desastres;

      *  restaurar los modos de la HP48 a sus estados originales, a menos que
         el comando sea especficamente para cambiar un modo.

      El gasto que implican estas convenciones estructurales y de
      comportamiento impone una pequea penalizacin en la ejecucin. Sin
      embargo, la principal ventaja del RPL del sistema sobre el RPL del
      usuario, la velocidad de ejecucin, viene simplemente del conjunto ms
      grande de procedimientos disponibles en el RPL del sistema, del acceso
      a la rpida aritmtica binaria y del control mejorado sobre los
      recursos del sistema y del flujo de ejecucin.


      2.7   Programacin en RPL del Sistema

      Escribir programas en RPL del sistema no es diferente, en principio,
      que en RPL de usuario; la diferencia est en la sintaxis y en la
      amplitud del compilador. Para el RPL de usuario, el compilador es el
      ENTER de la lnea de comandos, cuya lgica est documentada en los
      manuales del propietario. Para el RPL del sistema desarrollado en un
      PC, el compilador tiene varias partes. El anlogo inmediato del
      analizador de la lnea de comandos es el programa RPLCOMP, que analiza
      y traduce el texto del cdigo fuente al lenguaje ensamblador del
      Saturno. (La sintaxis usada por RPLCOMP se describe en RPLCOMP.DOC). La
      salida de RPLCOMP se pasa al programa ensamblador SASM, que genera el
      cdigo objeto ensamblado. El programa SLOAD resuelve las referencias de
      smbolos en la salida de SASM, devolviendo finalmente el cdigo
      ejecutable adecuado para cargarlo en la HP 48. Se pueden recoger los
      objetos individuales en un directorio de la HP 48 que se vuelve a
      transferir de nuevo al PC, donde el programa USRLIB puede transformar
      el directorio en un objeto biblioteca. (Sera deseable la creacin de
      una biblioteca directamente en el PC, pero el programa para hacer esto
      no est disponible aun).

      A modo de ilustracin, considera un hipottico proceso del desarrollo
      de un proyecto que dar lugar a un objeto biblioteca construido con la
      herramienta USRLIB. La biblioteca contendr un solo comando, BASKET,
      que calcula los factores de tejido de una cesta segn varios parmetros
      de entrada. BASKET se debe disear con la estructura descrita
      anteriormente para los comandos. Adems, supn que BASKET llama a otros
      programas que no sern accesibles al usuario. Para conseguir esto, se
      compilan los objetos en el PC, luego se cargan en la HP 48 en un
      directorio comn, almacenados como BASKET, B1, B2, ... , donde las
      ltimas variables contienen las subrutinas. El directorio se carga al
      PC, donde se le aplica USRLIB con la directiva que dice que B1, B2, ...
      han de ser "ocultos".





                                 Pgina 14






      No hay ninguna obligacin de que el programa producido con el
      compilador RPL se deba presentar en un objeto biblioteca - si toda la
      aplicacin se puede escribir dentro de un solo programa, mucho mejor. A
      medida que los programas crecen ms all de un cierto nivel razonable
      de complejidad, esto se hace ms difcil y el enfoque de un objeto
      biblioteca con mltiples variables es ms fcil de manejar.


         1. Crea el fichero fuente en el PC usando tu editor de texto
            favorito. El nombre del fichero del programa fuente deber tener
            la extensin ".s", tal como "prog.s". Usa el compilador
            RPLCOMP.EXE para producir el fichero ensamblador del Saturno
            "prog.a".

         2. Usa el ensamblador del Saturno SASM.EXE para ensamblar el
            programa y producir un fichero de salida "prog.o"

         3. Usa el cargador del Saturno SLOAD.EXE para resolver las llamadas
            de tu programa al sistema operativo de la HP 48. Los ficheros de
            salida de SLOAD.EXE pueden tener cualquier nombre, pero se usa a
            menudo la extensin ".ol".

         4. Carga el fichero final (usa transferencia binaria!) en la HP 48
            y prueba el funcionamiento de tu cdigo.

         5. Carga el directorio que contiene uno o ms objetos al PC y usa
            USRLIB.EXE para convertirlo en una biblioteca.
































                                 Pgina 15





      2.8   Programa de Ejemplo en RPL


      Para familiarizarse con el proceso de producir un programa escrito en
      RPL interno, considera el siguiente ejemplo, al que llamaremos TOSET.


      2.8.1 El Fichero Fuente

      Este programa elimina los objetos duplicados de una lista
      descomponiendo la lista en una serie de objetos en la pila, creando una
      nueva lista vaca y colocando los objetos de la pila en la nueva lista
      si son nicos.

       * ( {lista} --> {lista}' )
       ASSEMBLE
               NIBASC  /HPHP48-D/
       RPL
       ::
         CK1NOLASTWD                   ( *Req. 1 argumento* )
         CK&DISPATCH0 list
           ::
             DUPNULL{}? ?SEMI          ( *Sale si la lista est vaca* )
             INNERCOMP                 ( objn ... obj1 #n )
             reversym                  ( obj1 ... objn #n )
             NULL{} SWAP               ( obj1 ... objn {} #n )
             ZERO_DO (DO)
               SWAP                    ( obj1 ... objn-1 {} objn )
               apndvarlst              ( obj1 ... objn-1 {}' )
             LOOP
          ;
       ;


      La primera lnea es un comentario que muestra las condiciones de
      entrada y salida del programa. Los comentarios se denotan por un
      asterisco (*) en la primera columna o entre parntesis. Cada
      programador tiene su propio estilo para los comentarios. El estilo
      mostrado aqu es que los objetos se muestran con el nivel uno de la
      pila a la derecha. El texto se incluye entre asteriscos.

      La secuencia

       ASSEMBLE
               NIBASC  /HPHP48-D/
       RPL

      es un comando para el ensamblador que incluye la cabecera para la
      transferencia binaria de datos desde el PC a la HP48. Se incluye aqu
      por simplicidad, pero podra ser incluida desde otro fichero por el
      cargador.

      El primer comando, CK1NOLASTWD, exige que la pila contenga al menos un
      objeto y borra la posicin de la ram que almacena el nombre del comando
      actual. Esto es importante porque no querrs atribuir los errores que
      se puedan producir en este programa a la ltima funcin que gener un
      error.



                                 Pgina 16







      El segundo comando, CK&DISPATCH0, lee una estructura de la forma

               tipo accin
               tipo accin
               ...

      para decidir que accin tomar basndose en el TYPE (tipo) del objeto
      presentado. Si el tipo de objeto en el nivel 1 no tiene una entrada en
      la tabla, se generar el error "Bad Argument Type" ("Tipo de Argumento
      Incorrecto"). En este ejemplo, slo se acepta un tipo de argumento, una
      lista, y la accin correspondiente es un secundario. Para saber ms de
      los comandos de chequeo de argumentos, ver el captulo "Chequeo de
      Argumentos"

      El comando DUPNULL{}? devuelve la lista y una bandera TRUE/FALSE
      (Cierto/Falso) que indica si la lista esta o no vaca. El comando ?SEMI
      sale del secundario si la bandera es TRUE (Cierto). 

      El comando INNERCOMP es una forma interna de la palabra de usuario
      LIST->. El nmero de objetos se devuelve al nivel uno como un entero
      binario (ver el captulo "Enteros Binarios").

      El comando "reversym" invierte el orden de #n objetos en la pila. Se
      usa aqu teniendo en cuenta el orden en que son colocados los objetos
      en una lista por "apndvarlst" que se describe luego.

      El comando ZERO_DO inicia un bucle contador. Este bucle procesar cada
      objeto de la lista original. El comando (DO) le dice a RPLCOMP que este
      es el principio del bucle, si no el comando LOOP se sealara como "sin
      emparejar".

      El comando "apndvarlst" aade un objeto a una lista si y slo si ese
      objeto no aparece ya en la lista.

      El comando LOOP termina el bucle. Para saber ms de los comandos de
      bucle, ver el captulo "Estructuras de Control de Bucles"






















                                 Pgina 17




      2.8.2 Compilar el Programa    Para compilar el programa para la HP 48,
      seguir estos pasos:

         1. Almacena el cdigo ejemplo en el fichero TOSET.S

         2. RPLCOMP TOSET.S TOSET.A

            Este comando compila el fuente RPL y produce un fichero fuente en
            ensamblador del Saturno.
         
         3. SASM TOSET.A

            Este comando ensambla el fichero fuente del Saturno para producir
            los ficheros TOSET.L y TOSET.O

         4. El fichero TOSET.M es un fichero de control del cargador que se
            parece a esto:

             TITLE Example           <-- Especifica el ttulo del listado
             OUTPUT TOSET            <-- Especifica el fichero de salida
             LLIST TOSET.LR          <-- Especifica el fichero de listados
             SUPPRESS XREF           <-- Suprime las referencias cruzadas
             SEARCH ENTRIES.O        <-- Lee las entradas de la HP 48
             REL TOSET.O             <-- Carga TOSET.o
             END

            Crea el fichero TOSET.M e invoca el cargador:

             SLOAD -H TOSET.M

      Comprueba el fichero TOSET.LR para ver si hay errores. Una referencia
      no resuelta (unresolved reference) apunta normalmente a un comando mal
      escrito. Carga ahora el fichero TOSET en la HP 48 y dale una
      oportunidad!

      Entra la lista { 1 2 2 3 3 3 4 }, evala TOSET y deberas obtener { 1 2
      3 4 }.
























                                 Pgina 18






      3. Estructuras de los Objetos


      Este captulo proporciona informacin adicional acerca de algunos tipos
      de objetos RPL soportados por la HP 48. Aunque la informacin es
      relevante principalmente para la programacin en cdigo mquina, un
      conocimiento de la estructura de los objetos puede, a menudo, ayudar a
      entender las consecuencias en la ejecucin y en la eficacia de la
      programacin en RPL.

      A menos que se diga explcitamente lo contrario, todos los campos
      definidos especficamente dentro del cuerpo de un objeto se supone que
      son de 5 nibbles, el ancho de las direcciones de la CPU.


      3.1   Tipos de Objetos

      3.1.1 Objeto Identificador

      Un objeto identificador es atmico, tiene el prlogo DOIDNT y un cuerpo
      que es una "forma Nombre ID".

                   +------------------+
                   |    -> DOIDNT     |  Direccin del Prlogo
                   +------------------+                     Objeto
                   | FORMA NOMBRE ID  |  Cuerpo             Identificador     
                   +------------------+

      Una "forma Nombre ID" es una secuencia de caracteres precedida por un
      campo contador de caracteres de un byte.

      Los objetos identificadores son, entre otras cosas, la resolucin en
      tiempo de compilacin de las variables globales.


      3.1.3 Objeto Identificador Temporal

      Un objeto identificador temporal es atmico, tiene el prlogo DOLAM y
      un cuerpo que es una forma Nombre ID

                   +------------------+
                   |     -> DOLAM     | Direccin del Prlogo  Objeto   
                   +------------------+                        Identificador
                   |  FORMA NOMBRE ID | Cuerpo                 Temporal
                   +------------------+

      Los objetos identificadores temporales proporcionan referencias con
      nombres para los objetos temporales unidos a los identificadores en la
      lista formal de parmetros de una estructura de variables temporales.










                                 Pgina 19






      3.1.3 Objeto Puntero ROM


      Un objeto puntero ROM, o nombre XLIB, es atmico, tiene el prlogo
      DOROMP y un cuerpo que es un identificador ROM-WORD. 

                   +------------------+
                   |   -> DOROMP      | Direccin del Prlogo
                   +------------------+                     Objeto 
                   |                  |                     Puntero
                   |  Identificador   | Cuerpo              ROM
                   |   de Comando     |
                   |                  |
                   +------------------+

      Los objetos punteros ROM son la resolucin en tiempo de compilacin de
      los comandos en bibliotecas mviles. Un identificador identificador de
      comando es un par de campos de 12 bits: el primer campo es un nmero de
      ID de biblioteca y el segundo campo es el nmero ID del comando dentro
      de la biblioteca.


      3.1.4 Objeto Entero Binario

      Un objeto entero binario es atmico, tiene el prlogo DOBINT y un
      cuerpo que es un nmero de 5 nibbles.

                   +------------------+
                   |   -> DOBINT      | Direccin del Prlogo
                   +------------------+
                   |                  |             Objeto 
                   |      Nmero      | Cuerpo      Entero 
                   |                  |             Binario
                   +------------------+

      El uso de este tipo de objetos es para representar enteros binarios
      cuya precisin es equivalente a una direccin de memoria.


      3.1.5 Objeto Nmero Real

      Un objeto nmero real es atmico, tiene el prlogo DOREAL y un cuerpo
      que es un nmero en coma flotante de precisin simple (o, abreviando,
      un nmero real).

                   +-----------------+
                   |  -> DOREAL      | Direccin del Prlogo
                   +-----------------+
                   |                 |
                   | Nmero de Coma  |            Objeto Nmero
                   | Flotante de     | Cuerpo     Real
                   | Precisin Simple|
                   |                 |
                   +-----------------+





                                 Pgina 20







      Uno de los usos de este tipo de objetos es representar nmeros de coma
      flotante empaquetados (ocho bytes) en un sistema Saturno y, en esta
      aplicacin, el cuerpo del objeto consiste en 16 nibbles BCD como sigue:

              (mem baja)      EEEMMMMMMMMMMMMMMMS

      donde S es el signo numrico (0 para no negativo y 9 para negativo),
      MMMMMMMMMMMM son los 12 dgitos de la mantisa con una coma implcita
      entre el primero y segundo dgitos y el primer dgito distinto de cero
      si el nmero no es cero y EEE es el exponente en forma de complemento a
      diez (-500 < EEE < 500).


      3.1.6 Objeto Nmero Real Extendido

      Un objeto nmero real extendido es atmico, tiene el prlogo DOEREL y
      un cuerpo que es un nmero de coma flotante de precisin extendida (o,
      abreviando, real extendido).

                   +-----------------+
                   |  -> DOEREL      | Direccin del Prlogo
                   +-----------------+
                   |                 |              Objeto 
                   | Nmero de Coma  |              Nmero Real
                   | Flotante de     |              Extendido
                   | Precisin       | Cuerpo
                   | Extendida       |
                   |                 |
                   +-----------------+

      Uno de los usos de este tipo de objetos es representar nmeros de coma
      flotante sin empaquetar (10.5 bytes) en un sistema Saturno y, en este
      aplicacin, el cuerpo del objeto puede consistir en 21 nibbles BCD como
      sigue:

             (mem baja)     EEEEEMMMMMMMMMMMMMMMS

      donde S es el signo numrico (0 para no negativo, 9 para negativo),
      MMMMMMMMMMMMMMM es una mantisa de 15 dgitos con una coma decimal
      implcita entre el primer y el segundo dgitos y el primero distinto de
      cero si el nmero no es cero y EEEEE es el exponente en forma de
      complemento a diez (-50000 < EEEEE < 50000).
















                                 Pgina 21






      3.1.7 Objeto Nmero Complejo

      Un objeto nmero complejo es atmico, tiene el prlogo DOCMP y un
      cuerpo que es un par de nmeros reales.

                   +------------------+
                   |    -> DOCMP      | Direccin del Prlogo
                   +------------------+
                   |                  |            Objeto 
                   |   Nmero Real    |            Complejo
                   |    ---------     | Cuerpo
                   |   Nmero Real    |
                   |                  |
                   +------------------+

       
      Este tipo de objetos se usan para representar nmeros complejos de
      precisin simple, donde la parte real se interpreta como el primer
      nmero real del par.


      3.1.8 Objeto Nmero Complejo Extendido

      Un objeto nmero complejo extendido es atmico, tiene el prlogo DOECMP
      y un cuerpo que es un par de nmeros reales extendidos.

                   +------------------+
                   |    -> DOECMP     | Direccin del Prlogo
                   +------------------+
                   |                  |
                   |   Nmero Real    |
                   |    Extendido     |              Objeto  
                   |    ----------    | Cuerpo       Nmero Complejo
                   |   Nmero Real    |              Extendido
                   |    Extendido     |
                   |                  |
                   +------------------+

      Este tipo de objetos se usa para representar nmeros complejos de
      precisin extendida de la misma manera que un objeto complejo.



















                                 Pgina 22






      3.1.9 Objeto Formacin

      Un objeto Formacin es atmico, tiene el prlogo DOARRY y un cuerpo que
      es una coleccin de los elementos de la formacin. El cuerpo tambin
      incluye un campo longitud (indicando la longitud del cuerpo), un
      indicador de tipo (indicando el tipo de objetos de sus elementos), un
      campo contador de dimensiones y campos de longitud para cada dimensin.

                   +------------------+
                   |  -> DOARRY       | Direccin del Prlogo
                   +------------------+
                   |                  |
                   |  Campo Longitud  |
                   |   ------------   |
                   | Indicador de Tipo|
                   |   ------------   |
                   |Contador de Dimens|
                   |   ------------   |
                   |Dimensin 1 Longit|
                   |   ------------   |
                   |Dimensin 2 Longit|
                   |   ------------   |
                   |        .         |             Objeto
                   |        .         |             Formacin
                   |        .         | Cuerpo
                   |   ------------   |
                   |Dimensin N Longit|
                   |   ------------   |
                   |                  |
                   |    Elementos     |
                   |                  |
                   +------------------+

      Los elementos de la formacin son cuerpos de objetos del mismo tipo de
      objeto. El indicador de tipo es una direccin de prlogo (piensa en
      esta direccin de prlogo como si se aplicara a cada elemento de la
      formacin).

      El "OPTION BASE" de la formacin es siempre 1. Una formacin nula se
      designa teniendo algn lmite de dimensin el valor cero. Todos los
      elementos de un objeto formacin estn siempre presentes como se indica
      por la informacin de la dimensionalidad y se ordenan en memoria por el
      orden lexicogrfico de los ndices de la formacin.


      3.1.10   Objeto Formacin Encadenada

      Un objeto formacin encadenada es atmico, tiene el prlogo DOLNKARRY y
      un cuerpo que es una coleccin de los elementos de la formacin. El
      cuerpo tambin incluye un campo longitud (que indica la longitud del
      cuerpo), un indicador de tipo (que indica el tipo de objeto de los
      elementos), un campo contador de dimensiones, campos longitud para cada
      dimensin y una tabla de punteros cuyo contenido son offsets
      auto-relativos hacia adelante a los elementos de la formacin; los
      elementos de la tabla de punteros estn ordenados en memoria por el
      orden lexicogrfico de los ndices de la formacin.



                                 Pgina 23







                   +------------------+
                   | -> DOLNKARRY     | Direccin del Prlogo
                   +------------------+
                   |                  |
                   |  Campo Longitud  |
                   |   ------------   |
                   | Indicador de Tipo|
                   |   ------------   |
                   |Contador de Dimens|
                   |   ------------   |
                   |Dimensin 1 Longit|
                   |   ------------   |
                   |Dimensin 2 Longit|
                   |   ------------   |             Objeto 
                   |        .         |             Formacin
                   |        .         |             Encadenada
                   |        .         | Cuerpo
                   |   ------------   |
                   |Dimensin N Longit|
                   |   ------------   |
                   |                  |
                   |Tabla de Punteros |
                   |                  |
                   |   ------------   |
                   |                  |
                   |    Elementos     |
                   |                  |
                   +------------------+

      Los elementos de la formacin son cuerpos de objetos del mismo tipo de
      objeto. El indicador de tipo es una direccin de prlogo (piensa en
      esta direccin de prlogo como si se aplicara a cada elemento de la
      formacin).

      El "OPTION BASE" de la formacin encadenada es siempre 1. Una formacin
      encadenada nula es aquella que tiene alguno de sus lmites de dimensin
      igual a cero. No se supone ningn orden de los elementos de un objeto
      formacin encadenada y ni siquiera se supone su presencia; la ausencia
      de un elemento en una dimensin asignada se indica por el valor cero
      ocupando el elemento correspondiente de la tabla de punteros.


















                                 Pgina 24




      3.1.11   Objeto Cadena de Caracteres

      Un objeto cadena de caracteres es atmico, tiene el prlogo DOCSTR y un
      cuerpo que es una cadena de caracteres (una secuencia de bytes). El
      cuerpo tambin incluye un campo longitud (que indica la longitud del
      cuerpo).

                   +-------------------+
                   |  -> DOCSTR        | Direccin del Prlogo
                   +-------------------+
                   |                   |            Objeto   
                   |  Campo Longitud   |            Cadena de
                   |   ------------    | Cuerpo     Caracteres
                   | Secuencia de Bytes|
                   |                   |
                   +-------------------+



      3.1.12   Objeto Cadena Hexadecimal (Hex)

      Un objeto cadena Hex es atmico, tiene el prlogo DOHSTR y un cuerpo
      que es una secuencia de nibbles. El cuerpo tambin incluye un campo
      longitud (que indica la longitud del cuerpo).

                  +--------------------+
                  |  -> DOHSTR         | Direccin del Prlogo
                  +--------------------+
                  |                    |            Objeto
                  |  Campo Longitud    |            Cadena
                  |   ------------     | Cuerpo     Hex
                  |Secuencia de Nibbles|
                  |                    |
                  +--------------------+

      Un uso tpico de este tipo de objetos es un bfer o tabla. Los objetos
      cadena hex de 16 o menos nibbles se usan para representar objetos
      enteros binarios en RPL de usuario.


         3.1.13   Objeto Carcter

      Un objeto carcter es atmico, tiene el prlogo DOCHAR y un cuerpo que
      es un slo byte.

                   +-------------------+
                   |    -> DOCHAR      | Direccin del Prlogo
                   +-------------------+
                   |                   |          Objeto
                   |        Byte       | Cuerpo   Carcter
                   |                   |
                   +-------------------+

      Este objeto se usa para representar cantidades de un solo byte, tales
      como caracteres ASCII o ROMAN8.






                                 Pgina 25






      3.1.14   Objeto Unidad

      Un objeto unidad es compuesto, tiene el prlogo DOEXT y un cuerpo que
      es una secuencia que consiste en un nmero real seguido de cadenas de
      nombres de unidades, caracteres prefijo, operadores de unidades y
      potencias de nmeros reales, delimitado por la cola por un puntero a
      SEMI.

                   +--------------------+
                   |    -> DOEXT        |
                   +--------------------+
                   |Secuencia de Objetos|
                   |                    |
                   |     ->SEMI         |
                   +--------------------+



      3.1.15   Objeto Cdigo

      Un objeto cdigo es atmico, tiene el prlogo DOCODE y un cuerpo que es
      una seccin en lenguaje ensamblador. El cuerpo tambin incluye un campo
      longitud (que indica la longitud del cuerpo). Cuando se ejecuta, el
      prlogo coloca el contador de programa del sistema en la seccin en
      lenguaje ensamblador dentro del cuerpo.

                   +--------------------+
                   |  -> DOCODE         | Direccin del Prlogo
                   +--------------------+
                   |                    |           Objeto Cdigo
                   |  Campo Longitud    |
                   |   ------------     | Cuerpo
                   |    Seccin en      |
                   |Lenguaje Ensamblador|
                   |                    |
                   +--------------------+

      Las principales aplicaciones de este tipo de objeto son los
      procedimientos en lenguaje ensamblador que se pueden embeber
      directamente en los objetos compuestos o existir en RAM.



















                                 Pgina 26






      3.1.16   Objeto Cdigo Primitiva

      Un objeto cdigo primitiva es un caso especial de objeto cdigo, usado
      para representar el cdigo de las primitivas en las bibliotecas
      incorporadas. El prlogo de un objeto cdigo primitiva es su cuerpo,
      que es una seccin en lenguaje ensamblador; as, cuando se ejecuta, el
      cuerpo se ejecuta a s mismo.
      
                   +--------------------+
            +------+----------          | Direccin del Prlogo
            |      +--------------------+
            +----->|                    |            Objeto Cdigo
                   |     Seccin en     |Cuerpo      Primitiva  
                   |Lenguaje Ensamblador|
                   |                    |
                   +--------------------+

      El propsito principal de este tipo de objetos es la ejecucin ms
      rpida de los objetos cdigo en las bibliotecas incorporadas, esto es,
      estos objetos se ejecutan sin el nivel extra inherente a la ejecucin
      de un prlogo separado. Sin embargo, su estructura implica que (1) slo
      pueden existir en las bibliotecas incorporadas (nunca en RAM ni en
      bibliotecas mviles) ya que el cuerpo debe estar en una direccin fija,
      (2) no se pueden saltar y (3) no pueden existir en cualquier situacin
      en la que pueda ser necesario esquivar un objeto, tales como un
      elemento de una formacin o un objeto dentro de cualquier objeto
      compuesto.

      Observa que este tipo de objetos es una excepcin al esquema de
      clasificacin de tipos de objetos presentada al principio de este
      documento. Sin embargo, un objeto es un objeto cdigo primitiva si y
      slo si su direccin del prlogo es igual a la direccin del objeto ms
      5. Adems, los prlogos de este tipo de objetos (o sea, los cuerpos de
      los objetos) no necesitan contener ninguna lgica para comprobar si la
      ejecucin es directa o indirecta ya que, por definicin, no se pueden
      ejecutar directamente.


      3.1.17   Objeto Programa

      Un objeto programa (secundario) es compuesto, tiene el prlogo DOCOL y
      un cuerpo que es una secuencia de objetos y punteros de objeto, el
      ltimo de los cuales es un puntero de objeto que apunta al objeto
      cdigo primitiva SEMI.

                   +------------------+
                   |  -> DOCOL        | Direccin del Prlogo
                   +------------------+
                   |                  |
                   |   Secuencia de   |          Objeto   
                   |Punteros de Objeto|          Secundario
                   |     /Objetos     |
                   |     --------     | Cuerpo
                   |     -> SEMI      |
                   |                  |
                   +------------------+



                                    Pgina 27







      3.1.18   Objeto Lista

      Un objeto lista es compuesto, tiene el prlogo DOLIST y un cuerpo que
      es una secuencia de objetos y punteros de objeto, el ltimo de los
      cuales es un puntero de objeto que apunta al objeto cdigo primitiva
      SEMI.

                   +------------------+
                   |  -> DOLIST       | Direccin del Prlogo
                   +------------------+
                   |                  |
                   |   Secuencia de   |          Objeto
                   |Punteros de Objeto|          Lista
                   |      /Objetos    |
                   |     --------     | Cuerpo
                   |     -> SEMI      |
                   |                  |
                   +------------------+


      3.1.19   Objeto Simblico

      Un objeto simblico es compuesto, tiene el prlogo DOSYMB y un cuerpo
      que es una secuencia de objetos y punteros de objeto, el ltimo de los
      cuales es un puntero de objeto que apunta al objeto cdigo primitiva
      SEMI.

                   +------------------+
                   |  -> DOSYMB       | Direccin del Prlogo
                   +------------------+
                   |                  |
                   |  Secuencia de    |          Objeto 
                   |Punteros de Objeto|          Simblico
                   |     /Objetos     |
                   |     --------     | Cuerpo
                   |     -> SEMI      |
                   |                  |
                   +------------------+

      Este tipo de objetos se usa para representar objetos simblicos para
      aplicaciones de matemtica simblica.

















                                 Pgina 28






      3.1.20   Objeto Directorio

      Un objeto directorio (RAMROMPAIR) se atmico, tiene el prlogo DORRP y
      un cuerpo que consiste en un nmero ID de biblioteca y una RAMPART
      (PARTE RAM) (lista encadenada de variables--pares objeto/nombre)

                   +----------------+
                   |  -> DORRP      |  Direccin del Prlogo
                   +----------------+
                   |                |           Objeto
                   |   ROMPART ID   |           RAMROMPAIR
                   |    --------    |  Cuerpo
                   |    RAMPART     |
                   +----------------+



      3.1.21   Objeto Grfico


      Un objeto grfico es atmico, tiene el prlogo DOGROB y un cuerpo que
      consiste en lo siguiente:

      +  Un campo de 5 nibbles de longitud para los datos que siguen.

      +  Una cantidad de cinco nibbles que describe la altura del grfico en
         pixels.

      +  Una cantidad de cinco nibbles que describe la anchura del grfico en
         pixels.

      +  Los datos.

      La dimensin real de las filas en nibbles (W) es siempre un nmero par
      por razones del hardware, as que cada fila de datos de pixels est
      completada con 0 a 7 bits de datos desperdiciados.

                   +----------------+
                   |  -> DOGROB     | Direccin del Prlogo
                   +----------------+
                   | Longitud(nibs) |
                   +----------------+
                   | Altura (pixels)|         Objeto  
                   +----------------+ Cuerpo  Grfico
                   |Anchura (pixels)|
                   +----------------+
                   | Datos del Grob |
                   |      ...       |
                   +----------------+

      Los nibbles de datos comienzan en la esquina superior izquierda del
      objeto grfico y siguen de izquierda a derecha y de arriba hacia abajo.
      Cada fila de datos de pixels est completada segn se necesite hasta
      obtener un nmero par de nibbles por fila. As, la anchura en nibbles W
      se determina por:
                        W=CEIL(Anchura en pixels)/8



                                 Pgina 29






      Los bits de cada nibble se escriben en orden inverso, de modo que el
      pixel mostrado ms a la izquierda se representa en un nibble por el bit
      menos significativo del nibble.


       3.2  Terminologa y Abreviaciones

      En los diagramas de la pila que se usarn en el lo que resta de este
      documento, se usan los siguientes smbolos para representar los
      diferentes tipos de objetos: (N.T.> no los traduzco en los diagramas)

       ob ........... Cualquier Objeto
       id ........... Objeto Identificador
       lam .......... Objeto Identificador Temporal
       romptr ....... Objeto Puntero ROM
       # .............Objeto Entero Binario
       % ............ Objeto Real
       %% ........... Objeto Real Extendido
       C% ........... Objeto Complejo
       C%% .......... Objeto Complejo Extendido
       arry ......... Objeto Formacin
       lnkarry ...... Objeto Formacin Encadenada
       $ ............ Objeto Cadena de Caracteres
       hxs .......... Objeto Cadena Hex
       chr .......... Objeto Carcter
       ext .......... Objeto Externo
       code ......... Objeto Cdigo
       primcode ..... Objeto Cdigo Primitiva
       :: ........... Objeto Secundario
       {} ........... Objeto Lista
       symb ......... Objeto Simblico
       comp ......... Cualquier Objeto Compuesto (lista,secundario,simblico)
       rrp .......... Objeto Directorio
       tagged ....... Objeto Etiquetado
       flag ......... TRUE/FALSE (Cierto/Falso)

      (TRUE y FALSE denotan las partes de objeto de las ROM-WORDs (palabras
      ROM) incorporadas que tienen estos nombres. Las direcciones de estos
      objetos (o sea, sus representaciones en la pila de datos) se
      interpretan por las estructuras de control RPL como el valor apropiado
      de veracidad. Ambos objetos son objetos cdigo primitiva que, cuando se
      ejecutan, se colocan ellos mismos en la pila de datos).

      Adems de la notacin arriba indicada, es til conocer alguna
      terminologa adicional.

       ELEMENTO:
         Un ELEMENTO de un objeto compuesto es cualquier objeto o puntero de
         objeto en el cuerpo de un objeto compuesto.










                                 Pgina 30







      NUCLEO: 
         de una cadena de caracteres:  el ncleo de un objeto cadena de
                                       caracteres son los caracteres del
                                       cuerpo.

         de una cadena hex:   el ncleo de un objeto cadena hex es la
                              secuencia de nibbles del cuerpo.

         de un compuesto:  el ncleo de un objeto compuesto es la secuencia
                           de elementos del cuerpo sin incluir el puntero de
                           objeto final que apunta a SEMI.

       LONGITUD:
         de una cadena de caracteres:  la longitud de un objeto cadena de
                                       caracteres es el nmero de caracteres
                                       del ncleo.

         de una cadena hex:   la longitud de un objeto cadena hex es el
                              nmero de nibbles del ncleo.

         de un compuesto:  la longitud de un objeto compuesto es el nmero de
                           elementos del ncleo.

       NULO:
         cadena de caracteres:   un objeto cadena de caracteres nula es una
                                 cuya longitud es cero.

         cadena hex: un objeto cadena hex nulo es uno cuya longitud es cero.

         compuesto:  un objeto compuesto nulo es uno cuya longitud es cero.

       INTERNO:
         un interno de un objeto compuesto es cualquier objeto en el ncleo
         del objeto compuesto o lo apuntado por cualquier puntero de objeto
         en el ncleo del objeto compuesto.

      (A menudo nos referimos a un objeto compuesto diciendo que contiene un
      tipo especfico de objeto, por ejemplo, "una lista de enteros
      binarios"; lo que realmente se quiere decir es que los internos del
      ncleo son todos de este tipo de objeto).


















                                 Pgina 31




      4. Enteros Binarios


      Los enteros binarios internos tienen un tamao fijo de 20 bits y son el
      tipo usado ms a menudo por los contadores, bucles, etc. Los enteros
      binarios ofrecen ventajas de tamao y velocidad.

      NOTA: Los enteros binarios a nivel de usuario se implementan como
            cadenas hex, as que el objeto de usuario #247d es en realidad
            una cadena hex y no se debera confundir con un entero binario
            cuyo prlogo es DOBINT.


      4.1   Enteros Binarios Incorporados

      El compilador RPLCOMP interpreta un nmero decimal en un fichero fuente
      como una directiva que genera un objeto entero binario - usando un
      prlogo y un cuerpo. Los enteros binarios incorporados pueden accederse
      con slo un puntero de objeto. Por ejemplo, " 43 " (sin las comillas)
      en el fichero fuente genera un objeto binario:

               CON(5)  =DOBINT
               CON(5)  43

      El objeto ocupa cinco bytes, pero se puede reemplazar por la palabra
      "FORTYTHREE" (Cuarenta y tres), que es un punto de entrada soportado
      que generara el siguiente cdigo:

               CON(5)  =FORTYTHREE

      Un escollo a tener en cuenta en la convencin de cmo se nombran los
      enteros binarios es la diferencia que hay entre las entradas FORTYFIVE
      (Cuarenta y cinco) y FOURFIVE (Cuatro Cinco). En el primer caso, el
      valor decimal es 45 pero el ltimo es el decimal 69 (hex 45). Los
      nombres como 2EXT e IDREAL, donde los valores no son obvios, se usan
      conjuntamente con la familia de comandos CK&Dispatch de chequeo de
      argumentos. Los nombres para la familia de los CK&Dispatch se equiparan
      a los mismos lugares que otros enteros binarios. Esto se ha hecho por
      legibilidad. Por ejemplo, la palabra SEVENTEEN (diecisiete), para el
      decimal 17, tiene los nombres 2REAL y REALREAL equiparados a la misma
      posicin. Una "d" o "h" al final de nombres tales como BINT_122d o
      BINT80h (N.T.> BINT viene de B_inary INT_eger = Entero binario) indican
      la base asociada con el valor.

      Las palabras como ONEONE (UnoUno), ZEROONE (CeroUno), etc. ponen ms de
      un entero binario en la pila. Esto se indica con un pequeo diagrama de
      pila entre parntesis, tal como (--> #1 #1) para ONEONE.














                                 Pgina 32






      Las entradas soportadas para los enteros binarios se listan debajo con
      el valor hex entre parntesis cuando sea necesario: 
      N.T.> A la izquierda, el valor decimal. Separados con | si son dos o
            ms nmeros diferentes dichos de seguido (CuatroCinco) --> 4|5

  238  2EXT (#EE)       49  FORTYNINE        161  SYMREAL (#A1) 
  204  2GROB (#CC)      41  FORTYONE         170  SYMSYM (#AA)
   85  2LIST (#55)      47  FORTYSEVEN       208  TAGGEDANY (#D0)
   17  2REAL (#11)      46  FORTYSIX          10  TEN
  273  3REAL (#111)     43  FORTYTHREE        13  THIRTEEN
 2563  Attn# (#A03)     42  FORTYTWO          30  THIRTY
  253  BINT253           4  FOUR              38  THIRTYEIGHT
  255  BINT255d         69  FOURFIVE          35  THIRTYFIVE
   64  BINT40h          14  FOURTEEN          34  THIRTYFOUR
  128  BINT80h          67  FOURTHREE         39  THIRTYNINE
  192  BINTC0h          66  FOURTWO           31  THIRTYONE
  115  BINT_115d        40  FOURTY            37  THIRTYSEVEN
  116  BINT_116d        97  IDREAL (#61)      36  THIRTYSIX
  122  BINT_122d       337  INTEGER337        33  THIRTYTHREE
  130  BINT_130d        82  LISTCMP (#52)     32  THIRTYTWO
  131  BINT_131d        87  LISTLAM (#57)      3  THREE
   65  BINT_65d         81  LISTREAL (#51)    12  TWELVE
   91  BINT_91d    1048575  MINUSONE(#FFFFF)  20  TWENTY
   96  BINT_96d          9  NINE              28  TWENTYEIGHT
 3082  Connecting(#C0A) 19  NINETEEN          25  TWENTYFIVE
    8  EIGHT             1  ONE               24  TWENTYFOUR
   18  EIGHTEEN        100  ONEHUNDRED        29  TWENTYNINE
   80  EIGHTY          1|1  ONEONE(--> #1 #1) 21  TWENTYONE
   81  EIGHTYONE        30  REALEXT (#1E)     27  TWENTYSEVEN
   11  ELEVEN           16  REALOB (#10)      26  TWENTYSIX
   14  EXT (#E)        256  REALOBOB (#100)   23  TWENTYTHREE
 3584  EXTOBOB (#E00)   17  REALREAL (#11)    22  TWENTYTWO
  225  EXTREAL (#E1)    26  REALSYM (#1A)      2  TWO
  234  EXTSYM  (#EA)   240  ROMPANY (#F0)    131  XHI
   15  FIFTEEN           7  SEVEN            130  XHI-1 (#82)
   50  FIFTY            17  SEVENTEEN          0  ZERO
   58  FIFTYEIGHT       70  SEVENTY          0|0  ZEROZERO (--> #0 #0 )
   55  FIFTYFIVE        74  SEVENTYFOUR    0|0|1  ZEROZEROONE (--> #0 #0 #1 )
   54  FIFTYFOUR        79  SEVENTYNINE    0|0|2  ZEROZEROTWO (--> #0 #0 #2 )
   59  FIFTYNINE         6  SIX            0|0|0  ZEROZEROZERO (--> #0 #0 #0)
   51  FIFTYONE         16  SIXTEEN          103  char (#6F)
   57  FIFTYSEVEN       60  SIXTY              6  id (#6)
   56  FIFTYSIX         68  SIXTYEIGHT         6  idnt (#6)
   53  FIFTYTHREE       64  SIXTYFOUR        773  infreserr (#305)
   52  FIFTYTWO         61  SIXTYONE        2563  intrptderr (#a03)
    5  FIVE             63  SIXTYTHREE         5  list (#5)
   84  FIVEFOUR         62  SIXTYTWO         771  ofloerr (#303)
   86  FIVESIX         158  SYMBUNIT (#9E)     1  real (#1)
   83  FIVETHREE       174  SYMEXT (#AE)       8  seco (#8)
   40  FORTY           166  SYMID (#A6)        3  str (#3)
   48  FORTYEIGHT      167  SYMLAM (#A7)      10  sym (#A)
   45  FORTYFIVE       160  SYMOB (#A0)        9  symb (#9)
   44  FORTYFOUR






                                 Pgina 33




      4.2   Manipulacin de Enteros Binarios

      4.2.1 Funciones Aritmticas

       #*              ( #2 #1 --> #2*#1 )
       #+              ( #2 #1 --> #2+#1 )
       #+-1            ( #2 #1 --> #2+#1-1 )
       #-              ( #2 #1 --> #2-#1 )
       #-#2/           ( #2 #1 --> (#2-#1)/2 )
       #-+1            ( #2 #1 --> (#2-#1)+1 )
       #/              ( #2 #1 --> #resto #cociente )
       #1+             ( # --> #+1 )
       #1+'            ( # --> #+1 y ejecuta ' )
       #1+DUP          ( # --> #+1 #+1 )
       #1-             ( # --> #-1 )
       #10*            ( # --> #*10 )
       #10+            ( # --> #+10 )
       #12+            ( # --> #+12 )
       #2*             ( # --> #*2 )
       #2+             ( # --> #+2 )
       #2-             ( # --> #-2 )
       #2/             ( # --> FLOOR(#/2) )
       #3+             ( # --> #+3 )
       #3-             ( # --> #-3 )
       #4+             ( # --> #+4 )
       #4-             ( # --> #-4 )
       #5+             ( # --> #+5 )
       #5-             ( # --> #-5 )
       #6*             ( # --> #*6 )
       #6+             ( # --> #+6 )
       #7+             ( # --> #+7 )
       #8*             ( # --> #*8 )
       #8+             ( # --> #+8 )
       #9+             ( # --> #+9 )
       #MAX            ( #2 #1 --> MAX(#2,#1) )
       #MIN            ( #2 #1 --> MIN(#2,#1) )
       2DUP#+          ( #2 #1 --> #2 #1 #1+#2 )
       DROP#1-         ( # ob --> #-1 )
       DUP#1+          ( # --> # #+1 )
       DUP#1-          ( # --> # #-1 )
       DUP3PICK#+      ( #2 #1 --> #2 #1 #1+#2 )
       OVER#+          ( #2 #1 --> #2 #1+#2 )
       OVER#-          ( #2 #1 --> #2 #1-#2 )
       ROT#+           ( #2 ob #1 --> ob #1+#2 )
       ROT#+SWAP       ( #2 ob #1 --> #1+#2 ob )
       ROT#-           ( #2 ob #1 --> ob #1-#2 )
       ROT#1+          ( # ob ob' --> ob ob' #+1 )
       ROT+SWAP        ( #2 ob #1 --> #1+#2 ob )
       SWAP#-          ( #2 #1 --> #1-#2 )
       SWAP#1+         ( # ob --> ob #+1 )
       SWAP#1+SWAP     ( # ob --> #+1 ob )
       SWAP#1-         ( # ob --> ob #-1 )
       SWAP#1-SWAP     ( # ob --> #-1 ob )
       SWAPOVER#-      ( #2 #1 --> #1 #2-#1 )







                                 Pgina 34






       4.2.2  Funciones de Conversin

       COERCE          ( % --> # )  Si %<0 entonces # es 0
                                    Si %>FFFFF entonces #=FFFFF
       COERCE2         ( %2 %1 --> #2 #1 ) Ver COERCE
       COERCEDUP       ( % --> # # ) Ver COERCE 
       COERCESWAP      (ob % --> # ob ) 
       UNCOERCE        ( # --> % )
       UNCOERCE%%      ( # --> %% ) 
       UNCOERCE2       ( #2 #1 --> %2 %1 )

















































                                 Pgina 35






      5. Constantes Carcter

      Las siguientes palabras son tiles para la interconversin entre
      objetos carcter y otros tipos de objetos:

       CHR>#           ( chr --> # )
       #>CHR           ( # --> chr )
       CHR>$           ( chr --> $ )


      Las siguientes constantes carcter y cadena estn soportadas:       

       CHR_# CHR_* CHR_+ CHR_, CHR_- CHR_. CHR_/ CHR_0 CHR_1 CHR_2
       CHR_3 CHR_4 CHR_5 CHR_6 CHR_7 CHR_8 CHR_9 CHR_: CHR_; CHR_<
       CHR_= CHR_> CHR_A CHR_B CHR_C CHR_D CHR_E CHR_F CHR_G CHR_H
       CHR_I CHR_J CHR_K CHR_L CHR_M CHR_N CHR_O CHR_P CHR_Q CHR_R
       CHR_S CHR_T CHR_U CHR_V CHR_W CHR_X CHR_Y CHR_Z CHR_a CHR_b
       CHR_c CHR_d CHR_e CHR_f CHR_g CHR_h CHR_i CHR_j CHR_k CHR_l
       CHR_m CHR_n CHR_o CHR_p CHR_q CHR_r CHR_s CHR_t CHR_u CHR_v
       CHR_w CHR_x CHR_y CHR_z

       CHR_00 (hex 0) CHR_...  CHR_DblQuote    CHR_-> CHR_<<
       CHR_>> CHR_Angle CHR_Deriv CHR_Integral CHR_LeftPar
       CHR_Newline  CHR_Pi CHR_RightPar CHR_Sigma CHR_Space
       CHR_UndScore CHR_[  CHR_]  CHR_{ CHR_}  CHR_<= CHR_>=
       CHR_<>

       $_R<<           ( $ "R\80\80" "R<ngulo><ngulo>" )
       $_R<Z           ( $ "R\80Z"   "R<ngulo>Z"       )
       $_XYZ           ( $ "XYZ"                       )
       $_<<>>          ( $ "ABBB"                      )
       $_{}            ( $ "{}"                        )
       $_[]            ( $ "[]"                        )
       $_''            ( $ "''"                        )
       $_::            ( $ "::"                        )
       $_LRParens      ( $ "()"                        )
       $_2DQ           ( $ """"""                      )
       $_ECHO          ( $ "ECHO"                      )
       $_EXIT          ( $ "EXIT"                      )
       $_Undefined     ( $ "Undefined"                 )
       $_RAD           ( $ "RAD"                       )
       $_GRAD          ( $ "GRAD"                      )
       NEWLINE$        ( $ "\0a"                       )
       SPACE$          ( $ " "                         )















                                 Pgina 36
      6.  Cadenas Hex y de Caracteres

      6.1  Cadenas de Caracteres

      Las siguientes palabras estn disponibles para manipular cadenas de
      caracteres:
      N.T.> Cuando se dice "aade" se entiende que es por la derecha. Cuando
            sea por la izquierda se indicar expresamente.

   &$              ( $1 $2 --> $3 )
                        Aade $2 a $1 
   !append$        ( $1 $2 --> $3 )
                        Lo mismo que &$, excepto que intentar la
                        concatenacin "in situ" si no hay suficiente memoria
                        para la nueva cadena y el objetivo est en tempob
                        (rea de memoria de objetos temporales)
   $>ID            ( $nombre --> Id )
                        Convierte el objeto cadena en un objeto nombre
   &$SWAP          ( ob $1 $2 --> $3 ob )
                        Aade $2 a $1 y luego intercambia (swap) en la pila
                        el resultado con ob 
   1-#1-SUB$       ( $ # --> $' )
                        Donde $' = caracteres 1 hasta #-1 de $
   >H$             ( $ chr --> $' )
                        Aade chr a $ por la izquierda
   >T$             ( $ chr --> $' )
                        Aade chr a $
   AND$            ( $1 $2 --> $1 AND $2 )
                        AND (y) lgico Bit a Bit entre dos cadenas
   APPEND_SPACE    ( $ --> $' )
                        Aade un espacio a $
   Blank$          ( # --> $  )
                        Crea una cadena de # espacios
   CAR$            ( $ --> chr | $ )
                        Devuelve el primer carcter de $ o NULL$ si $ es nulo
   CDR$            ( $ --> $' )
                        $' es $ menos el primer carcter. Devuelve NULL$ si $
                        es nulo
   COERCE$22       ( $ --> $' )
                        Si $ tiene ms de 22 caracteres trunca a 21
                        caracteres y aade "..."
   DECOMP$         ( ob --> $ )
                        Descompila el objeto para mostrarlo en la pila
   DO>STR          ( ob --> $ )
                        Versin interna de ->STR
   DROPNULL$       ( ob --> NULL$ )
                        Elimina el objeto (Drop) de la pila y devuelve una
                        cadena de longitud cero
   DUP$>ID         ( $nombre --> $nombre Id )
                        Duplica (Dup) y convierte el objeto cadena en un
                        objeto nombre.
   DUPLEN$         ( $ --> $ #longitud )
                        Devuelve $ y su longitud
   DUPNULL$?       ( $ --> $ flag )
                        Devuelve TRUE si $ es de longitud cero
   EDITDECOMP$     ( ob --> $ )
                        Descompila el objeto para editarlo
   JstGETTHEMESG   ( # --> $ )
                        Obtiene mensaje nmero # de la tabla de mensajes
   ID>$            ( ID --> $nombre )
                        Convierte el objeto nombre en una cadena
   LAST$           ( $ # --> $' )
                        Devuelve los ltimos # caracteres de $

                                 Pgina 37





   LEN$            ( $ --> #longitud )
                        Devuelve la longitud de $
   NEWLINE$&$      ( $ --> $' )
                        Aade "\0a" a $ (un salto de lnea)
   NULL$           ( --> $ )
                        Devuelve una cadena vaca
   NULL$?          ( $ --> flag )
                        Devuelve TRUE si $ es de longitud cero
   NULL$SWAP       ( ob --> $ ob )
                        Intercambia (swap) una cadena vaca con ob
   NULL$TEMP       ( --> $ )
                        Crea una cadena vaca en TEMPOB (rea de objetos
                        temporales)
   OR$             ( $1 $2 --> $3 )
                        OR (o) lgico Bit a Bit entre dos cadenas
   OVERLEN$        ( $ ob --> $ ob #longitud )
                        Devuelve la longitud del $ del nivel 2
   POS$            ( $buscar_en $a_buscar #inicio --> #posicin )
                        Devuelve la #posicin (#0 si no lo encuentra) de
                        $a_buscar dentro de $buscar_en empezando por la
                        posicin #inicio de $buscar_en y buscando de
                        izquierda a derecha
   POS$REV         ( $buscar_en $a_buscar #inicio --> #posicin )
                        Devuelve la #posicin (#0 si no lo encuentra) de
                        $a_buscar dentro de $buscar_en empezando por la
                        posicin #inicio de $buscar_en y buscando de derecha
                        a izquierda (N.T.>#inicio=1 es primer carcter izq)
   PromptIdUtil    ( id ob -> $ )
                        Devuelve una cadena de la forma "id: ob"
   SEP$NL          ( $ --> $2 $1 )
                        Divide $ por donde haya un carcter "salto de lnea"
   SUB$            ( $ #inicio #fin --> $' )
                        Devuelve una subcadena de $
   SUB$1#          ( $ #pos --> # )
                        Devuelve un entero binario con el valor del carcter
                        en la posicin #pos de $
   SUB$SWAP        ( ob $ #inicio #fin --> $' ob )
                        Devuelve una subcadena de $ y hace SWAP con ob
   SWAP&$          ( $1 $2 --> "$2$1" )
                        Aade $1 a $2
   TIMESTR         ( %fecha %hora --> "WED 03/30/90 11:30:15A" )
                        Devuelve la cadena con la hora y fecha (como la
                        palabra de usuario TSTR)
   XOR$            ( $1 $2 --> $3 )
                        XOR (o exclusivo) lgico Bit a Bit entre dos cadenas
   a%>$            ( % --> $ )
                        Convierte % en $ usando el modo actual de mostrar
                        nmeros en pantalla
   a%>$,           ( % --> $ )
                        Convierte % en $ usando el modo actual de mostrar
                        nmeros en pantalla. (Igual que a%>$ pero sin comas)
   palparse        ( $ --> ob TRUE         )
                   ( $ --> $ #pos $' FALSE )
                        Analiza la cadena y la convierte en un objeto y
                        devuelve TRUE o devuelve la posicin de error y FALSE





                                 Pgina 38




      6.2   Cadenas Hex

   N.T.> Cuando digo aade, no es una suma sino que se concatena, como en las
         cadenas de caracteres.

   #>%             ( hxs --> % )
                        Convierte el hxs en real
   %>#             ( % --> hxs )
                        Convierte el real en hxs
   &HXS            ( hxs1 hxs2 --> hxs3 )
                        Aade hxs2 a hxs1
   2HXSLIST?       ( { hxs1 hxs2 } --> #1 #2 )
                        Convierte una lista de dos hxs en dos enteros
                        binarios. Produce el error "Valor del Argumento
                        Incorrecto" si la entrada es invlida
   HXS#HXS         ( hxs1 hxs2 --> %flag )
                        Devuelve %1 si hxs1 <> hxs2, si no, %0
   HXS>#           ( hxs --> # )
                        Convierte los 20 bits inferiores de hxs en entero
                        binario
   HXS>$           ( hxs --> $ )
                        Hace hxs>$, luego le aade el carcter de la base
   HXS>%           ( hxs --> % )
                        Convierte la cadena hex en un nmero real
   HXS<HXS         ( hxs1 hxs2 --> %flag )
                        Devuelve %1 si hxs<hxs2, si no, %0
   HXS>HXS         ( hxs1 hxs2 --> %flag )
                        Devuelve %1 si hxs1>hxs2, si no, %0
   HXS>=HXS        ( hxs1 hxs2 --> %flag )
                        Devuelve %1 si hxs1>=hxs2, si no, %0
   HXS<=HXS        ( hxs1 hxs2 --> %flag )
                        Devuelve %1 si hxs1<=hxs2, si no, %0
   LENHXS          ( hxs --> #longitud )
                        Devuelve el nmero de nibbles en hxs
   NULLHXS         ( --> hxs )
                        Devuelve una cadena hex de longitud cero
   SUBHXS          ( hxs #m #n --> hxs' )
                        Devuelve la subcadena

      Los enteros binarios del RPL de usuario son realmente cadenas hex. Las
      siguientes palabras suponen cadenas hex de 64 o menos bits y devuelven
      el resultado de acuerdo con el ancho de palabra actual:

   bit/            ( hxs1 hxs2 --> hxs3 )
                        Divide hxs1 por hxs2
   bit%#/          ( % hxs --> hxs' )
                        Divide % por hxs y devuelve hxs
   bit#%/          ( hxs % --> hxs' )   
                        Divide hxs por % y devuelve hxs
   bit*            ( hxs1 hxs2 --> hxs3 )
                        Multiplica hxs1 por hxs2 
   bit%#*          ( % hxs --> hxs' )
                        Multiplica % por hxs y devuelve hxs
   bit#%*          ( hxs % --> hxs' )
                        Multiplica hxs por % y devuelve hxs    
   bit+            ( hxs1 hxs2 --> hxs3 )
                        Suma hxs1 a hxs2 




                                 Pgina 39




   bit%#+          ( % hxs --> hxs' )
                        Suma % a hxs y devuelve hxs
   bit#%+          ( hxs % --> hxs' )
                        Suma hxs a % y devuelve hxs 
   bit-            ( hxs1 hxs2 --> hxs3 )
                        Resta hxs2 de hxs1 
   bit%#-          ( % hxs --> hxs' )
                        Resta % de hxs y devuelve hxs
   bit#%-          ( hxs % --> hxs' )
                        Resta hxs de % y devuelve hxs
   bitAND          ( hxs1 hxs2 --> hxs3 )
                        AND (y) lgico bit a bit
   bitASR          ( hxs --> hxs' )
                        Desplazamiento aritmtico a la derecha de un bit
   bitOR           ( hxs1 hxs2 --> hxs3 )
                        OR (o) lgico bit a bit
   bitNOT          ( hxs1 hxs2 --> hxs3 )
                        NOT (no) lgico bit a bit
   bitRL           ( hxs --> hxs' )
                        Rotacin a la izquierda de un bit
   bitRLB          ( hxs --> hxs' )
                        Rotacin a la izquierda de un byte
   bitRR           ( hxs --> hxs' )
                        Rotacin a la derecha de un bit
   bitRRB          ( hxs --> hxs' )      
                        Rotacin a la derecha de un byte
   bitSL           ( hxs --> hxs' )
                        Desplazamiento a la izquierda de un bit
   bitSLB          ( hxs --> hxs' ) 
                        Desplazamiento a la izquierda de un byte
   bitSR           ( hxs --> hxs' )
                        Desplazamiento a la derecha de un bit
   bitSRB          ( hxs --> hxs' )
                        Desplazamiento a la derecha de un byte
   bitXOR          ( hxs1 hxs2 --> hxs3 )
                        XOR (o exclusivo) lgico bit a bit


      Control del Tamao de Palabra:

      WORDSIZE        ( --> # )           Devuelve el tamao de palabra de
                                          los enteros binarios de usuario.
      dostws          ( # --> )           Almacena el tamao de palabra
                                          binaria.
      hxs>$           (hxs --> $ )        Convierte la cadena hex a una
                                          cadena de caracteres usando el modo
                                          de pantalla y el tamao de palabra
                                          actuales.













                                 Pgina 40




      7. Nmeros Reales

      Los nmeros reales se escriben con % y los nmeros reales extendidos se
      escriben con %%.


      7.1   Reales Incorporados


      Los siguientes nmeros reales y reales extendidos estn incorporados:

       %%.1    %%4    %-8         %11    %21    %5
       %%.4    %%5    %-9         %12    %22    %6
       %%.5    %%60   %-MAXREAL   %13    %23    %7
       %%0     %%7    %-MINREAL   %14    %24    %8
       %%1     %-2    %.1         %15    %25    %MAXREAL
       %%10    %-3    %.5         %16    %26    %MINREAL
       %%12    %-4    %0          %17    %27    %PI
       %%2     %-5    %1          %180   %3     %e
       %%2PI   %-6    %10         %2     %360   %-1
       %%3     %-7    %100        %20    %4


      7.2   Funciones de Nmeros Reales

      En los diagramas de pila que siguen a continuacin, %1 y %2 se refieren
      a dos nmeros reales diferentes, NO a los nmeros reales uno y dos.


       %%*             ( %%1 %%2 -->  %%3 )
                         Multiplica dos reales extendidos
       %%*ROT          ( ob1 ob2 %%1 %%2 --> ob2 %%3 ob1 )
                         Multiplica dos reales extendidos,
                         luego hace ROT
       %%*SWAP         ( ob %%1 %%2 --> %%3 ob )
                         Multiplica dos reales extendidos,
                         luego hace SWAP
       %%*UNROT        ( ob1 ob2 %%1 %%2 --> %%3 ob1 ob2 )
                         Multiplica dos reales extendidos,
                         luego hace UNROT
       %%+             ( %%1 %%2 --> %%3 )
                         Suma dos reales extendidos
       %%-             ( %%1 %%2 --> %%3 )
                         Resta
       %%ABS           ( %% --> %%' )
                         Valor absoluto
       %%ACOSRAD       ( %% --> %%' )
                         Arco-coseno usando radianes
       %%ANGLE         ( %%x %%y --> %%ngulo )
                         Angulo usando el modo actual de ngulos de %%x %%y
       %%ANGLEDEG      ( %%x %%y --> %%ngulo )
                         Angulo usando grados sexagesimales de %%x %%y









                                 Pgina 41






   %%ANGLERAD      ( %%x %%y --> %%ngulo )
                        Angulo en radianes de %%x %%y
   %%ASINRAD       ( %% --> %%' )
                        Arco-seno con radianes
   %%CHS           ( %% --> %%' )
                        Cambiar signo
   %%COS           ( %% --> %%' )
                        Coseno
   %%COSDEG        ( %% --> %%' )
                        Coseno con grados sexagesimales
   %%COSH          ( %% --> %%' )
                        Coseno hiperblico
   %%COSRAD        ( %% --> %%' )
                        Coseno con radianes
   %%EXP           ( %% --> %%' )
                        e^x
   %%FLOOR         ( %% --> %%' )
                        El mayor entero <= x
   %%H>HMS         ( %% --> %%' )
                        Horas decimales a hh.mmss
   %%INT           ( %% --> %%' )
                        Parte entera
   %%LN            ( %% --> %%' )
                        ln(x)
   %%LNP1          ( %% --> %%' )
                        ln(x+1)
   %%MAX           ( %%1 %%2 --> %%3 )
                        Devuelve el mayor de dos %%s
   %%P>R           ( %%radio %%ngulo --> %%x %%y )
                        Conversin de polar a rectangular
   %%R>P           ( %%x %%y --> %%radio %%ngulo )
                        Conversin de rectangular a polar
   %%SIN           ( %% --> %%' )
                        Seno
   %%SINDEG        ( %% --> %%' )
                        Seno con grados sexagesimales
   %%SINH          ( %% --> %%' )
                        Seno hiperblico
   %%SQRT          ( %% --> %%' )
                        Raz cuadrada
   %%TANRAD        ( %% --> %%' )
                        Tangente con radianes
   %%^             ( %%1 %%2 --> %%3 )
                        Exponencial
   %+              ( %1 %2 --> %3 )
                        Suma
   %+SWAP          ( ob %1 %2 --> %3 ob )
                        Suma, luego SWAP
   %-              ( %1 %2 --> %3 )
                        Resta
   %1+             ( % --> %+1 )
                        Suma uno
   %1-             ( % --> %-1 )
                        Resta uno





                                 Pgina 42




   %>#             ( % --> hxs )
                        Convierte el real en entero binario
   %>%%            ( % --> %% )
                        Convierte el real en real extendido
   %%>%            ( %% --> % )
                        Convierte el real extendido en real
   %>%%-           ( %1 %2 --> %%3 )
                        Convierte dos % en %% y luego los resta
   %>%%1           ( %x --> %% )
                        Convierte % en %% y luego lo invierte (1/x)
   %>%%ANGLE       ( %x %y --> %%ngulo )
                        Angulo en el modo actual de ngulos
   %>%%SQRT        ( % --> %% )
                        Convierte % en %% y luego raz cuadrada (sqrt(x))
   %>%%SWAP        ( ob % --> %% ob )
                        Convierte % en %% y luego hace SWAP
   %>C%            ( %real %imaginaria --> C% )
                         Conversin de real en complejo
   %>HMS           ( % --> %hh.mmss )
                        Horas decimales a hh.mmss
   %ABS            ( % --> %' )
                        Valor absoluto
   %ABSCOERCE      ( % --> # )
                        Valor absoluto y luego lo convierte en #
   %ACOS           ( % --> %' )
                        Arco-coseno
   %ACOSH          ( % --> %' )
                        Arco-coseno hiperblico
   %ALOG           ( % --> %' )
                         10^x
   %ANGLE          ( %x %y --> %ngulo )
                        Angulo con el modo actual de ngulos de %x %y
   %ASIN           ( % --> %' )
                        Arco-seno
   %ASINH          ( % --> %' )
                        Arco-seno hiperblico
   %ATAN           ( % --> %' )
                        Arco-tangente
   %ATANH          ( % --> %' )
                        Arco-tangente hiperblica
   %CEIL           ( % --> %' )
                        El siguiente entero ms grande
   %CH             ( %1 %2 --> %3 )
                        Variacin porcentual
   %CHS            ( % --> %' )
                        Cambio de signo
   %COMB           ( %m %n -> %COMB(m,n) )
                        Combinaciones de m elementos tomados de n en n
   %COS            ( % --> %' )
                        Coseno
   %COSH           ( % --> %' )
                        Coseno hiperblico
   %D>R            ( % --> %' )
                        Grados sexagesimales a radianes
   %EXP            ( % --> %' )
                        e^x
   %EXPM1          ( % --> %' )
                        e^x-1



                                 Pgina 43




   %EXPONENT       ( % --> %' )
                        Devuelve el exponente
   %FACT           ( % --> %! )
                        Factorial
   %FLOOR          ( % --> %' )
                        El mayor entero <= x
   %FP             ( % --> %' )
                        Parte Fraccionaria
   %HMS+           ( %1 %2 --> %3 )
                        Suma de HH.MMSS
   %HMS-           ( %1 %2 --> %3 )
                        Resta de HH.MMSS
   %HMS>           ( % --> %' )
                        Convierte hh.mmss a horas decimales
   %IP             ( % --> %' )
                        Parte entera
   %IP>#           ( % --> # )
                        IP(ABS(x)) convertido en #
   %LN             ( % --> %' )
                        ln(x)
   %LNP1           ( % --> %' )
                        ln(x+1)
   %LOG            ( % --> %' )
                        Logaritmo base 10
   %MANTISSA       ( % --> %' )
                        Devuelve la mantisa
   %MAX            ( %1 %2 --> % )
                        Devuelve el mayor de dos reales
   %MAXorder       ( %1 %2 --> %mayor %menor )
                        Ordena dos nmeros
   %MIN            ( %1 %2 --> % )
                        Devuelve el menor de dos reales
   %MOD            ( %1 %2 --> %3 )
                        Devuelve %1 MOD %2
   %NFACT          ( % --> %' )
                        Factorial
   %NROOT          ( %1 %2 --> %3 )
                        Raz ensima
   %OF             ( %1 %2 --> %3 )
                        Devuelve el porcentaje de %1 que es %2
   %PERM           ( %m %n --> %PERM(%m,%n) )
                        Devuelve las variaciones de %m elementos tomados de
                        %n en %n
   %POL>%REC       ( %x %y --> %radio %ngulo )
                        Conversin rectangular a polar
   %R>D            ( %radianes --> %grados )
                        Radianes a grados sexagesimales
   %RAN            ( --> %aleatorio )
                        Nmero aleatorio
   %RANDOMIZE      ( %semilla --> )
                        Actualiza la semilla de nmeros aleatorios usando el
                        reloj del sistema si %semilla es %0
   %REC>%POL       ( %radio %ngulo --> %x %y )
                        Conversin de polar a rectangular
   %SGN            ( % --> %' )
                        Signo: devuelve -1, 0 o 1 dependiendo del signo del
                        argumento
   %SIN            ( % --> %' )
                        Seno


                                 Pgina 44




   %SINH           ( % --> %' )
                        Seno hiperblico
   %SPH>%REC       ( %r %th %ph --> %x %y %z )
                        Conversin de coordenadas esfrica a rectangulares
   %SQRT           ( % --> %' )
                        Raz cuadrada
   %T              ( %1 %2 --> %3 )
                        Porciento total
   %TAN            ( % --> %' )
                        Tangente
   %TANH           ( % --> %' )
                        Tangente hiperblica
   %^              ( %1 %2 --> %3 )
                        Exponencial
   2%%>%           ( %%1 %%2 --> %1 %2 )
                        Conversin real extendido a real
   2%>%%           ( %1 %2 --> %%1 %%2 )
                        Conversin real a real extendido
   C%>%            ( C% --> %real %imag )
                        Conversin complejo a real
   DDAYS           ( %fecha1 %fecha2 --> %diferencia )
                        Das entre dos fechas en formato DMY (Da/Mes/Ao)
   DORANDOMIZE     ( % --> )
                        Actualiza semilla del generador de nmeros aleatorios
   RNDXY           ( %nmero %posiciones --> %nmero' )
                        Redondea %nmero a %posiciones
   TRCXY           ( %nmero %posiciones --> %nmero' )
                        Trunca %nmero a %posiciones
   SWAP%>C%        ( %imaginario %real --> C% )
                        Conversin real a complejo































                                 Pgina 45




      8. Nmeros Complejos

      Los nmeros complejos se representan por C% y los nmeros complejos
      extendidos por C%%


      8.1   Nmeros Complejos Incorporados


       C%0             (0,0)
       C%1             (1,0)
       C%-1            (-1,0)
       C%%1            (%%1,%%0)


      8.2   Palabras de Conversin


   %>C%            ( %real %imag --> C% )
   %%>C%%          ( %%real %%imag --> C%% )
   %%>C%           ( %%real %%imag --> C% )
   C%>%            ( C% --> %real %imag )
   C%%>%%          ( C%% --> %%real %%imag )
   C%%>C%          ( C%% --> C% )
   C%>%%C          ( C% --> %%real %%imag )
   C%>%%SWAP       ( C% --> %%imag %%real )
   C>Im%           ( C% --> %imag )
   C>Re%           ( C% --> %real )



      8.3   Funciones de Complejos


       C%1/            ( C% --> C%' )
                        Inverso
       C%ABS           ( C% --> % )
                        Devuelve SQRT(x^2+y^2) de (x,y)
       C%ACOS          ( C% --> C%' )
                        Arco-coseno
       C%ALOG          ( C% --> C%' )
                        Antilogaritmo base 10
       C%ARG           ( C% --> %)
                        Devuelve ANGULO(x,y) de (x,y)
       C%ASIN          ( C% --> C%' )
                        Arco-seno
       C%ATAN          ( C% --> C%' )
                        Arco-tangente
       C%C^C           ( C%1 C%2 --> C%3 )
                        Potencia
       C%CHS           ( C% --> C%' )
                        Cambio de signo
       C%%CHS          ( C%% --> C%%' )
                        Cambio de signo
       C%CONJ          ( C% --> C%' )
                        Conjugado
       C%%CONJ         ( C%% --> C%%' )
                        Conjugado



                                 Pgina 46






       C%COS           ( C% --> C%' )
                        Coseno
       C%COSH          ( C% --> C%' )
                        Coseno hiperblico
       C%EXP           ( C% --> C%' )
                        e^z
       C%LN            ( C% --> C%' )
                        Logaritmo natural
       C%LOG           ( C% --> C%' )
                        Logaritmo base 10
       C%SGN           ( C% --> C%' )
                        Devuelve (x/SQRT(x^2+y^2),y/SQRT(x^2+y^2)
       C%SIN           ( C% --> C%' )
                        Seno
       C%SINH          ( C% --> C%' )
                        Seno hiperblico
       C%SQRT          ( C% --> C%' )
                        Raz cuadrada
       C%TAN           ( C% --> C%' )
                        Tangente
       C%TANH          ( C% --> C%' )
                        Tangente hiperblica





































                                 Pgina 47




      9. Formaciones

      La notacin [array] representa una formacin real o compleja. [arry%] y
      [arryC%] representan una formacin real y compleja respectivamente.
      {dims} significa una lista con las dimensiones de la formacin, que
      puede ser o bien { #cols } o bien { #filas #cols }.

      A menos que se indique lo contrario, las siguientes palabras NO
      comprueban las condiciones fuera de lmites (p.ej. elementos
      especificados que no se encuentran dentro del margen de la formacin
      actual).
       ARSIZE          ( [array] --> #elementos )
                       ( [array] --> {dims} )
       GETATELN        ( # [array] --> ob TRUE )
                       ( # [array] --> FALSE ) (no hay tal elemento)
       MAKEARRY        ( {dims} ob --> [array] )
                        Crea una formacin no-encadenada que tiene el mismo
                        tipo de elementos que ob. Todos los elementos se
                        inicializan con ob. 
       MATCON          ( [arry%] % --> [arry%]' )
                       ( [arryC%] C% --> [arryC%]' )
                        Pone todos los elementos de la formacin a % o C%
       MATREDIM        ( [array] {dims} --> [array]' )
       MATTRN          ( [array] --> [array]' )
       MDIMS           ( [1-D array] --> #m FALSE )
                       ( [2-D array] --> #m #n TRUE )
       MDIMSDROP       ( [2-D array] --> #m #n )
                        No usar MDIMSDROP con un vector!
       OVERARSIZE      ( [array] ob --> [array] ob #elementos )
       PULLREALEL      ( [arry%] # --> [arry%] % )
       PULLCMPEL       ( [arryC%] # --> [arryC%] C% )
       PUTEL           ( [arry%] % # --> [arry%]' )
                       ( [arryC%] C% # --> [arryC%] )
       PUTREALEL       ( [arry%] % # --> [arry%]' )
       PUTCMPEL        ( [arryC%] C% # --> [arryC%]' )


























                                 Pgina 48






      10.   Objetos Compuestos

      Las palabras descritas en este captulo se usan para manipular objetos
      compuestos - principalmente listas y secundarios. En la siguiente
      notacin, el trmino "comp" se refiere a cualquier objeto compuesto. El
      trmino "#n" se refiere al nmero de objetos en un objeto compuesto y
      el trmino "#i" se refiere al ndice de un objeto dentro de un
      compuesto. El trmino "flag" se refiere a TRUE o FALSE.

       &COMP           ( comp comp' --> comp'' )
                        comp se concatena a comp'
       2Ob>Seco        ( ob1 ob2 --> :: ob1 ob2 ; )
       ::N             ( obn ... ob1 #n --> :: obn ... ob1 ; )
       ::NEVAL         ( obn ... ob1 #n --> ? )
                        Hace ::N y luego evala el secundario
       >TCOMP          ( comp ob --> comp' )
                        Se aade ob al final de comp
       CARCOMP         ( comp --> ob )
                       ( comp --> comp )
                        Devuelve el primer objeto del ncleo del compuesto.
                        Devuelve un comp nulo si el compuesto suministrado es
                        nulo.
       CDRCOMP         ( comp --> comp' )
                       ( comp --> comp )
                        Devuelve el ncleo del compuesto menos el primer
                        objeto. Devuelve un comp nulo si el compuesto
                        suministrado es nulo.
       DUPINCOMP       ( comp --> comp obn ... ob1 #n )
       DUPLENCOMP      ( comp --> comp #n )
       DUPNULLCOMP?    ( comp --> comp flag ) TRUE si comp es nulo.
       DUPNULL{}?      ( {list} --> {list} flag ) TRUE si {list} es nula.
       EQUALPOSCOMP    ( comp ob --> #pos | #0 )
                        Devuelve el ndice del primer objeto en comp que
                        coincide (EQUAL) con ob (ver NTHOF tambin)
       Embedded?       ( ob1 ob2 --> flag )
                        Devuelve TRUE si ob2 est embebido en, o es igual
                        que, ob1; si no, devuelve FALSE.
       INCOMPDROP      ( comp --> obn ... ob1 )
       INNERCOMP       ( comp --> obn ... ob1 #n )
       INNERDUP        ( comp --> obn ... ob1 #n #n )
       LENCOMP         ( comp --> #n )
       NEXTCOMPOB      ( comp #offset --> comp #offset' ob TRUE )
                       ( comp #offset --> comp FALSE )
                        #offset es el offset en nibbles desde el principio
                        del comp hasta el ensimo objeto en el mismo.
                        Devuelve un nuevo #offset' y el siguiente objeto si
                        ste no es SEMI, si es SEMI devuelve comp y FALSE.
                        Usar #5 como #offset al principio del comp, para
                        saltarse el prlogo.
       NTHCOMDDUP      ( comp #i --> ob ob )
       NTHCOMPDROP     ( comp #i --> ob )
       NTHELCOMP       ( comp #i --> ob TRUE )
                       ( comp #i --> FALSE )
                        Devuelve FALSE si #i est fuera de margen.
       NTHOF           ( ob comp --> #i | #0 ) Igual que SWAP EQUALPOSCOMP.
       NULL::          ( --> :: ; ) (Devuelve un secundario nulo)
       NULL{}          ( --> { } )  (Devuelve una lista Nula)


                                 Pgina 49






       ONE{}N          ( ob --> { ob } )
       Ob>Seco         ( ob --> :: ob ; )
       POSCOMP         ( comp ob pred --> #i | #0 )
                        Si el objeto especificado "cuadra" con algn elemento
                        especificado del compuesto, donde "cuadrar" se define
                        como que el predicado (pred) especificado devuelve
                        TRUE cuando se aplica a algn elemento del compuesto
                        y al objeto ob, entonces POSCOMP devuelve el ndice
                        de izquierda a derecha del elemento dentro del
                        compuesto o cero. Por ejemplo, para encontrar el
                        primer real menor que 5 en una lista de reales:

                                   :: {list} 5 ' %< POSCOMP ;

       PUTLIST         ( ob #i {list} --> {list}' ) (Supone que 0<#i<=#n)
       SUBCOMP         ( comp #m #n --> comp' ) (Devuelve un subcompuesto)
                         IF #m > #n THEN comp' es nulo
                         IF #m=0    THEN #m se pone a 1
                         IF #n=0    THEN #n se pone a 1
                         IF #m > LONGitud(comp) THEN comp' es nulo
                         IF #n > LONG(comp) THEN #n se pone a LONG(comp)
       SWAPINCOMP      ( comp obj --> obj obn ... ob1 #n )
       THREE{}N        ( ob1 ob2 ob3 --> { ob1 ob2 ob3 } )
       TWO{}N          ( ob1 ob2 --> { ob1 ob2 } )
       {}N             ( obn ... ob1 #n --> {list} )
       apndvarlst      ( {list} ob --> {list}' )
                        Aade ob a la lista si ob no se encuentra dentro de
                        la lista
       matchob?        ( ob comp --> ob TRUE )
                       ( ob comp --> FALSE )
                        Determina si ob es igual (EQUAL) a algn elemento del
                        comp



























                                 Pgina 50




      11.   Objetos Etiquetados

      Estn disponibles las siguientes palabras para manipular objetos
      etiquetados. Recuerda que un objeto puede tener etiquetas mltiples.

   %>TAG           ( ob % --> tagged )
                        Etiqueta ob con %

   >TAG            ( ob $ --> tagged )
                        Etiqueta ob con $

   ID>TAG          ( ob id/lam --> tagged )
                        Etiqueta ob con id

   STRIPTAGS       ( tagged --> ob )
                        Elimina todas las etiquetas

   STRIPTAGSl2     ( tagged ob' --> ob ob' )
                        Quita las etiquetas del objeto etiquetado del nivel 2

   TAGOBS          ( ob $ --> tagged )
                   ( ob1... obn {$1 ... $n} --> tagged_1 ... tagged_n)
                        Etiqueta un objeto, o varios objetos si hay una lista
                        de etiquetas en el nivel 1
                         

   USER$>TAG       ( ob $ --> tagged )
                        Etiqueta ob con $ (vlido hasta 255 caracteres)

































                                 Pgina 51





      12.   Objetos de Unidades

      Cuando se comparan los objetos de unidad para ver si son consistentes
      dimensionalmente, se puede extraer una cadena hex, llamada "cadena de
      cantidad", usando la palabra U>NCQ. Esta cadena de cantidad contiene
      informacin acerca de que unidades hay y se puede comparar directamente
      con otra cadena de cantidad. Si coinciden las cadenas de cantidad, se
      puede decir que los dos objetos de unidad son dimensionalmente
      consistentes. U>NCQ tambin devuelve dos nmeros reales extendidos que
      consisten en el nmero y un factor de conversin a las unidades
      bsicas.

       U>NCQ           ( unidad --> n%% cf%% qhxs )
                        Devuelve el nmero, el factor de conversin y la
                        cadena de cantidad hex (qhxs)
       UM=?            ( unidad1 unidad2 --> %flag )
                        Devuelve %1 si dos obs unidades son iguales
       UM#?            ( unidad1 unidad2 --> %flag )
                        Devuelve 1% si unidad1 <> unidad2
       UM<?            ( unidad1 unidad2 --> %flag )
                        Devuelve %1 si unidad1 < unidad2
       UM>?            ( unidad1 unidad2 --> %flag )
                        Devuelve %1 si unidad1 > unidad2
       UM<=?           ( unidad1 unidad2 --> %flag )
                        Devuelve %1 si unidad1 <= unidad2
       UM>=?           ( unidad1 unidad2 --> %flag )
                        Devuelve %1 si unidad1 >= unidad2
       UM>U            ( % unidad --> unidad' )
                        Reemplaza la parte numrica de un objeto unidad 
       UM%             ( unidad %porcentaje --> unidad' )
                        Devuelve un porcentaje de un objeto unidad
       UM%CH           ( unidad1 unidad2 --> % )
                        Devuelve la diferencia porcentual
       UM%T            ( unidad1 unidad2 --> % )
                        Devuelve la fraccin porcentual
       UM+             ( unidad1 unidad2 --> unidad3 )
                        Suma
       UM-             ( unidad1 unidad2 --> unidad3 )
                        Resta
       UM*             ( unidad1 unidad2 --> unidad3 )
                        Multiplicacin
       UM/             ( unidad1 unidad2 --> unidad3 )
                        Divisin
       UM^             ( unidad1 unidad2 --> unidad3 )
                        Potencia
       UM1/            ( unidad --> unidad' )
                        Inverso
       UMABS           ( unidad --> unidad' )
                        Valor absoluto
       UMCHS           ( unidad --> unidad' )
                        Cambio de signo
       UMCONV          ( unidad1 unidad2 --> unidad1' )
                        Convierte unidad1 a las unidades de unidad2
       UMCOS           ( unidad --> unidad' )
                        Coseno
       UMMAX           ( unidad1 unidad2 --> unidad? )
                        Devuelve la mayor de unidad1 y unidad2



                                 Pgina 52






       UMMIM           ( unidad1 unidad2 --> unidad? )
                        Devuelve la menor de unidad1 y unidad2 
       UMSI            ( unidad --> unidad' )
                        Convierte a las unidades bsicas SI
       UMSIN           ( unidad --> unidad' )
                        Seno
       UMSQ            ( unidad --> unidad' )
                        Cuadrado
       UMSQRT          ( unidad --> unidad' )
                        Raz cuadrada
       UMTAN           ( unidad --> unidad' )
                        Tangente
       UMU>            ( unidad --> % unidad' )
                        Devuelve la parte numrica y la parte normalizada de
                        unidad de un objeto de unidad
       UMXROOT         ( unidad1 unidad2 --> unidad3 )
                        unidad1^1/unidad2
       UNIT>$          ( unidad --> $ )
                        Descompila un objeto unidad a una cadena de texto








































                                 Pgina 53






      13.   Variables Temporales y Entornos Temporales

      Una de las caractersticas implementadas en RPL es la capacidad de
      crear variables temporales ("variables locales", "variables lambda")
      cuyos nombres los da el programador y que se pueden destruir fcilmente
      cuando no se necesitan ms. Estas variables temporales sirven para
      varios propsitos importantes. Primero de todo, se pueden usar para
      eliminar las manipulaciones de la pila dentro de un programa, lo que
      hace la tarea de seguir la pila (rastrearla) mucho ms fcil y facilita
      la depuracin. Adems, son esenciales para la implementacin de
      programas que toman un nmero indefinido de parmetros de la pila y
      quieren salvar uno o ms de esos parmetros.

      Las variables temporales se referencian con objetos identificadores
      temporales ("nombres locales") y la unin entre un objeto identificador
      temporal y su valor est soportada por estructuras en memoria llamadas
      entornos temporales. (Esto es el anlogo RPL de la "unin lambda" en
      Lisp).

      Los entornos temporales se apilan en orden cronolgico. Esto permite
      que el programador pueda crear sus propias variables temporales
      "privadas" sin que exista la posibilidad que interfieran con aquellas
      creadas por otros. Cuando se ejecuta un objeto identificador temporal,
      se realiza una bsqueda a travs de la pila de entornos temporales,
      empezando en el creado ms recientemente y yendo hacia atrs por los
      entornos temporales anteriores, si hiciera falta. Cuando se produce una
      coincidencia entre el objeto identificador temporal que se est
      ejecutando y un objeto identificador temporal en uno de los entornos
      temporales, se sube a la pila de datos el objeto unido a ese
      identificador. La ejecucin de un objeto identificador temporal sin
      ninguna unin es una condicin de error.

      Los procesos de crear un entorno temporal y asignarle valores iniciales
      a sus variables temporales se consiguen simultneamente con el objeto
      suministrado BIND. BIND espera una lista de objetos identificadores
      temporales en la cima de la pila de datos y al menos tantos objetos
      (excluyendo la lista) en la pila como objetos identificadores
      temporales haya en la lista. BIND crear entonces un entorno temporal y
      unir cada objeto identificador temporal de la lista con un objeto de
      la pila, eliminando ese objeto de la pila.

      La ejecucin posterior de cualquier objeto identificador temporal de la
      lista devolver el objeto unido a l. El valor unido a un objeto
      identificador temporal se puede cambiar usando STO exactamente del
      mismo modo que un valor "unido" a un objeto identificador (nombre
      global). 

      La disolucin de un entorno temporal se consigue con el objeto
      suministrado ABND (contraccin de "abandonar"). ABDN elimina el entorno
      temporal que est en la cima de la pila de entornos temporales. No se
      pueden eliminar variables temporales individuales de un entorno
      temporal; se tiene que abandonar todo el entorno temporal.







                                 Pgina 54






      Observa que el compilador RPL no comprueba si hay un ABND asociado con
      cada BIND. Puedes incluir los dos en un mismo programa o los puedes
      poner en programas separados, como prefieras, sin ninguna otra
      restriccin que las exigencias de la buena prctica de la programacin
      estructurada. Esto tambin quiere decir que debes recordar incluir el
      ABND en algn punto, si no, puedes dejar entornos innecesarios en la
      memoria despus de terminar la ejecucin del programa. (En RPL de
      usuario no tienes tal libertad. La palabra estructural -> tiene BIND
      incorporado en ella y el analizador de la lnea de comandos exige que
      haya el >> o el ' correspondiente que incluye el ABND.)


      13.1  Estructura del Area de Entornos Temporales

      A continuacin se muestra la estructura del rea de entornos
      temporales.

                            --------------------------
                            |   Campo de Enlace      |-----+      (El primer
                    ---------------------------------|     | entorno temporal
                    |   Primer Entorno Temporal      |     | es el creado ms
                    ----------------------------------     |  recientemente) 
                                                           |               
                            --------------------------     |    
               +------------|   Campo de Enlace      |<----+
               |    ---------------------------------|
               |    |   Segundo Entorno Temporal     |
               |    ----------------------------------
               .                       .
               .                       .
               .                       .
               |             -------------------------
               +-----------> |   Campo de Enlace     |-----+
                    ---------------------------------|     |
                    |    Ultimo Entorno Temporal     |     |
                    ----------------------------------     |
                                                           |
                             -------------------------     |
                             |          0            |<----+
                             -------------------------
                                                               (memoria alta)


















                                 Pgina 55






      Cada entorno temporal consiste en una palabra de proteccin (el cuerpo
      de un objeto entero binario) que se usa en el control de errores,
      seguida por una secuencia de uno o ms pares de punteros de objeto. El
      primer puntero de objeto en cada par es la direccin de un objeto
      identificador temporal y el segundo puntero de objeto en cada par es la
      direccin del objeto unido a ese objeto identificador temporal. Todos
      los punteros de objeto en un entorno temporal son actualizables. A
      continuacin se muestra la estructura de cada entorno temporal dentro
      del rea de entornos temporales:

         -----------------------------------------------------  (direcciones
         |                Palabra de Proteccin              |   bajas)
         |---------------------------------------------------|
         |        -> Objeto Identificador Temporal 1         |
         |---------------------------------------------------|
         | -> Objeto Unido al Objeto Identificador Temporal 1|
         |---------------------------------------------------|
         |         -> Objeto Identificador Temporal 2        |
         |---------------------------------------------------|
         | -> Objeto Unido al Objeto Identificador Temporal 2|
         |---------------------------------------------------|
         |                      .                            |
         |                      .                            |
         |                      .                            |
         |---------------------------------------------------|
         |         -> Objeto Identificador Temporal N        |
         |---------------------------------------------------|
         | -> Objeto Unido al Objeto Identificador Temporal N|
         -----------------------------------------------------  (direcciones
                                                                 altas)





























                                 Pgina 56





      13.2  Variables Temporales Con Nombre versus Sin Nombre

      Las variables temporales normalmente se nombran con el correspondiente
      identificador temporal en la lista usada por BIND. Los nombres de la
      lista se usan en el mismo orden en que los objetos unidos aparecen en
      la pila -- el ltimo identificador de la lista corresponde al objeto en
      el nivel 1, el identificador anterior al ltimo corresponde al objeto
      en el nivel 2 y as sucesivamente. En el siguiente ejemplo, el entero
      binario ONE se une a Var1 y TWO se une a Var2

           ONE TWO
           {
             ' LAM Var1
             ' LAM Var2
           }
           BIND                ( Une ONE con la variable temporal Var1 y TWO
                                 con la variable temporal Var2 )
           ...
           LAM Var1            ( Llama a ONE desde Var1 )
           ...
           LAM Var2            ( Llama a TWO desde Var2 )
           ...
           ' LAM Var1 STO      ( Almacena un nuevo objeto en Var1 )
           ...
           ABND                ( Abandona el entorno temporal )


      Los identificadores temporales pueden contener cualquier carcter de
      texto excepto que no deberas empezar los nombres con ' o # ya que
      tales nombres estn reservados para los programas incorporados en ROM.
      Por razones parecidas, se recomienda que uses nombres que no entren en
      conflicto con los nombres generados por el usuario; un modo fcil de
      asegurarse de esto es incluir un carcter ilegal, tal como uno de los
      delimitadores de objetos, en tus nombres.


























                                 Pgina 57





      Si NO HAY NINGUNA POSIBILIDAD que se cree otro entorno temporal encima
      del entorno que vas a crear, se pueden usar los nombres nulos para
      ahorrar memoria. Hay varias palabras de utilidades que te permiten
      acceder a variables locales en el entorno superior mediante su nmero
      de posicin, que es ms rpido que la resolucin ordinaria de un
      nombre. Por ejemplo, el ejemplo anterior sera as:

         ::
           ONE TWO
           { NULLLAM NULLLAM }
           BIND                ( Une ONE y TWO a dos variables temporales con
                                 nombres nulos )
           ...
           2GETLAM             ( Llama a ONE desde la primera variable )
           ...
           1GETLAM             ( Llama a TWO desde la ltima variable )
           ...
           2PUTLAM             ( Almacena un nuevo objeto en la primera
                                 variable )
           ...
           ABND                ( Abandona el entorno temporal )
         ;

      La numeracin comienza con la ltima variable temporal (o sea, en el
      mismo orden que el nmero del nivel de la pila).



































                                 Pgina 58




       13.3  Palabras Proporcionadas para las Variables Temporales

      Se proporcionan las siguientes palabras para trabajar con variables
      temporales. El trmino "lamob" se usa en este caso para indicar un
      objeto llamado desde una variable temporal.

       1ABNDSWAP       ( ob --> lamob ob )
                        Hace :: 1GETLAM ABND SWAP ;
       1GETABND        ( --> lamob )
                        Hace :: 1GETLAM ABND ;
       1GETLAM
        ...            ( --> ob )
       22GETLAM         Devuelve el contenido del ensimo lam

       1GETSWAP        ( ob --> lamob ob )
                        Hace :: 1GETLAM SWAP ;
       1LAMBIND        ( ob --> )
                        Hace :: 1NULLLAM{} BIND ;
       1NULLLAM{}      ( --> { NULLLAM } )
                        Devuelve una lista con un lam nulo
       1PUTLAM
        ...            ( ob --> )
       22PUTLAM         Almacena ob en el ensimo lam

       2GETEVAL        ( --> ? )
                        Llama y evala el ob en el segundo lam
       @LAM            ( id --> ob TRUE )
                       ( id --> FALSE )
                        Llama lam por nombre, devuelve ob y TRUE si id
                        existe; si no, FALSE
       ABND            ( --> )
                        Abandona el entorno de variables tempor. de la cima
       BIND            ( ob ... { id ... } --> )
                        Crea un nuevo entorno de variables temporales
       CACHE           ( obn ... ob1 n lam --> )
                        Salva n objetos ms la cuenta n en un entorno
                        temporal, estando unido cada objeto al mismo
                        identificador lam. El ltimo par tiene la cuenta.
       DUMP            ( NULLLAM --> ob1..obn n ) 
                        DUMP es esencialmente el inverso de CACHE, PERO: SOLO
                        funciona cuando el nombre cacheado es NULLLAM y
                        SIEMPRE hace una recoleccin de basura.
       DUP1LAMBIND     ( ob --> ob )
                        Hace DUP y luego 1LAMBIND
       DUP4PUTLAM      ( ob --> ob )
                        Hace DUP y luego 4PUTLAM
       DUPTEMPENV      ( --> )
                        Duplica el entorno temporal de la cima y borra la
                        palabra de proteccin.
       GETLAM          ( #n --> ob )
                        Devuelve el objeto de la ensima variable temporal
       NULLLAM         ( --> NULLLAM )
                        Nombre de variable temporal nulo
       PUTLAM          ( ob #n --> )
                        Almacena ob en la ensima variable temporal
       STO             ( ob id --> )
                        Almacena ob en la variable global/temp. con nombre.
       STOLAM          ( ob id --> )
                        Almacena ob en la variable temporal con nombre.


                                 Pgina 59






      13.4  Sugerencias para la Codificacin

      La caracterstica DEFINE del compilador RPL se puede usar para combinar
      la legibilidad de las variables con nombre con la velocidad y eficacia
      de las variables con nombres nulos. Por ejemplo:

         DEFINE RclCodigo  1GETLAM
         DEFINE StoCodigo  1PUTLAM
         DEFINE RclNombre  2GETLAM
         DEFINE StoNombre  2PUTLAM
         ::
           ...
           { NULLLAM NULLLAM }
           BIND                ( Une dos objetos a las variables temporales 1
                                 y 2 ambas con nombres nulos )
           ...
           RclCodigo           ( Llama el contenido de la ltima variable )
           ...
           RclNombre           ( Llama el contenido de la primera variable )
           ...
           StoCodigo           ( Almacena un objeto en la primera variable )
           ...
           ABND                ( Abandona el entorno temporal )
         ;

      Si se va a usar un gran nmero de variables temporales sin nombre, he
      aqu un truco que ahorra cdigo:

      Reemplaza:

               ...
               {
                 NULLLAM NULLLAM NULLLAM NULLLAM
                 NULLLAM NULLLAM NULLLAM NULLLAM
                 NULLLAM NULLLAM NULLLAM NULLLAM
                 NULLLAM NULLLAM NULLLAM NULLLAM
                 NULLLAM NULLLAM NULLLAM NULLLAM
                 NULLLAM NULLLAM NULLLAM NULLLAM
               } BIND
               ...

       Con:

               NULLLAM TWENTYFOUR NDUPN
               TWENTYFOUR {}N BIND

      El primer mtodo gasta 67.5 bytes mientras que el ltimo mtodo gasta
      15 bytes, con lo que se ahorran 52.5 bytes!

      Tambin puedes usar TWENTYFOUR ' NULLAM CACHE, que es ms corto an y
      no requiere crear la lista de identificadores nulos en tempob. Observa,
      sin embargo, que CACHE aade una variable temporal extra (para mantener
      la cuenta), de modo que todos los nmeros de posicin de las variables
      difieren en uno con respecto a los mtodos anteriores.





                                 Pgina 60






      14.   Chequeo de Argumentos       

      Cualquier objeto programa que un usuario puede ejecutar directamente
      debera asegurarse que estn presentes el nmero y tipo correctos de
      argumentos para evitar problemas. Si en ltimo trmino el objeto va a
      ser un comando de biblioteca, entonces debera seguir la convencin de
      la estructura de los comandos (ver seccin 2.6):

               :: CK0 ... ; para comandos con 0 argumentos o

               :: CK<n>&Dispatch tipo1 accin1
                                 tipo2 accin2
                                      ...
                                 tipon accinn
               ;

      para comandos con <n> argumentos, donde tipoi es un cdigo de tipo y
      accini es el correspondiente destino del despacho/envo (o sea, accin
      correspondiente a realizar) para esa combinacin de tipos o 

               :: CKN ... ;   para comandos que toman un nmero de argumentos
                              especificado por un nmero real en el nivel 1
                              (como PICK o ->LIST).

      CK<n>&Dispatch es realmente una combinacin de CK<n> y CK&DISPATCH1.
      Hay unos pocos comandos incorporados (p.ej. TYPE) que usan las dos
      palabras en vez de la forma combinada, pero todas las funciones
      algebraicas deben usar CK<n>&Dispatch ya que estas palabras tambin
      sirven para identificar el nmero de argumentos usados por una funcin.

      Si un objeto no va a ser un comando de biblioteca, entonces debera
      tener la siguiente estructura:

               :: CK0NOLASTWD ... ; en los programas con 0 argumentos o

               :: CK<n>NOLASTWD  CK<n>&DISPATCH1   type1 action1
                                                   type2 action2
                                                      ...
                                                   typen actionn
               ;

               para programas con <n> argumentos o

               :: CKNNOLASTWD ... ; 

               para programas que toman tantos argumentos como se especifica
               en el nivel 1












                                 Pgina 61



      14.1  Nmero de Argumentos

      Las siguientes palabras verifican que haya 0-5 argumentos en la pila y
      emiten el mensaje de error "Faltan Argumentos" si no es as.
      
       CK0, CK0NOLASTWD                No se requiere ningn argumento
       CK1, CK1NOLASTWD                Se requiere un argumento
       CK2, CK2NOLASTWD                Se requieren dos argumentos
       CK3, CK3NOLASTWD                Se requieren tres argumentos
       CK4, CK4NOLASTWD                Se requieren cuatro argumentos
       CK5, CK5NOLASTWD                Se requieren cinco argumentos

      Cada palabra CK<n>... "marca" la pila por debajo del <en>simo
      argumento y si est activada la capacidad de recuperacin de
      argumentos, guarda una copia de los <n> argumentos en el rea de salvar
      ltimos argumentos. Si se produce un error que se controla por el
      controlador de errores del bucle externo, entonces se borra la pila
      hasta el nivel marcado (esto elimina cualquier objeto descarriado que
      no hubiera sido puesto all por el usuario). Si est activado el
      sistema de recuperacin de argumentos, entonces de reponen en la pila
      los argumentos guardados.

      Cualquier CK<n> tambin anota el comando en el que se ejecuta y de
      nuevo lo hace por el controlador de errores del bucle externo, que usa
      el nombre del comando como parte del mensaje de error que se muestra.
      Un CK<n> slo se debera usar en los comandos de biblioteca y debe ser
      el primer objeto del programa del comando. CK<n>NOLASWD no anota el
      comando y se puede usar en cualquier punto. Sin embargo, no es en
      general una buena idea ejecutar estas palabras excepto:

      *  al principio de un objeto ejecutado por el usuario o

      *  inmediatamente despus de la ejecucin de cualquier procedimiento de
         usuario.

      Los procedimientos de usuario slo se deberan ejecutar cuando la pila
      solo contiene objetos de usuario; el CK<n>NOLASTWD (usualmente
      CK0NOLASTWD) se ejecuta inmediatamente despus del procedimiento de
      usuario para actualizar la marca de guardar la pila para proteger los
      resultados del procedimiento en la pila. Esto normalmente se hace
      conjuntamente con 0LASTOWDOB!, que borra la salvaguarda del comando
      hecha por el ltimo CK<n> ejecutado dentro del procedimiento de
      usuario, de modo que ese comando no se identifique como el culpable de
      cualquier error posterior. Son palabras tiles para estos propsitos:


               AtUserStack     que es :: CK0NOLASTWD 0LASTOWDOB! ;
               CK1NoBlame      que es :: 0LASTOWDOB! CK1NOLASTWD ;

      Los anlogos de CK<n> y CK<n>NOLASTWD para los objetos que toman un
      nmero de argumentos especificados por la pila son CKN y CKNNOLASTWD.
      Ambas palabras comprueban que haya un nmero real en el nivel 1 de la
      pila y luego comprueban si hay ese nmero de objetos adicionales en la
      pila. La pila se marca en el nivel 2 y slo se restaura el nmero real
      con LAST ARG.







                                 Pgina 62






      14.2  Despachar segn el Tipo de Argumento

      Las palabras CK&DISPATCH1 y CK&DISPATCH0 proporcionan un mecanismo de
      despachar-por-tipo (las palabras CK<n>&Dispatch incluyen el mismo
      mecanismo, de modo que la siguiente discusin se les aplica tambin a
      ellas), que proporciona una bifurcacin directa de acuerdo con los
      tipos de objeto de hasta cinco argumentos a la vez. Cada palabra va
      seguida por un nmero indefinido de pares de objetos. Cada par consiste
      en un entero binario o un puntero de objeto a un entero binario,
      seguido por cualquier objeto o puntero de objeto (el uso exclusivo de
      punteros de objeto garantiza el despacho ms rpido):

               ...
            CK&DISPATCH1   #tipo1 accin1
                           #tipo2 accin2
                               ...        
                           #tipon accin3
         ;

      La secuencia de pares de objeto debe terminar con un SEMI (;).      

      CK&DISPATCH1 procede as: Por cada tipoi, desde el tipo1 hasta el
      tipon, si tipoi coincide con la configuracin de la pila entonces se
      ejecuta la accini, descartndose el resto de las palabras que contiene
      CK&DISPATCH1. Si no se encuentra ninguna coincidencia, se informa del
      error "Tipo de Argumento Incorrecto".

      Si se hace una pasada completa por la tabla sin ninguna coincidencia,
      CK&DISPATCH1 hace una segunda pasada por la tabla, eliminando esta vez
      las etiquetas que pudieran haber en los objetos de la pila y se
      comparan los objetos que as quedan con los tipos requeridos.




























                                 Pgina 63






      La palabra CK&DISPATCH0 no realiza el segundo pase que quita las
      etiquetas. Esta palabra solo se debera usar cuando es importante
      encontrar un objeto etiquetado. El comportamiento general de la HP 48
      es considerar las etiquetas como algo auxiliar de lo etiquetado y por
      tanto se debe usar CK&DISPATCH1 en la mayora de los casos.

      El entero binario tipoi se codifica nominalmente as:

               #nnnnn
                |||||
                ||||+-- Tipo de argumento del nivel 1
                |||+--- Tipo de argumento del nivel 2
                ||+---- Tipo de argumento del nivel 3
                |+----- Tipo de argumento del nivel 4
                +------ Tipo de argumento del nivel 5

      Cada "n" es un dgito hexadecimal que representa un tipo de objeto,
      como se muestra en la tabla de abajo. As #00011 representa dos nmeros
      reales; #000A0 indica un objeto de la clase simblico (symb, id o lam)
      en el nivel 2 y cualquier tipo de objeto en el nivel 1. Tambin hay
      tipos de objetos de dos dgitos, que terminan en F; por tanto, usar
      cualquiera de estos reduce el nmero total de argumentos que se pueden
      codificar en un solo entero de tipoi. Por ejemplo, #13F4F representa un
      nmero real en el nivel 3, un nmero real extendido en el nivel 2 y un
      complejo extendido en el nivel 1.

      La siguiente tabla muestra los valores de los dgitos hex para cada
      tipo de argumento. La columna "# nombre" muestra el nombre del puntero
      de objeto del entero binario correspondiente que se puede usar para una
      funcin de un solo argumento. El captulo de "Enteros Binarios"
      contiene una lista de los enteros binarios incorporados que se pueden
      usar en diversas combinaciones comunes de dos argumentos.

               Valor   Argumento             # nombre  TYPE del Usuario
               -----   ----------------      --------  ----------------
                 0     Cualquier Objeto      any
                 1     Nmero Real           real          0
                 2     Nmero Complejo       cmp           1
                 3     Cadena de Caracteres  str           2
                 4     Formacin             arry        3,4
                 5     Lista                 list          5
                 6     Nombre Global         idnt          6
                 7     Nombre Local          lam           7
                 8     Secundario            seco          8
                 9     Simblico             symb          9
                 A     Clase Simblico       sym       6,7,9
                 B     Cadena Hex            hxs          10
                 C     Objeto Grfico        grob         11
                 D     Objeto Etiquetado     TAGGED       12
                 E     Objeto Unidad         unitob       13
                0F     Puntero ROM                        14
                1F     Entero Binario                     20
                2F     Directorio                         15
                3F     Real Extendido                     21
                4F     Complejo Extendido                 22
   



                                 Pgina 64




                5F     Formacin Encadenada               23
                6F     Carcter                           24
                7F     Objeto Cdigo                      25
                8F     Biblioteca                         16
                9F     Backup                             17
                AF     Biblioteca de Datos                26
                BF     Objeto externo1                    27
                CF     Objeto externo2                    28
                DF     Objeto externo3                    29
                EF     Objeto externo4                    30



















































                                 Pgina 65




      14.3  Ejemplos

      Los comandos incorporados y otras palabras proporcionan buenos ejemplos
      del esquema de comprobar-y-despachar. A continuacin la definicin del
      comando de usuario STO:

:: CK2&Dispatch
    THIRTEEN  XEQXSTO                   ( 2:cualquier ob 1:ob etiquetado )
    SIX       :: STRIPTAGSl2 ?STO_HERE ;( 2:cualquiera   1:id )
    SEVEN     :: STRIPTAGSl2 STO ;      ( 2:cualquiera   1:lam )
    NINE      :: STRIPTAGSl2 SYMSTO ;   ( 2:cualquiera   1:symb )
    # 000c8   PICTSTO                   ( 2:grob         1:programa [PICT] )
    # 009f1   LBSTO                     ( 2:backup ob    1:nmero real )
    # 008f1   LBSTO                     ( 2:biblioteca   1:nmero real )
;

      Como quiera que STO es un comando, empieza con CK2&Dispatch, que
      verifica que haya al menos dos argumentos presentes, los salva y salva
      tambin el comando STO para el control de errores, luego despacha
      (enva) a uno de los objetos accin listados en la tabla de despachos.
      Si el objeto del nivel uno est etiquetado, STO enva a la palabra
      XEQSTO. Si es un nombre global (id), STO ejecuta :: STRIPTAGSl2
      ?STO_HERE ;, que est embebido directamente dentro del programa STO. Y
      as sucesivamente hasta la ltima opcin, que es un despacho (envo) a
      LBSTO cuando los argumentos son una biblioteca en el nivel 2 y un
      nmero real en el nivel 1.

      El comando TYPE proporciona un ejemplo de despacho que est situado en
      un punto distinto del inicio del comando. TYPE es un comando, pero su
      contador de argumentos y su despachador segn el tipo de los argumentos
      estn separados de modo que la ltima parte puede ser llamada por otras
      palabras del sistema que no quieren marcar la pila:

       ::
         CK1
         :: CK&DISPATCH0
               real             %0
               cmp              %1
               str              %2
               arry             XEQTYPEARRY
               list             %5
               id               %6
               lam              %7
               seco             TYPESEC ( 8, 18, o 19 )
               symb             %9
               hxs              %10
               grob             % 11
               TAGGED           % 12
               unitob           % 13
               rompointer       % 14
               THIRTYONE ( # )  % 20
               rrp              % 15
               # 3F ( %% )      % 21
               # 4F ( C%% )     % 22
               # 5F ( LNKARRY ) % 23
               # 6F ( CHR )     % 24
               # 7F ( CODE )    % 25
               library          % 16



                                 Pgina 66






               backup           % 17
               # AF             % 26 ( Biblioteca de Datos )
               any              % 27 ( external )
         ;
         SWAPDROP
       ;

      Aqu se usa CK&DISPATCH0 aunque CK&DISPATCH1 tambin funcionara ya que
      los objetos etiquetados estn listados explcitamente en la tabla de
      despachos (envos). Observa tambin que el ltimo tipoi es "any"
      (cualquiera) lo que significa que el tipo 27 se devuelve cuando el
      objeto es cualquier tipo no listado previamente. 

      El programa "interior" (el que empieza despus de CK1) es el cuerpo de
      la palabra del sistema XEQTYPE.












































                                 Pgina 67




      15.   Estructuras de Control de Bucles

      Hay disponibles dos tipos de estructuras de bucles - los bucles
      indefinidos y los bucles definidos.


      15.1  Bucles Indefinidos

      Los bucles indefinidos se construyen combinando las siguientes palabras
      RPL:

          BEGIN ( --> )
            Copia el puntero del intrprete (la variable RPL I) en la pila de
            retornos. Tambin llamada IDUP

          UNTIL ( flag --> )
            Si flag es TRUE, elimina el puntero de la cima de la pila de
            retornos, si no, copia ese puntero al puntero del intrprete.

          WHILE ( flag --> )
            Si flag es TRUE, entonces no hace nada. Si no, elimina el primer
            puntero de la pila de retornos y hace que el puntero del
            intrprete se salte los dos siguientes objetos.

          REPEAT ( --> )
            Copia el primer puntero de la pila de retornos al puntero del
            intrprete

          AGAIN ( --> )


      El bucle WHILE es un bucle indefinido:

               BEGIN
                 <clusula test>
               WHILE
                 <objeto del bucle>
               REPEAT


      El bucle WHILE ejecuta <clusula test> y si el resultado es la bandera
      del sistema TRUE, ejecuta el <objeto del bucle> y repite; si no, sale y
      sigue justo pasado el REPEAT. El bucle WHILE no se ejecuta nunca si la
      primera vez que se evala la <clusula test> devuelve FALSE.

      La accin que realiza WHILE precisa que el <objeto del bucle> sea un
      slo objeto. Sin embargo, el compilador RPL combina automticamente
      todos los objetos que haya entre WHILE y REPEAT en un slo objeto de
      modo que

               BEGIN
                 <clusula test>
               WHILE
                 ob1 ... obn
               REPEAT

      se compila realmente como




                                 Pgina 68






               BEGIN
                 <clusula test>
               WHILE
                 :: ob1 ... obn ;
               REPEAT


      Otro bucle indefinido comn es BEGIN...UNTIL:

               BEGIN
                 <clusula del bucle>
               UNTIL


      Este bucle se ejecuta al menos una vez, al contrario que el bucle
      WHILE, que no ejecuta su objeto del bucle si el test inicial es falso.
      La palabra UNTIL espera una bandera (TRUE o FALSE).

      El bucle BEGIN...AGAIN no tiene test:

               BEGIN
                 <clusula del bucle>
               AGAIN

      Para que se termine este bucle se precisa que suceda un error o que se
      manipule directamente la pila de retornos.

































                                 Pgina 69




      15.2  Bucles Definidos

      Los bucles definidos con un contador de bucles se consiguen en RPL por
      medio de los DO Loop. La palabra DO toma dos objetos enteros binarios
      de la pila y almacena el objeto de la cima como el ndice y el otro
      como el valor de parada en un entorno DoLoop especial. DO tambin copia
      el puntero del intrprete en la pila de retornos. Los entornos DoLoop
      estn apilados, de modo que se pueden anidar indefinidamente. El ndice
      ms interno (superior) se reclama (se llama) con INDEX@; el ndice en
      el segundo entorno se reclama (se llama) con JINDEX@. El valor de
      parada ms interno (superior) est disponible va ISTOP@.

      Los complementos de DO son LOOP y +LOOP. LOOP incrementa el valor del
      ndice del entorno DoLoop ms interno (el entorno DoLoop de la cima de
      la pila de entornos DoLoop); luego, si el (nuevo) valor es mayor que o
      igual al valor de parada, LOOP elimina el puntero de la cima de la pila
      de retornos y elimina el entorno DoLoop ms interno. Si no, LOOP acta
      copiando el puntero de la cima de la pila de retornos al puntero del
      intrprete. La forma estndar de un DoLoop es

                    parada inicio DO <clusula del bucle> LOOP,

      que ejecuta <clusula del bucle> para cada valor del ndice desde
      inicio hasta parada-1.

      +LOOP es parecido a LOOP excepto que toma un entero binario de la pila
      e incrementa el contador del bucle en esa cantidad en lugar de en 1.


      15.2.1   Palabras Proporcionadas

      Se proporcionan las siguientes palabras para usarlas con los bucles DO.
      Las palabras marcadas con * no se reconocen como especiales por el
      compilador RPL, de modo que deberas incluir directivas del compilador
      para evitar mensajes de advertencia. Por ejemplo, #1+_ONE_DO puede ir
      seguido de (DO) que, para el compilador, hace de pareja con el prximo
      LOOP pero que no genera ningn cdigo compilado (Ver RPLCOMP.DOC)

       #1+_ONE_DO *    ( #fin --> )
                        Equivalente a #1+ ONE DO; usada a menudo para
                        ejecutar un bucle #fin veces
       DO              ( #fin #inicio --> )
                        Empieza el bucle DO 
       DROPLOOP *      ( ob --> )
                        Hace un DROP y luego LOOP
       DUP#0_DO *      ( # --> # )
                        Empieza el bucle # ...#0 DO 
       DUPINDEX@       ( ob --> ob ob #ndice )
                        Hace DUP, luego devuelve el valor del ndice del
                        entorno DoLoop ms interno.
       ExitAtLOOP      ( --> )
                        Almacena cero en el valor de parada del entorno
                        DoLoop ms interno.
       INDEX@          ( --> #ndice )
                        Devuelve el ndice del entorno DoLoop ms interno
       INDEX@#-        ( # --> #' )
                        Resta a # el valor del ndice del entorno DoLoop ms
                        interno.



                                 Pgina 70






       INDEXSTO        ( # --> )
                        Almacena # como el ndice del entorno DoLoop ms
                        interno.
       ISTOP@          ( --> #stop )
                        Devuelve el valor de parada del entorno DoLoop ms
                        interno
       ISTOPSTO        ( # --> )
                        Almacena el nuevo valor de parada en el el entorno
                        DoLoop ms interno.
       JINDEX@         ( --> #ndice )
                        Devuelve el ndice del segundo entorno DoLoop
       LOOP            ( --> )
                        Termina una estructura de bucle
       NOT_UNTIL *     ( flag --> )
                        Termina una estructura de bucle
       ONE_DO *        ( #fin --> )
                        Comienza un Bucle #1...#fin DO
       OVERINDEX@      ( ob1 ob2 --> ob1 ob2 ob1 #ndice )
                        Hace OVER y luego devuelve el valor del ndice del
                        entorno DoLoop ms interno.
       SWAPINDEX@      ( ob1 ob2 --> ob2 ob1 #ndice )
                        Hace SWAP y luego devuelve el valor del ndice del
                        entorno DoLoop ms interno.
       SWAPLOOP *      ( ob1 ob2 --> ob2 ob1 )
                        Hace SWAP y luego LOOP
       ZEROISTOPSTO    ( --> )
                        Almacena cero como el valor de parada del entorno
                        DoLoop ms interno
       ZERO_DO *       ( #fin --> )
                        Comienza el bucle DO desde #0 hasta #fin
       toLEN_DO        ( {list} --> {list} )
                        Comienza el bucle DO con inicio = #1 y con el valor
                        de parada = #nmero-de-elementos-de-la-lista+1

      15.2.2   Ejemplos

               FIVE ZERO
               DO
                 INDEX@
               LOOP

      Devuelve los valores:

               #00000 #00001 #00002 #00003 #00004

      La siguiente secuencia muestra cada uno de los elementos (hasta 8) de
      una lista de cadenas de caracteres en una lnea distinta de la
      pantalla.

               DUPLENCOMP
               ONE_DO (DO)
                 DUP INDEX@ NTHCOMPDROP
                 INDEX@ DISPN
               LOOP





                                 Pgina 71






      Una versin ms compacta que utiliza toLEN_DO:

               toLEN_DO (DO)
                 DUP INDEX@ NTHCOMPDROP
                 INDEX@ DISPN
               LOOP

      Otra versin ligeramente ms rpida, pues evita repetidas extracciones
      de los elementos de la lista:

               INNERCOMP
               #1+_ONE_DO (DO)
                 INDEX@ DISPN
               LOOP

      Esta versin muestra los elementos en orden inverso al de las versiones
      anteriores.










































                                 Pgina 72




      16.   Generacin y Captura de Errores

      El subsistema RPL de control de errores se invoca ejecutando la palabra
      ERRJMP, o sea, cuando un objeto de la clase procedimiento desea generar
      un error, ejecuta ERRJMP (probablemente despus de actualizar los
      valores de ERROR y ERRNAME). La mecnica de ERRJMP se describir ms
      tarde.


      16.1  Captura: ERRSET y ERRTRAP

      RPL proporciona objetos procedimiento con la capacidad de interceptar
      la ejecucin del subsistema de control de errores, o sea, capturar un
      error generado por un objeto que es menor (est en un nivel inferior)
      segn el orden del entrelazado. Esta capacidad est disponible a travs
      de los objetos incorporados ERRSET y ERRTRAP usados del siguiente modo:

       :: ... ERRSET <objeto sospechoso> ERRTRAP <objeto si-error> ... ;

      Arriba, un error generado por el <objeto sospechoso> ser capturado.
      <objeto si-error> denota el objeto que se ejecutar si el <objeto
      sospechoso> genera un error. El algoritmo exacto es: Si <objeto
      sospechoso> genera un error, entonces contina la ejecucin en <objeto
      si-error>; si no, contina la ejecucin ms all de <objeto si-error>.

      La accin del <objeto si-error> es completamente flexible; cuando
      <objeto si-error> toma el control, puede examinar los valores de ERROR
      y de ERRNAME para determinar si le concierne o no el error actual. Si
      no, puede sencillamente reiniciar el subsistema ejecutando ERRJMP. Si
      le concierne, puede decidir controlar el error, o sea, borrar tanto
      ERROR como ERRNAME y NO reiniciar el subsistema. Tambin puede
      desactivar la ejecucin del resto del programa (quizs va RDROP).

      Observa que durante la ejecucin (normal) del <objeto sospechoso>, hay
      en algn sitio del "runstream" un puntero de objeto al siguiente
      ERRTRAP.


      16.2  Accin de ERRJMP

      Cuando un procedimiento RPL quiere iniciar un error, ejecuta ERRJMP que
      es el subsistema de control de errores. ERRJMP se recorre el RUNSTREAM
      desde el puntero del intrprete I hacia arriba a travs de la pila de
      retornos buscando una trampa de errores. Especficamente, ERRJMP
      elimina los cuerpos de programas pendientes del RUNSTREAM hasta que
      encuentra uno en el que su primer elemento es un puntero de objeto que
      direcciona (apunta) a ERRTRAP (este cuerpo de programa puede
      corresponder a un nivel de la pila de retornos as como tambin al
      puntero del intrprete I). Entonces se SALTA el puntero de objeto a
      ERRTRAB y contina la ejecucin ms all de l (en el <objeto
      si-error>).

      Observa, por tanto, que ERRTRAP slo se ejecuta si <objeto sospechoso>
      termina sin generar ningn error; en este caso, ERRTRAP, entre otras
      cosas, se SALTARA el <objeto si-error> y continuar la ejecucin ms
      all de l.





                                 Pgina 73







      Si un procedimiento no est meramente de paso por un error que l no
      inici, su invocacin de ERRJMP debe ir precedida por la ejecucin de
      ERRORSTO, que almacena un nmero de error en un sitio especial del
      sistema. ERROR@ devuelve el nmero de error almacenado, que lo pueden
      usar las trampas de error para determinar si quieren controlar un error
      determinado. El nmero de error se almacena y se devuelve como un
      entero binario; los 12 bits ms significativos del nmero representan
      el ID de Biblioteca de la biblioteca que contiene el mensaje de error y
      el resto de los bits indican el nmero de error dentro de la tabla de
      mensajes de la biblioteca.


      16.3  La Palabra de Proteccin

      Cada entorno temporal y cada entorno DoLoop tienen una palabra de
      proteccin. La nica razn de la existencia de esta palabra de
      proteccin es permitir al subsistema de control de errores distinguir
      los entornos temporales y DoLoop que ya existan cuando se activ la
      trampa de error de aquellos que se crearon despus que se activ la
      trampa de error. Por ejemplo, considera lo siguiente:

       ::
         ...
         { NULLLAM } BIND
         ...
         TEN ZERO DO
           ERRSET ::
             ...
             { NULLLAM } BIND
             ...
             FIVE TWO DO
               <procedimiento>
             LOOP
             ABND
           ;
           ERRTRAP
             :: "Fall el Procedimiento" FlashMsg ;
         LOOP
         ...
         ABND
         ...
       ;

      Si <procedimiento> genera un error, entonces este error ser atrapado
      por la palabra o secundario a continuacin de ERRTRAP. Sin embargo, los
      entornos temporales y DoLoop internos se deben borrar de modo que el
      procedimiento externo tenga disponible los parmetros DoLoop y las
      variables locales correctas. La palabra de proteccin sirve para apoyar
      esta funcin.

      ERRSET incrementa la palabra de proteccin del entorno temporal ms
      interno y del entorno DoLoop ms interno. Estos entornos ms internos
      tendrn por consiguiente un valor de la palabra de proteccin distinto
      de cero. (DO y BIND siempre inicializan la palabra de proteccin a
      cero).



                                 Pgina 74






      ERRTRAP y ERRJMP borran los entornos temporales y DoLoop (desde el
      primero (ms interno) hacia el ltimo (ms externo)) hasta que, en
      ambos casos, encuentran uno con la palabra de proteccin distinta de
      cero, que entonces se decrementa. Por tanto, tanto si ERRJMP ejecuta un
      <objeto si-error> o ERRTRAP sigue la ejecucin a continuacin de
      <objeto si-error>, solo estarn presentes los entornos temporales y
      DoLoop que ya existan cuando se activ ERRSET .

      Observa especialmente que la palabra de proteccin es ms que un simple
      interruptor, ya que permite un nmero prcticamente ilimitado de
      trampas de error anidadas.

      El ejemplo anterior es realmente una trampa de error bastante pobre -
      el cdigo debera determinar cual fue el error y tomar la accin
      correspondiente. Se puede usar la palabra ERROR@ para saber que error
      se produjo. Los nmero de error corresponden a los nmeros de
      mensajes - ver la tabla de mensajes en el apndice A del "HP 48, Manual
      de Referencia del Programador"


      16.4  Palabras de Error

      Se suministran las siguientes palabras para el control de errores:

       ABORT           ( --> )
                        Hace ERRORCLR y ERRJMP
       DO#EXIT         ( msj# --> )
                        Almacena un nuevo nmero de error y ejecuta ERRJMP;
                        tambin ejecuta AtUserStack
       'ERRJMP         ( --> ERRJMP )
                        Pone el objeto ERRJMP en la pila
       ERRBEEP         ( --> )
                        Genera un pitido de error
       ERRJMP          ( --> )
                        Invoca al subsistema de control de errores
       ERROR@          ( --> # )
                        Devuelve el nmero de error actual
       ERRORCLR        ( --> )
                        Almacena cero como el nmero de error
       ERROROUT        ( # --> )
                        Almacena un nuevo nmero de error y hace ERRJMP
       ERRORSTO        ( # --> )
                        Almacena un nuevo nmero de error
       ERRTRAP         ( --> )
                        Se salta el siguiente objeto del "runstream"



   










                                 Pgina 75






      17.   Test y Control

      Este captulo examina las palabras relacionadas con el control del
      flujo: bifurcaciones condicionales e incondicionales y las palabras de
      test asociadas.


      17.1  Banderas y Tests

      TRUE y FALSE son objetos incorporados que son reconocidos por las
      palabras test como banderas para tomar decisiones de bifurcacin. Las
      siguientes palabras crean o combinan banderas:

       AND ( flag1 flag2  --> flag )
            Si flag1 y flag2 son ambos TRUE entonces TRUE si no, FALSE.

       FALSE ( --> FALSE )
            Pone la bandera FALSE en la pila

       FALSETRUE       ( --> FALSE TRUE )

       FalseFalse      ( --> FALSE FALSE )

       OR ( flag1 flag2  --> flag )
            Si flag1 o flag2 (o ambos) es TRUE entonces TRUE si no, FALSE.

       ORNOT           ( flag1 flag2 --> flag3 )
            O lgico seguido de un NO lgico.

       NOT ( flag --> flag' )
            Si flag es TRUE entonces FALSE si no, TRUE.

       NOTAND          ( flag1 flag2 --> flag3 )
            NO lgico y luego Y lgico.

       ROTAND          ( flag1 ob flag2 --> ob flag3 )
            Hace ROT y luego un Y lgico.

       TRUE            ( --> TRUE )
            Coloca en la pila la bandera TRUE

       TrueFalse       ( --> TRUE FALSE )

       TrueTrue        ( --> TRUE TRUE )

       XOR             ( flag1 flag2  --> flag )
            Si tanto flag1 y flag2 son TRUE o FALSE entonces FALSE si no,
            TRUE.

       COERCEFLAG      ( TRUE --> %1 )
                       ( FALSE --> %0 )
            Convierte una bandera del sistema en una bandera nmero real.







                                 Pgina 76






      17.1.1   Tests de Objetos en General

      Las siguientes palabras comprueban el tipo de objeto y la igualdad:

       EQ              ( ob1 ob2 --> flag )
         Si los objetos ob1 y ob2 son el mismo objeto, o sea, ocupan
         fsicamente el mismo espacio en la memoria, entonces TRUE, si no,
         FALSE.

       EQUAL           ( ob1 ob2 --> flag )
         donde ob1 y ob2 no son objetos cdigo primitiva. Si los objetos ob1
         y ob2 son el mismo entonces TRUE, si no, FALSE (esta palabra es el
         equivalente en RPL del sistema del comando en RPL de usuario SAME)

       2DUPEQ          ( ob1 ob2 --> ob1 ob2 flag )
         Devuelve TRUE si ob1 y ob2 tienen la misma direccin fsica.

       EQOR            ( flag1 ob1 ob2 --> flag2 )
         Hace EQ y luego un O lgico.

       EQUALOR         ( flag1 ob1 ob2 --> flag2 )
         Hace EQUAL y luego un O lgico.

       EQOVER          ( ob1 ob2 ob3 --> ob1 flag ob1 )
         Hace EQ y luego OVER.

       EQUALNOT        ( ob1 ob2 --> flag )
         Devuelve FALSE si ob1 es igual a ob2.

      Las siguientes palabras comprueban el tipo de un objeto. Las palabras
      de la forma TYPE...? tienen un diagrama de pila ( ob --> flag ); las de
      la forma DTYPE...? o DUPTYPE...? duplican primero el objeto ( ob --> ob
      flag ).

       Palabras Test           Tipo de Objeto

       TYPEARRY?               formacin
       DTYPEARRY?
       DUPTYPEARRY?

       TYPEBINT?               entero binario
       DUPTYPEBINT?

       TYPECARRY?              formacin compleja

       TYPECHAR?               carcter
       DUPTYPECHAR?

       TYPECMP?                nmero complejo
       DUPTYPECMP?

       TYPECOL?                programa
       DTYPECOL?
       DUPTYPECOL?





                                 Pgina 77






       TYPECSTR?               cadena
       DTYPECSTR?
       DUPTYPECSTR?

       TYPEEXT?                unidad
       DUPTYPEEXT?

       TYPEGROB?               objeto grfico
       DUPTYPEGROB?

       TYPEHSTR?               cadena hex
       DUPTYPEHSTR?

       TYPEIDNT?               identificador (nombre global)
       DUPTYPEIDNT?

       TYPELAM?                identificador temporal (nombre local)
       DUPTYPELAM?

       TYPELIST?               lista
       DTYPELIST?
       DUPTYPELIST?

       TYPERARRY?              formacin real

       TYPEREAL?               nmero real
       DTYPEREAL?
       DUPTYPEREAL?

       TYPEROMP?               puntero ROM (nombre XLIB)
       DUPTYPEROMP?

       TYPERRP?                Directorio
       DUPTYPERRP?

       TYPESYMB?               Simblico
       DUPTYPESYMB?

       TYPETAGGED?             Etiquetado
       DUPTYPETAG?


      17.1.2   Comparaciones de Enteros Binarios

      Las siguientes palabras comparan enteros binarios, devolviendo TRUE o
      FALSE. La igualdad se comprueba en el sentido de EQUAL (no EQ). Se
      tratan todos los enteros binarios como "sin signo". Algunas de estas
      palabras tambin estn disponibles combinadas con las palabras de
      "casos" (ver ms abajo).

       #=      ( # #' --> flag )       TRUE si # = #'.

       #<>     ( # #' --> flag )       TRUE si # <> #' (no igual).

       #0=     ( # --> flag )          TRUE si # = 0




                                 Pgina 78






       #0<>    ( # --> flag )          TRUE si # <> 0

       #<      ( # #' --> flag )       TRUE si # < #'

       #>      ( # #' --> flag )       TRUE si # > #'

       2DUP#<  ( # #' --> # #' flag )  TRUE si # < #'

       2DUP#=  ( # #' --> # #' flag )  TRUE si # = #'

       DUP#0=  ( # --> # flag )        TRUE si # = #0

       DUP#1=  ( # --> # flag )        TRUE si # = #1

       DUP#0<> ( # --> # flag )        TRUE si # <> #0

       DUP#1=  ( # --> # flag )        TRUE si # = #1

       DUP#<7  ( # --> # flag )        TRUE si # < #7

       DUP%0=  ( % --> % flag )        TRUE si % = %0

       ONE#>   ( # --> flag )          TRUE si # > #1

       ONE_EQ  ( # --> flag )          TRUE si # es ONE (1)

       OVER#>  ( # #' --> # flag )     TRUE si # > #'

       OVER#0= ( # ob --> # ob flag )  TRUE si # es #0

       OVER#<  ( # #' --> # flag )     TRUE si # > #'

       OVER#=  ( # #' --> # flag )     TRUE si # = #'

       OVER#>  ( # #' --> # flag )     TRUE si # < #'


      17.1.3   Tests de Nmeros Decimales

      Las siguientes palabras comparan nmeros reales, reales extendidos y
      complejos, devolviendo TRUE o FALSE.

   %<      ( % %' --> flag )       TRUE si % < %'

   %<=     ( % %' --> flag )       TRUE si % <= %'

   %<>     ( % %' --> flag )       TRUE si % <> %'

   %=      ( % %' --> flag )       TRUE si % = %'

   %>      ( % %' --> flag )       TRUE si % > %'

   %>=     ( % %' --> flag )       TRUE si % >= %'

   %0<     ( % --> flag )          TRUE si % < 0




                                 Pgina 79






   %0<>    ( % --> flag )          TRUE si % <> 0

   %0=     ( % --> flag )          TRUE si % = 0

   %0>     ( % --> flag )          TRUE si % > 0

   %0>=    ( % --> flag )          TRUE si % >= 0


   %%0<=   ( %% %%' --> flag )     TRUE si %% <= %%'

   %%0<>   ( %% --> flag )         TRUE si %% <> 0

   %%0=    ( %% --> flag )         TRUE si %% = 0

   %%0>    ( %% --> flag )         TRUE si %% > 0

   %%0>=   ( %% --> flag )         TRUE si %% >= 0

   %%>     ( %% %%' --> flag )     TRUE si %% > %%'

   %%>=    ( %% %%' --> flag )     TRUE si %% >= %%'

   %%<=    ( %% %%' --> flag )     TRUE si %% <= %%'


   C%%0=   ( C%% --> flag )        TRUE si C%% = (%%0,%%0)

   C%0=    ( C% --> flag )         TRUE si C% = (0,0)


      17.2  Palabras que Operan en el "Runstream"

      N.T.> El Runstream es la secuencia de palabras (comandos, etc.) que se
            ejecutan unas detrs de otras.

      En muchos casos es deseable interrumpir el orden entrelazado normal de
      ejecucin e insertar objetos adicionales o saltarse otros en el
      runstream. Para estos propsitos se proporcionan las siguientes
      palabras.

       '  ( --> ob )

         Este es al anlogo RPL del QUOTE del Lisp y es uno de los objetos de
         control ms fundamentales, permitiendo posponer la evaluacin de un
         objeto. De modo ms preciso, supone que el cuerpo en la cima del
         RUNSTREAM no es uno vaco, o sea, que el puntero del intrprete no
         apunta a un SEMI; y (1) Si el siguiente objeto en el runstream es un
         objeto, entonces sube este objeto a la pila de datos y mueve el
         puntero del intrprete al siguiente objeto; (2) Si el siguiente
         objeto es un puntero de objeto, entonces sube lo apuntado a la pila
         de datos y salta tambin al siguiente objeto. Como ejemplo, la
         evaluacin de los secundarios

          :: # 3 # 4 SWAP ;      y      :: # 3 # 4 ' SWAP EVAL ;

         dan ambos el mismo resultado.


                                 Pgina 80






       'R  ( --> ob )
         
         Si el objeto apuntado por el puntero en la cima de la pila de
         retornos (o sea, el primer elemento en el segundo cuerpo en el
         runstream) es un objeto, entonces 'R sube este objeto a la pila de
         datos y adelanta el puntero al siguiente objeto del mismo compuesto.
         Si el puntero apunta a un puntero de objeto que no apunta a SEMI,
         entonces sube lo apuntado a la pila de datos y adelanta de modo
         similar el puntero de la pila de retornos. Si lo apuntado es SEMI,
         entonces si el primer elemento en el segundo cuerpo en el runstream
         es un puntero de objeto a SEMI, entonces sube un secundario nulo a
         la pila de datos y no adelante el puntero de la pila de retornos. 'R
         es til para definir operadores prefijos. Por ejemplo, supn que
         PREFIXSTO se define como :: 'R STO ; Entonces la secuencia PREFIXSTO
         FRED ANOTHEROBJECT subira primero FRED a la pila de datos y luego
         ejecutara STO, despus de lo cual la ejecucin contina en
         ANOTHEROBJECT.


      ticR  ( --> ob TRUE | FALSE )

         Esta palabra funciona de modo parecido a 'R, excepto que devuelve
         una bandera para indicar si se ha alcanzado el final del compuesto
         de la cima de la pila de retornos. O sea, si el puntero de la cima
         de la pila de retornos apunta a un puntero de objeto a SEMI,
         entonces ticR baja la pila de retornos y devuelve solo FALSE. Si no,
         devuelve el siguiente objeto del compuesto y TRUE, mientras adelanta
         el puntero de la pila de retornos al siguiente objeto.

       >R ( :: --> )

         Inserta el cuerpo de :: en el runstream justo debajo del de la cima.
         (O sea, sube un puntero al cuerpo de :: a la pila de retornos). Un
         ejemplo de su uso es

                         :: ' :: <foo> ; >R <bar> ;

         que provocar que, cuando se ejecute, <bar> se ejecuta antes que
         <foo>.

       R>  ( --> :: )

         Crea un objeto programa a partir cuerpo del compuesto apuntado por
         el puntero de la cima de la pila de retornos y sube el programa a la
         pila de datos y baja la pila de retornos. Ejemplo:

                       :: :: R> EVAL <foo> ; <bar> ;

         que cuando se ejecuta, causar que <bar> se ejecute antes que <foo>.


       R@ ( --> :: )

         Lo mismo que R> excepto que la pila de retornos no se baja.





                                 Pgina 81




       RDROP  ( --> )

         Baja la pila de retornos.

       IDUP  ( --> )

         Duplica el cuerpo de la cima del runstream. (O sea, sube la variable
         RPL I a la pila de retornos).

       COLA  ( --> )

         Suponiendo que el puntero del intrprete est apuntando a un objeto
         distinto de SEMI, COLA elimina el resto del cuerpo del programa
         pasado el objeto y ejecuta el objeto. Esto permite una eficiente
         recursin por la cola; la eficiencia se gana porque COLA se puede
         usar para evitar un excesivo crecimiento de los retornos pendientes.
         Un ejemplo de su uso es en una definicin de factorial:

                 fact:         :: { LAM x } BIND # 1 factpair ABND
                               ;

                 factpair:     :: LAM x #0= ?SEMI
                                  LAM x #* LAM x #1- ' LAM x
                                  STO COLA factpair
                               ;

         En este ejemplo, la importancia de COLA es que est justo antes de
         factpair en la definicin de factpair. Si no se usara, el clculo de
         n! requerira n niveles de la pila de retornos, que, cuando se
         terminara el clculo, simplemente se iran bajando todos (ya que sus
         cuerpos estaran vacos). Con la inclusin de COLA, la definicin
         usa un nmero mximo fijo de niveles, independientemente del
         argumento de la funcin.

       ?SEMI   ( flag --> )

         Sale del programa en curso si la bandera es TRUE.         

       ?SEMIDROP  ( ob TRUE --> )  o  ( FALSE --> )

         Elimina ob si la bandera es TRUE; sale del programa en curso si la
         bandera es FALSE.

       ?SKIP  ( flag --> )

         Si la bandera es TRUE, se salta el siguiente objeto a continuacin
         de ?SKIP.

       NOT?SEMI  ( flag --> )

         Sale del programa en curso si la bandera es FALSE.










                                 Pgina 82






      17.3  If/Then/Else

      La capacidad if/then/else fundamental del RPL se proporciona por medio
      de las palabras RPIT y RPITE:

       RPITE   ( flag ob1 ob2 --> ? )

         Si flag es TRUE entonces se eliminan flag y ob2 y se EVALa ob1, si
         no, se eliminan flag y ob1 y se EVALa ob2. La expresin RPL

                           ' <foo> ' <bar> RPITE

         es equivalente a la expresin FORTH

                          IF <foo> ELSE <bar> THEN

       RPIT    ( flag ob --> ? )

         Si flag es TRUE entonces se elimina flag y se EVALa ob, si no,
         simplemente se eliminan flag y ob. La expresin RPL

                                ' <foo> RPIT

         es equivalente a la expresin FORTH

                               IF <foo> THEN

      Sin embargo, tambin estn disponibles las versiones prefijo de estas
      palabras y se usan ms a menudo que las versiones sufijo:

       IT      ( flag -->  )

         Si flag es TRUE entonces ejecuta el siguiente objeto en el
         runstream; si no, se salta ese objeto. Por ejemplo,

                        DUPTYPEREAL? IT :: %0 %>C% ;

         convierte un nmero real en un nmero complejo; no hace nada si el
         argumento no es un nmero real.

       ITE     ( flag -->  )

         Si flag es TRUE entonces ejecuta el siguiente objeto del runstream y
         se salta el segundo objeto; si no, se salta el siguiente objeto y
         ejecuta el segundo. Por ejemplo,

                       DUPTYPELIST? ITE INNERCOMP ONE

         toma una lista y la descompone en sus componentes, dejando la cuenta
         (de los elementos de la lista) en la pila; con cualquier otro tipo
         de argumento distinto de una lista, sube el entero binario #1 a la
         pila.







                                 Pgina 83






      El inverso de IT es

       ?SKIP ( flag --> )

         Si flag es TRUE, se salta el siguiente objeto del runstream; si no,
         lo ejecuta.

      Tambin hay un salto incondicional:

       SKIP ( --> )

         Se salta el siguiente objeto del runstream y contina la ejecucin
         ms all de l. La secuencia SKIP ; es un NOP (no operation, o sea,
         no hace nada).

      Palabras Combinadas:

              Palabra         Pila           Equivalente

            #0=ITE      ( # --> )            #0= ITE
            #<ITE       ( # --> )            #0< ITE
            #=ITE       ( # --> )            #= ITE
            #>ITE       ( # --> )            #> ITE
            ANDITE      ( flag flag' --> )   AND ITE
            DUP#0=ITE   ( # --> # )          DUP #0= ITE
            EQIT        ( ob1 ob2 --> )      EQ IT
            EQITE       ( ob ob' --> )       EQ ITE
            DUP#0=IT    ( # --> # )          DUP #0= IT
            SysITE                           ( # --> )
            UserITE                          ( # --> )



      17.4  Palabras CASE

      La palabra case (caso) es una combinacin de ITE, COLA y SKIP. O sea,
      case toma una bandera de la pila; si es TRUE, case ejecuta el objeto
      que le sigue en el runstream mientras baja la pila de retornos al
      puntero del intrprete, descartando el resto del programa que sigue al
      objeto (como COLA). Si es FALSE, case se salta el siguiente objeto y
      contina con el programa (como SKIP). Por ejemplo, el siguiente
      programa ejecuta objetos diferentes de acuerdo con el valor de un
      entero binario en la pila:

            :: DUP #0= case ZEROCASE
               DUP ONE #= case ONECASE
               DUP TWO #= case TWOCASE
               ...
            ;










                                 Pgina 84






      Hay varias palabras que contienen a "case" como parte de sus
      definiciones. El ejemplo anterior se puede escribir de modo ms
      compacto usando OVER#=case:

            :: ZERO OVER#=case ZEROCASE
               ONE OVER#=case ONECASE
               TWO OVER#=case TWOCASE
               ...
            ;

      Lo que hacen las palabras que se listan ms abajo est generalmente
      suficientemente claro a partir de sus nombres. Los nombres tienen
      (hasta) tres partes: una parte inicial, luego "case" y luego una parte
      final. La parte inicial indica que se hace antes de la accin "case", o
      sea, "xxxcase..." es equivalente a "xxx case...". Las palabras que
      tienen una parte final despus de "case" son de dos tipos. En un tipo,
      la parte final indica el objeto mismo ejecutado condicionalmente, o
      sea, "...caseyyy" es equivalente a "...case yyy". En el otro tipo, la
      parte final es una palabra o palabras que se incorporan al siguiente
      objeto. caseDROP y casedrop son del primer y segundo tipo
      respectivamente. caseDROP es equivalente a case DROP; casedrop es como
      case con un DROP incorporado en el siguiente objeto. O sea,

      (?!)

      Palabras que hacen COLA o SKIP al siguiente objeto:

         #=casedrop    ( # # --> )
                       ( # #' --> # )
               Se debera llamar OVER#=casedrop

         %1=case       ( % --> )

         %0=case       ( % --> flag )

         ANDNOTcase    ( flag1 flag2 --> )

         ANDcase       ( flag1 flag2 --> )

         case2drop     ( ob1 ob2 TRUE --> )
                       ( FALSE --> )

         casedrop      ( ob TRUE --> )
                       ( FALSE --> )

         DUP#0=case    ( # --> # )

         DUP#0=csedrp  ( # --> # ) # <> #0
                       ( # -->   ) # = #0

         EQUALNOTcase  ( ob ob' --> )

         EQUALcase     ( ob ob' --> )






                                 Pgina 85




         EQUALcasedrp  ( ob ob' ob' --> )
                       ( ob ob' ob'' --> ob )

         EQcase        ( ob1 ob2 --> )

         NOTcase       ( flag --> )

         NOTcasedrop   ( ob FALSE --> )
                       ( TRUE --> )

         ORcase        ( flag1 flag2 --> )

         OVER#=case    ( # #' --> # )


      Palabras case que o salen o continan con el siguiente objeto:

         caseDoBadKey  ( flag --> ) Sale va DoBadKey

         caseDrpBadKey ( ob TRUE --> ) Sale va DoBadKey
                       ( FALSE --> )

         case2DROP     ( ob1 ob2 TRUE --> )
                       ( FALSE --> )

         caseDROP      ( ob TRUE --> )
                       ( FALSE --> )

         caseFALSE     ( TRUE --> FALSE )
                       ( FALSE --> )

         caseTRUE      ( TRUE --> TRUE )
                       ( FALSE --> )

         casedrpfls    ( ob TRUE --> FALSE )
                       ( FALSE --> )

         case2drpfls   ( ob1 ob2 TRUE --> FALSE )
                       ( FALSE --> )

         casedrptru    ( ob TRUE --> TRUE )
                       ( FALSE --> )

         DUP#0=csDROP  ( #0 -->  )
                       ( #  --> # ) # <> 0.
         NOTcaseTRUE   ( FALSE --> TRUE )
                       ( TRUE --> )














                                 Pgina 86




      18.   Operaciones de la Pila

      Las palabras listadas en este captulo realizan operaciones de la pila
      sencillas o mltiples.

       2DROP           ( ob1 ob2 --> )
       2DROP00         ( ob1 ob2 --> #0 #0 )
       2DROPFALSE      ( ob1 ob2 --> FALSE )
       2DUP            ( ob1 ob2 --> ob1 ob2 ob1 ob2 )
       2DUP5ROLL       ( ob1 ob2 ob3 --> ob2 ob3 ob2 ob3 ob1 )
       2DUPSWAP        ( ob1 ob2 --> ob1 ob2 ob2 ob1 )
       2OVER           ( ob1 ob2 ob3 ob4 --> ob1 ob2 ob3 ob4 ob1 ob2 )
       2SWAP           ( ob1 ob2 ob3 ob4 --> ob3 ob4 ob1 ob2 )
       3DROP           ( ob1 ob2 ob3 --> )
       3PICK           ( ob1 ob2 ob3 --> ob1 ob2 ob3 ob1 )
       3PICK3PICK      ( ob1 ob2 ob3 --> ob1 ob2 ob3 ob1 ob2 )
       3PICKOVER       ( ob1 ob2 ob3 --> ob1 ob2 ob3 ob1 ob3 )
       3PICKSWAP       ( ob1 ob2 ob3 --> ob1 ob2 ob1 ob3 )
       3UNROLL         ( ob1 ob2 ob3 --> ob3 ob1 ob2 )
       4DROP           ( ob1 ob2 ob3 ob4 --> )
       4PICK           ( ob1 ob2 ob3 ob4 --> ob1 ... ob4 ob1 )
       4PICKOVER       ( ob1 ob2 ob3 ob4 --> ob1 ob2 ob3 ob4 ob1 ob4 )
       4PICKSWAP       ( ob1 ob2 ob3 ob4 --> ob1 ob2 ob3 ob1 ob4 )
       4ROLL           ( ob1 ob2 ob3 ob4 --> ob2 ob3 ob4 ob1 )
       4UNROLL         ( ob1 ob2 ob3 ob4 --> ob4 ob1 ob2 ob3 )
       4UNROLL3DROP    ( ob1 ob2 ob3 ob4 --> ob4 )
       4UNROLLDUP      ( ob1 ob2 ob3 ob4 --> ob4 ob1 ob2 ob3 ob3 )
       4UNROLLROT      ( ob1 ob2 ob3 ob4 --> ob4 ob3 ob2 ob1 )
       5DROP           ( ob1 ... ob5 --> )
       5PICK           ( ob1 ... ob5 --> ob1 ... ob5 ob1 )
       5ROLL           ( ob1 ... ob5 --> ob2 ... ob5 ob1 )
       5ROLLDROP       ( ob1 ... ob5 --> ob2 ... ob5 )
       5UNROLL         ( ob1 ... ob5 --> ob5 ob1 ... ob4 )
       6DROP           ( ob1 ... ob6 --> )
       6PICK           ( ob1 ... ob6 --> ob1 ... ob6 ob1 )
       6ROLL           ( ob1 ... ob6 --> ob2 ... ob6 ob1 )
       7DROP           ( ob1 ... ob7 --> )
       7PICK           ( ob1 ... ob7 --> ob1 ... ob7 ob1 )
       7ROLL           ( ob1 ... ob7 --> ob2 ... ob7 ob1 )
       8PICK           ( ob1 ... ob8 --> ob1 ... ob8 ob1 )
       8ROLL           ( ob1 ... ob8 --> ob2 ... ob8 ob1 )
       8UNROLL         ( ob1 ... ob8 --> ob8 ob1 ... ob7 )
       DEPTH           ( ob1 ... obn ... --> #n )
       DROP            ( ob --> )
       DROPDUP         ( ob1 ob2 --> ob1 ob1 )
       DROPFALSE       ( ob --> FALSE )
       DROPNDROP       ( ... # ob ) elimina ob, luego DROP # objetos
       DROPONE         ( ob --> #1 )
       DROPOVER        ( ob1 ob2 ob3 --> ob1 ob2 ob1 )
       DROPRDROP       ( ob --> )   DROP ob y baja 1 nivel de la pila de
                                    retornos.
       DROPROT         ( ob1 ob2 ob3 ob4 --> ob2 ob3 ob1 )
       DROPSWAP        ( ob1 ob2 ob3 --> ob2 ob1 )
       DROPSWAPDROP    ( ob1 ob2 ob3 --> ob2 )
       DROPTRUE        ( ob --> TRUE )
       DROPZERO        ( ob --> #0 )
       DUP             ( ob --> ob ob )
       DUP#1+PICK      ( ... #n --> ... #n obn )
       DUP3PICK        ( ob1 ob2 --> ob1 ob2 ob2 ob1 )


                                 Pgina 87






       DUP4UNROLL      ( ob1 ob2 ob3 --> ob3 ob1 ob2 ob3 )
       DUPDUP          ( ob --> ob ob ob )
       DUPONE          ( ob --> ob ob #1 )
       DUPPICK         ( ... #n --> ... #n obn-1 )
       DUPROLL         ( ... #n --> ... #n obn-1 )
       DUPROT          ( ob1 ob2 --> ob2 ob2 ob1 )
       DUPTWO          ( ob --> ob ob #2 )
       DUPUNROT        ( ob1 ob2 --> ob2 ob1 ob2 )
       DUPZERO         ( ob --> ob ob #2 )
       N+1DROP         ( ob ob1 ... obn #n --> )
       NDROP           ( ob1 ... obn #n --> )
       NDUP            ( ob1 ... obn #n --> ob1 ... obn ob1 ... obn )
       NDUPN           ( ob #n --> ob ... ob )
       ONEFALSE        ( --> #1 FALSE )
       ONESWAP         ( ob --> #1 ob )
       OVER            ( ob1 ob2 --> ob1 ob2 ob1 )
       OVER5PICK       ( v w x y z --> v w x y z y v )
       OVERDUP         ( ob1 ob2 --> ob1 ob2 ob1 ob1 )
       OVERSWAP        ( ob1 ob2 --> ob2 ob1 ob1 )
       OVERUNROT       ( ob1 ob2 --> ob1 ob1 ob2 )
       PICK            ( obn ... #n --> ... obn )
       ROLL            ( obn ... #n --> ... obn )
       ROLLDROP        ( obn ... #n --> ... )
       ROLLSWAP        ( obn ... ob #n --> ... obn ob )
       ROT             ( ob1 ob2 ob3 --> ob2 ob3 ob1 )
       ROT2DROP        ( ob1 ob2 ob3 --> ob2 )
       ROT2DUP         ( ob1 ob2 ob3 --> ob2 ob3 ob1 ob3 ob1 )
       ROTDROP         ( ob1 ob2 ob3 --> ob2 ob3 )
       ROTDROPSWAP     ( ob1 ob2 ob3 --> ob3 ob2 )
       ROTDUP          ( ob1 ob2 ob3 --> ob2 ob3 ob1 ob1 )
       ROTOVER         ( ob1 ob2 ob3 --> ob2 ob3 ob1 ob3 )
       ROTROT2DROP     ( ob1 ob2 ob3 --> ob3 )
       ROTSWAP         ( ob1 ob2 ob3 --> ob2 ob1 ob3 )
       SWAP            ( ob1 ob2 --> ob2 ob1 )
       SWAP2DUP        ( ob1 ob2 --> ob2 ob1 ob2 ob1 )
       SWAP3PICK       ( ob1 ob2 ob3 --> ob1 ob3 ob2 ob1 )
       SWAP4PICK       ( ob1 ob2 ob3 ob4 --> ob1 ob2 ob4 ob3 ob4 )
       SWAPDROP        ( ob1 ob2 --> ob2 )
       SWAPDROPDUP     ( ob1 ob2 --> ob2 ob2 )
       SWAPDROPSWAP    ( ob1 ob2 ob3 --> ob3 ob1 )
       SWAPDROPTRUE    ( ob1 ob2 --> ob2 TRUE )
       SWAPDUP         ( ob1 ob2 --> ob2 ob1 ob1 )
       SWAPONE         ( ob1 ob2 --> ob2 ob1 #1 )
       SWAPOVER        ( ob1 ob2 --> ob2 ob1 ob2 )
       SWAPROT         ( ob1 ob2 ob3 --> ob3 ob2 ob1 )
       SWAPTRUE        ( ob1 ob2 --> ob2 ob1 TRUE )
       UNROLL          ( ... ob #n --> ob ... )
       UNROT           ( ob1 ob2 ob3 --> ob3 ob1 ob2 )
       UNROT2DROP      ( ob1 ob2 ob3 --> ob3 )
       UNROTDROP       ( ob1 ob2 ob3 --> ob3 ob1 )
       UNROTDUP        ( ob1 ob2 ob3 --> ob3 ob1 ob2 ob2 )
       UNROTOVER       ( ob1 ob2 ob3 --> ob3 ob1 ob2 ob1 )
       UNROTSWAP       ( ob1 ob2 ob3 --> ob3 ob2 ob1 )
       ZEROOVER        ( ob --> ob #0 ob )
       reversym        ( ob1 ... obn #n --> obn ... ob1 #n )




                                 Pgina 88




      19.   Operaciones de Memoria

      Las palabras que se presentan en este captulo manipulan directorios,
      variables y ram del sistema.


      19.1  Memoria Temporal

      N.T.>TEMPOB es el rea de memoria de objetos temporales

      La palabra de usuario NEWOB crea una nueva copia de un objeto en la
      memoria temporal. Hay unas cuantas variaciones internas en este tema:

       CKREF           ( ob --> ob' )
                        Si ob est en TEMPOB, no est embebido en un objeto
                        compuesto y no est referenciado entonces no hace
                        nada. Si no, copia ob en TEMPOB y devuelve la copia.

       INTEMNOTREF?    ( ob --> ob flag )
                        Si el objeto inicial no est en el rea TEMPOB, no
                        est embebido en un objeto compuesto y no est
                        referenciado, devuelve ob y TRUE, si no, devuelve ob
                        y FALSE.

       TOTEMPOB        ( ob --> ob' )
                        Copia ob en TEMPOB y devuelve un puntero al nuevo ob.


      19.2  Variables y Directorios

      El fundamento en RPL del sistema de las palabras de usuario STO y RCL
      son las palabras STO, CREATE y @:

       CREATE ( ob id --> )
         Crea en el directorio actual una PALABRA-RAM (RAM-WORD) con ob como
         su parte objeto y la FORMA de NOMBRE (NAME FORM) del id como su
         parte nombre. Se produce un error si ob es o contiene el directorio
         actual ("Recursin de Directorio"). Se supone que ob no es un objeto
         cdigo primitiva.

       STO ( ob id --> )
           ( ob lam --> )
         En el caso lam, el identificador temporal lam se vuelve a unir al
         nuevo ob. La unin es al primer objeto identificador temporal que
         empareja (casa) con lam en el rea de Entornos Temporales (buscando
         desde el primer entorno temporal (el ms interno) hacia el ltimo).
         Se devuelve un error si lam no est unido a nada. En el caso de id,
         STO intenta emparejar id con la parte nombre de una variable global.
         Si no lo consigue, STO crea en el directorio actual una variable con
         ob como su parte objeto y la "forma de nombre" a partir del
         identificador como su parte nombre. Si se empareja (se resuelve),
         entonces el ob reemplaza la parte de objeto de la variable resuelta.
         Si cualquier puntero de objeto del sistema actualizable hace
         referencia a la parte objeto de la variable resuelta, entonces la
         parte objeto se coloca en el rea de objetos temporales antes de
         reemplazarla y se ajustan todos los punteros de objeto actualizables
         afectados para que se refieran a la copia de la parte de objeto en
         el rea de objetos temporales. En el caso del id, STO supone que ob
         no es un objeto cdigo primitiva.


                                 Pgina 89






       @   ( id --> ob TRUE )
           ( id --> FALSE )
           ( lam --> ob TRUE )
           ( lam --> FALSE )
         En el caso lam, @ intenta emparejar lam a la parte objeto
         identificador temporal de una unin en el rea de Entornos
         Temporales (buscando desde la primera rea de entornos temporales
         (la ms interna) hacia la ltima). Si lo consigue, entonces el
         objeto unido al lam se devuelve junto con una bandera TRUE; si no,
         se devuelve una bandera FALSE. En el caso id, @ intenta emparejar id
         con la parte nombre de una variable global, comenzando en el
         directorio actual y subiendo por los directorios padre si fuera
         necesario. Si no se consigue resolver, entonces se devuelve una
         bandera FALSE. Si se consigue resolver, se devuelve la parte objeto
         de la variable resuelta junto con una bandera TRUE.

      Una dificultad al usar STO y @ es que no hacen ninguna distincin con
      los comandos incorporados; con SIN como su argumento (objeto), STO
      copiar alegremente el cuerpo entero de SIN en una variable. Luego @
      llamara (a la pila) ese programa indescompilable. Por esta razn, es
      mejor usar SAFESTO y SAFE@, que funcionan como STO y @ excepto que
      convierten automticamente los cuerpos ROM en nombres XLIB (SAFESTO) y
      al revs de nuevo (SAFE@).

      Las extensiones adicionales son:

       ?STO_HERE ( ob id --> )
                 ( ob lam --> )
         Esto es la versin del sistema del STO de usuario. Es igual que
         SAFESTO, excepto que con las variables globales, a) almacena slo en
         el directorio actual; y b) no sobrescribir un directorio
         almacenado.

       SAFE@_HERE ( id --> ob TRUE )
                  ( id --> FALSE )
                  ( lam --> ob TRUE )
                  ( lam --> FALSE )
      Igual que SAFE@, excepto que con variables globales la bsqueda se
      restringe al directorio actual.

         Otras palabras relacionadas:

         PURGE    ( id --> )     Elimina la variable especificada por id; no
                                 hace ninguna comprobacin de tipo en el
                                 objeto almacenado.

         XEQRCL   ( id --> ob )  Igual que SAFE@ con las variables globales,
                                 pero produce un error si la variable no
                                 existe.










                                 Pgina 90




         XEQSTOID ( ob id --> ) Nombre alternativo de ?STO_HERE


      19.2.1   Directorios.   Un directorio (abreviado "rrp" de su nombre
      original "ramrompair" (parramrom) es un objeto cuyo cuerpo contiene un
      lista encadenada de variables globales--objetos con nombre
      referenciados con nombres globales. El cuerpo tambin contiene un
      nmero ID de biblioteca que asocia ("attaches", "asigna") un objeto
      biblioteca con el directorio de modo que los comandos de la biblioteca
      siguen a las variables del directorio en el orden de bsqueda en la
      compilacin de nombres.
      
      Un directorio puede estar "enraizado", o sea, almacenado en una
      variable global (que puede estar dentro del cuerpo de otro directorio),
      en cuyo caso sus nombres de variables estn disponibles para la
      compilacin. El directorio concreto en el que empieza la bsqueda para
      la resolucin de un nombre se llama "directorio actual" o "directorio
      contexto"; este directorio se especifica por el contenido de una
      posicin RAM del sistema. Un directorio no enraizado (en el tempob o en
      un puerto, por ejemplo), no se debera seleccionar nunca como el
      directorio contexto. Ni puede haber ninguna referencia dentro de un
      directorio en tempob; un directorio no es un objeto compuesto, de modo
      que la "recoleccin de basura" (G.C) no puede funcionar correctamente
      si existen tales referencias. Por esta razn, no se puede eliminar un
      directorio referenciado internamente con PURGE--usa XEQPGDIR en su
      lugar.

      Adems del contexto, otra posicin de la RAM del sistema identifica el
      directorio "seal de stop", que es el que acta como el punto final en
      la bsqueda de la resolucin de un nombre as como el directorio
      contexto es el punto de partida. Usando la seal de stop, puedes
      restringir la bsqueda en la resolucin de un nombre a un margen
      especfico; sin embargo, deberas usar trampas de error para asegurar
      que la seal de stop se reinicializa al directorio "home" cuando sucede
      un error.

      El directorio "home" ("sysramrompair") es el directorio por defecto
      tanto para el contexto como para el seal de stop. No es un directorio
      normal pues nunca puede estar no-enraizado (o sea, siempre est
      enraizado) y contiene unas estructuras adicionales que no tienen los
      directorios ordinarios (tales como asignaciones mltiples de
      bibliotecas y tablas alternativas de mensajes y "hash" de comandos).

      Un directorio es un objeto de la clase datos por lo que la ejecucin de
      un directorio simplemente lo devuelve a la pila. Sin embargo, la
      ejecucin de un nombre global tiene la propiedad que ejecutando el
      nombre de un directorio enraizado (almacenado) hace de ese directorio
      el directorio actual en lugar de ejecutar el directorio mismo.

      Hay disponibles las siguientes palabras para la manipulacin de
      directorios:
       CONTEXT! ( rrp --> )
         Almacena como directorio actual un puntero a un directorio enraizado

       CONTEXT@ ( --> rrp )
         Llama a la pila el directorio contexto actual.

       CREATEDIR       ( id --> )
         Crea un objeto directorio en el directorio actual.


                                 Pgina 91






       DOVARS  ( --> { id1 id2 ... } )
         Devuelve la lista de los nombres de variables del directorio actual.

       HOMEDIR ( --> )
         Hace de HOME el directorio actual.

       PATHDIR ( --> { HOME dir dir ... } )
         Devuelve el camino actual.

       UPDIR   ( --> )
         Convierte en contexto el directorio padre del actual.

       XEQORDER ( { id1 id2 ... } --> )
         Ordena el directorio actual.

       XEQPGDIR ( id --> )
         Elimina un directorio mientras respeta las convenciones de
         referencia/recoleccin de basura.

      19.3  El Directorio Oculto

      Hay un directorio sin nombre y oculto al principio del directorio
      "home", que contiene las definiciones de teclas del usuario y la
      informacin de las alarmas. Los programas de aplicaciones pueden usar
      tambin este directorio. Sin embargo, recuerda que el usuario no tiene
      modo alguno de detectar o eliminar variables de este directorio, de
      modo que una aplicacin debera o bien eliminar tales variables antes
      de terminar o proporcionar un comando que le permita al usuario
      eliminar variables especficas del directorio oculto.

      Estas palabras proporcionan capacidades de almacenamiento, llamada y
      eliminacin en el directorio oculto:

       PuHiddenVar  ( id --> )  Elimina la variable oculta de nombre id.

       RclHiddenVar ( id --> ob TRUE )
                    ( id --> FALSE   )
         Llama (@) a una variable oculta.

       StoHiddenVar    ( ob id --> )
         Almacena ob en una variable oculta.


















                                 Pgina 92






      19.4  Utilidades Adicionales de Memoria

       GARBAGE  ( --> )
         Fuerza una recoleccin de basura.

       MEM( --> # )
         Devuelve (a la pila) la cantidad de memoria libre (no se fuerza una
         recoleccin de basura)

       OCRC ( ob --> #nibbles checksum(hxs) )  
         Devuelve el tamao del objeto en nibbles y una cadena hex con el
         checksum

       getnibs ( DATOShxs DIRECCIONhxs --> DATOShxs' ) 
         Versin interna en RPL de PEEK

       putnibs ( DATOShxs DIRECCIONhxs --> ) 
         Versin interna en RPL de POKE









































                                 Pgina 93






      20.   Manejo de la Pantalla y Grficos

      La mayora de los comandos grficos en RPL de usuario se dirigen a la
      pantalla de grficos, que es el objeto grfico visible en el entorno
      del trazador (dibujo de funciones). Sin embargo, la "pantalla de
      texto", el grob visible en el entorno de la pila estndar tiene las
      mismas propiedades que la pantalla de grficos y deben usarla los
      programas de las aplicaciones para mostrar grficos cuando sea posible,
      para dejar la pantalla de grficos como un recurso "propiedad" del
      usuario. El Escritor de Ecuaciones (EquationWriter) lo hace as, por
      ejemplo, como tambin lo hace la tarjeta HP de la Biblioteca de
      Ecuaciones HP82211A (HP Solve Equation Library)

      20.1  Organizacin de la Pantalla

      La ram del sistema de la HP 48 contiene tres objetos grficos dedicados
      usados para mostrar informacin.

          Puntero           Grob               Posicin
         ---------    -----------------------  ---------

                      +---------------------+
         HARDBUFF2 -> | etiquetas de mens  |  (Mem Baja)
                      +---------------------+
         ABUFF     -> | grob de texto       |
                      +---------------------+
         GBUFF     -> | grob de grficos    |  (Mem Alta)
                      +---------------------+

      El grob de texto y el grob de grficos se pueden agrandar y se pueden
      desplazar.

      La palabra TOADISP hace visible el grob de texto; TOGDISP pone en el
      LCD (pantalla de cristal lquido) el grob grfico.

      Las siguientes palabras son tiles para devolver a la pila los grobs de
      pantalla:

       ABUFF      ( --> grob de texto )
       GBUFF      ( --> grob grfico )
       HARDBUFF   ( --> HBgrob )
         Devuelve a la pila el grob de texto o grfico que se est mostrando
         actualmente.
       HARDBUFF2  ( --> grob de men )
       HBUFF_X_Y  ( --> HBgrob #x1 #y1 )

      Un puntero ram llamado VDISP indica que grob se est mostrando
      actualmente en la pantalla. VDISP puede apuntar al grob de texto o al
      grob grfico. VDISP no se puede acceder directamente - la palabra
      HARDBUFF devuelve el grob de pantalla actual a la pila (ver ms abajo).
      Recuerda que ABUFF y GBUFF solo devuelven punteros, de modo que si se
      llama al grob para modificarlo y devolverlo posteriormente al usuario,
      se debera usar TOTEMPOB para crear una copia nica en la memoria
      temporal.





                                 Pgina 94




      Desde el punto de vista del usuario, la pantalla de texto se organiza
      en tres regiones y la convencin interna de numeracin de estas reas
      queda reflejada en muchas de las palabras de control de la pantalla
      (ver "Control de las Areas de la Pantalla" ms abajo). Las reas de la
      pantalla se numeran 1, 2 y 3. Las letras "DA" de "Display Area" (Area
      de Pantalla) se encuentran en los nombres de algunas palabras de
      control de la pantalla.

                 +-------------------+
            DA1  | directorio  tiempo| Lnea de Estado (16 lneas)
                 +-------------------+
                 |4:                 |
            DA2a |3:                 | Pantalla
                 +-------------------+ de la Pila
            DA2b |2:                 | (40 lneas en total)
                 |1:                 |
                 +-------------------+
            DA3  | 1  2  3   4  5  6 | Etiquetas de Mens (8 lneas)
                 +-------------------+

      El rea de la pantalla 2 est en realidad dividida en las reas 2a y
      2b, una distincin usada muy a menudo por la lnea de la lnea de
      comandos. La frontera entre 2a y 2b se puede mover, pero el tamao
      total de las reas 1, 2 y 3 es fijo.


      20.2  Preparacin de la Pantalla

      Dos palabras establecen el control sobre la pantalla de texto. Estas
      palabras son RECLAIMDISP y ClrDA1IsStat.

      La palabra RECLAIMDISP realiza las siguientes acciones:

         +  Asegura que el grob de texto es la pantalla actual

         +  Borra la pantalla de texto

         +  Si es necesario, cambia el tamao del grob de texto a las medidas
            estndar (131 de ancho por 56 de alto)

      RECLAIMDISP se parece mucho a la palabra de usuario CLLCD, excepto que
      CLLCD no cambia el tamao del grob de texto.

      La palabra ClrDA1IsStat suspende la actualizacin del reloj en la
      pantalla y es opcional. Si se va a solicitar alguna entrada al usuario
      usando palabras tales como WaitForKey o un bucle externo parametrizado
      (ver "Control del Teclado"), entonces se continuar actualizando el
      reloj y puede estropear la imagen en pantalla.

      Se puede encontrar un ejemplo del uso de ClrDA11IsStat en la aplicacin
      Tabla Peridica, dnde un usuario puede entrar una frmula molecular.
      La palabra WaitForKey se usa para obtener las teclas pulsadas y
      ClrDA1IsStat evita que el reloj sobreimpresione la cuadrcula de la
      Tabla Peridica en la pantalla.

      Si la pantalla del men no es necesaria, la palabra TURNMENUOFF
      eliminar DA3 de la pantalla y aumentar el grob de texto hasta 131x64.
      La palabra complementaria de sta es TURNMENUON que restaura los mens
      en la pantalla.


                                 Pgina 95







      Un esqueleto simplificado para un secundario de una aplicacin que
      puede ser invocada por el usuario final y usa la pantalla de texto
      podra ser ms o menos as:

       ::
         ClrDA1IsStat          ( *Suspende la actualizacin del reloj en la
                                 pantalla* )
         RECLAIMDISP           ( *Asegura y borra la pantalla alfa* )
         TURNMENUOFF           ( *Quita las teclas de men* )

         < aplicacin >

         ClrDAsOK   -\         ( *Le dice a la 48 que redibuje el LCD* )
           -o-        > Escoge una
         SetDAsTemp -/         ( *Congela todas las reas de la pantalla* )
       ;



      20.3  Control del Refresco de la Pantalla

      Cuando se termina una aplicacin o se vuelve al bucle externo del
      sistema para esperar que se entre algo por teclado, hay disponibles
      varias versiones internas de la palabra de usuario FREEZE para
      controlar la pantalla y hay una palabra que asegura que se redibujarn
      ciertas o todas las reas de la pantalla:

       SetDA1Temp      Congela el rea de pantalla 1
       SetDA2aTemp     Congela el rea de pantalla 2a
       SetDA2bTemp     Congela el rea de pantalla 2b
       SetDA3Temp      Congela el rea de pantalla 3
       SetDAsTemp      Congela todas las reas de la pantalla
       ClrDAsOK        Redibuja toda la pantalla cuando termina el programa

      Todava hay ms variaciones en este tema - ver el captulo "Control del
      Teclado" para ms informacin.




   

















                                 Pgina 96






      20.4  Borrar la Pantalla

      Las siguientes palabras se pueden usar para borrar toda la pantalla o
      una parte del HARDBUFF. Recuerda que HARDBUFF se refiere al grob
      mostrado actualmente, que es o el grob de texto o el grob grfico.

       BLANKIT         ( #filainicio #filas --> )
                        Borra #filas empezando en #filainicio
       BlankDA12       ( --> )
                        Borra desde la fila 0 hasta la 56
       BlankDA2        ( --> )
                        Borra desde la fila 16 hasta la 56
       CLEARVDISP      ( --> )
                        Pone a cero todo el HARDBUFF
       Clr16           ( --> )
                        Borra las primeras 16 filas de pixels
       Clr8            ( --> )
                        Borra las primeras 8 filas de pixels
       Clr8-15         ( --> )
                        Borra desde la fila 8 de pixels hasta la 15


      20.5  Control de los Indicadores

      Las siguientes palabras controlan los indicadores de desplazamiento a
      la izquierda, desplazamiento a la derecha y alfa. Es poco probable que
      una aplicacin tenga que controlarlos directamente y el mal uso de
      estas palabras puede conducir a pantallas confusas despus de que la
      aplicacin haya terminado.

       ClrAlphaAnn     Apaga el indicador alfa
       ClrLeftAnn      Apaga el indicador de desplazamiento izquierda
       ClrRightAnn     Apaga el indicador de desplazamiento derecha
       SetAlphaAnn     Enciende el indicador alfa
       SetLeftAnn      Enciende el indicador de desplazamiento izquierda
       SetRightAnn     Enciende el indicador de desplazamiento derecha























                                 Pgina 97






      20.6  Coordenadas de la Pantalla

      El pixel superior izquierdo de la pantalla tiene las coordenadas x=0 e
      y=0, que son las mismas que las coordenadas del pixel de usuario
      { #0 #0 }. Las coordenadas del pixel inferior derecho son x=130 e y=63.

      NOTA: los subgrobs se toman desde la coordenada superior izquierda
      hasta el pixel debajo y a la derecha de la esquina inferior derecha.
      Los trminos #x1 e #y1 se refieren al pixel superior izquierdo de una
      subrea, mientras que #x2 e #y2 se refieren al pixel debajo y a la
      derecha de la esquina inferior derecha.


        { #0 #0 } +------------------------------+
        {#x1 #y1} |*                             |
                  |                              |
                  | coordenada+----+             |
                  |        GOR|*   |             |
                  |           |    |             |
                  |           +----+             |
                  |                 * Coordenada |
                  |                   SubGrob    |
                  |                              |
                  |                             *|  <- { #130 #63 }
                  +------------------------------+
                                                  * <- { #x2  #y2 }



      20.6.1   Coordenadas de la Ventana

      Las siguientes rutinas devuelven HARDBUFF y las coordenadas para las
      porciones de la pantalla en la forma adecuada para una subsiguiente
      llamada a SUBGROB. Los trminos #x1 e #y1 se refieren a la esquina
      superior izquierda de la ventana en el grob mostrado actualmente. Si se
      ha desplazado el grob, stas no sern #0 #0!.

      Si HARDBUFF ha sido desplazado, algunas palabras de pantalla pueden no
      ser apropiadas para usarse, ya que dependen de que la esquina superior
      izquierda de la pantalla sea #0 #0. Al LCD se le llama entonces la
      "ventana" y los trminos #x1 e #y1 se referirn a las coordenadas del
      pixel de la esquina superior izquierda de la ventana. La palabra
      HBUFF_X_Y devuelve HARDBUFF y estas coordenadas de la ventana. La
      palabra WINDOWCORNER devuelve solo las coordenadas de la ventana. Las
      palabras DISPROW1* y DISPROW2*, mencionadas ms abajo, funcionan en
      relacin a la esquina de la ventana.

       Rows8-15        ( --> HBgrob #x1 #y1+8 #x1+131 #y1+16 )
       TOP16           ( --> HBgrob #x1 #y1 #x1+131 #y1+16 )
       TOP8            ( --> HBgrob #x1 #y1 #x1+131 #y1+8 )
       WINDOWCORNER    ( --> #x #y )
                        Devuelve las coordenadas del pixel de la esquina
                        superior izquierda de la ventana.






                                 Pgina 98






      La palabra Save16 llama a TOP16 y a SUBGROB para producir un grob que
      consiste en las 16 primeras filas de la pantalla actual:

       Save16          ( --> grob )

      En la HP 48 no existen las palabras equivalentes para las primeras 8
      filas ni para las filas 8 hasta la 15, pero se pueden escribir como se
      indica a continuacin:

       :: TOP8 SUBGROB ; ( --> grob ) ( *Salva las primeras 8 filas* )
       :: TOP8-15 SUBGROB ; ( --> grob ) ( *Salva las filas 8 a 15* )


      20.7  Mostrar Texto

      Hay tres fuentes (tipos de letras) disponibles en la HP 48, que se
      distinguen por el tamao. La fuente ms pequea es de anchura variable;
      la mediana y la grande son de anchura fija.

      Las palabras que se describen ms abajo muestran texto usando las
      fuentes mediana y grande en reas especficas. El uso de las fuentes
      pequeas y otras posiciones opcionales para las fuentes mediana y
      grande se deben hacer en los grficos, lo que se describe ms tarde.


      20.7.1 Areas Estndar para Mostrar Texto      

      Cuando la pantalla actual es el grob de texto Y no ha sido desplazada,
      se pueden usar las siguientes palabras para mostrar texto en la fuente
      mediana (5x7). Las cadenas largas se truncan a 22 caracteres con puntos
      suspensivos al final (...) y las cadenas con menos de 22 caracteres se
      rellenan con espacios (por la derecha)

       DISPROW1        ( $ --> )
       DISPROW2        ( $ --> )
       DISPROW3        ( $ --> )
       DISPROW4        ( $ --> )
       DISPROW5        ( $ --> )
       DISPROW6        ( $ --> )
       DISPROW7        ( $ --> )
       DISPN           ( $ #fila --> )
       DISP5x7         ( $ #inicio #max )


                               (0,0)                (130,0)
          DISPROW1 escribe en    +--------------------+
                                 |                    |
                                 +--------------------+
                               (0,7)                 (130,7)

                               (0,8)                 (130,8)
          DISPROW2 escribe en    +--------------------+
                                 |                    |
                                 +--------------------+
                               (0,15)                (130,15)
                (etc.)



                                 Pgina 99





      La palabra DISP5x7 se puede usar para mostrar una cadena que se
      extiende por ms de una lnea de la pantalla. La cadena debe tener
      embebidos "retornos de carro" (chr: #13d) para indicar donde se ha de
      pasar a la siguiente lnea de la pantalla. Si un segmento de lnea es
      mayor de 22 caracteres, se truncar y se mostrar con puntos
      suspensivos al final (...). La cadena se muestra empezando en la fila
      #inicio con #max filas.

      Las siguientes palabras se pueden usar para mostrar texto en la fuente
      grande (5x9). Las cadenas largas se truncan a 22 caracteres con  puntos
      suspensivos (...) al final y las cadenas con menos de 22 caracteres se
      rellenan con espacios en blanco (por la derecha).

       BIGDISPROW1     ( $ --> )
       BIGDISPROW2     ( $ --> )
       BIGDISPROW3     ( $ --> )
       BIGDISPROW4     ( $ --> )
       BIGDISPN        ( $ #fila --> )


                               (0,17)              (130,0)
       BIGDISPROW1 escribe en    +--------------------+
                                 |                    |
                                 +--------------------+
                               (0,26)              (130,26)

                               (0,27)              (130,27)
       BIGDISPROW2 escribe en    +--------------------+
                                 |                    |
                                 +--------------------+
                               (0,36)              (130,36)
                (etc.)




























                                 Pgina 100




      20.7.2   Mensajes Temporales

      A veces es conveniente mostrar una advertencia y luego devolver la
      pantalla a su estado previo. Hay varias tcnicas y herramientas
      disponibles para esto. El modo ms fcil de hacerlo es con la palabra
      FlashWarning. El cdigo de FlashWarning se parece a este:

       FlashWarning            ( $ --> )
       ::
         ERRBEEP               ( *Produce un pitido de error* )
         Save16                ( *Salva las 16 filas de pixels superiores* )
         SWAP DISPSTATUS2      ( *Muestra la advertencia* )
         VERYVERYSLOW          ( *Pausa de unos 3 segundos* )
         Restore16             ( *Restaura las 16 filas superiores* )
       ;

      Se pueden hacer variaciones alrededor de FlashWarning usando palabras
      como TOP16 o una versin de la sugerida arriba que salva menos filas.
      El ejemplo que sigue salva las 8 filas superiores y muestra un mensaje
      de una lnea durante unos 0.6 segundos:

       ::
         TOP8 SUBGROB          ( *Salva las 8 filas superiores* )
         SWAP DISPROW1*        ( *Muestra el mensaje* )
         VERYSLOW VERYSLOW     ( *Pausa corta* )
         Restore8              ( *Restaura las 8 filas superiores* )
       ;

      NOTA: Es importante usar DISPROW1* y DISPROW2* en vez de DISPROW1 y
      DISPROW2 si existe la posibilidad que HARDBUFF haya sido desplazado. No
      existen las palabras correspondientes para otras lneas de la pantalla.






























                                 Pgina 101






      20.8  Objetos Grficos

      La siguiente seccin presenta herramientas para crear, manipular y
      mostrar objetos grficos.


      20.8.1   Advertencias

      He aqu dos advertencias:

         1. El trmino "operacin tipo-explosiva" se refiere a una operacin
            que se lleva a cabo directamente sobre un objeto sin hacer antes
            una copia. La convencin de los nombres para las palabras que
            realizan este tipo de operacin hace que tengan a menudo un signo
            de admiracin para indicar una operacin "explosiva", como por
            ejemplo GROB! o GROB!ZERO.

            Debes recordar dos cosas cuando uses operaciones "explosivas":

            +  Ya que se modifica el propio objeto, cualquier puntero en la
               pila que se refiera a ese objeto apuntar ahora a un objeto
               modificado. Se puede usar la palabra CKREF para asegurar que
               un objeto es nico.

            +  Estas operaciones no comprueban errores, por lo que los
               parmetros inadecuados o fuera de margen pueden corromper la
               memoria sin posibilidad de recuperacin.

         2. En la prctica, es mejor usar la palabra XYGROBDISP para colocar
            un grob en el grob de pantalla. La palabra XYGROBDISP es de
            naturaleza conservadora - si el grfico a colocar en HARDBUFF
            sobrepasa los lmites de HARDBUFF, se aumenta el grob HARDBUFF
            para acomodar al nuevo grob.


























                                 Pgina 102



      20.8.2   Herramientas Grficas
      
      Las siguientes palabras crean o modifican objetos grficos:      

       $>BIGGROB       ( $ --> grob ) ( fuente 5x9 )
       $>GROB          ( $ --> grob ) ( fuente 5x7 )
       $>grob          ( $ --> grob ) ( fuente 3x7 )
       DOLCD>          ( --> 64x131grob )
       GROB!           ( grob1 grob2 #col #fila --> )
                        Almacena grob1 en grob2. Es una palabra
                        tipo-explosiva sin chequeo de errores!
       GROB!ZERO       ( grob #x1 #y1 #x2 #y2 --> grob' )
                        Pone a cero una seccin rectangular del grob. NOTA:
                        operacin tipo-explosiva
       GROB!ZERODRP    ( grob #x1 #y1 #x2 #y2 --> )
                        Pone a cero una seccin rectangular de un grob. NOTA:
                        Operacin tipo-explosiva!
       GROB>GDISP      ( grob --> )
                        Almacena el grob en el grob grfico.
       HARDBUFF        ( --> HBgrob (el grob de pantalla actual) )
       HEIGHTENGROB    ( grob #filas --> )
                        Aade #filas al grob, a menos que el grob sea nulo.
                        NOTA: Se supone es el grob de texto o el grfico!
       INVGROB         ( grob --> grob' )
                        Invierte los bits de datos del grob - tipo-explosiva
       LINEOFF         ( #x1 #y1 #x2 #y2 --> )
                        Borra los pixels en una lnea del grob de texto.
                        Nota: #x2 debe ser > #x1 (usar ORDERXY#)
       LINEOFF3        ( #x1 #y1 #x2 #y2 --> )
                        Borra los pixels en una lnea del grob grfico. 
                        Nota: #x2 debe ser > #x1 (usar ORDERXY#)
       LINEON          ( #x1 #y1 #x2 #y2 --> )
                        Activa los pixels en una lnea del grob de texto.
                        Nota: #x2 debe ser > #x1 (usar ORDERXY#)
       LINEON3         ( #x1 #y1 #x2 #y2 --> )
                        Activa los pixels en una lnea del grob grfico.
                        Nota: #x2 deber ser > #x1 (usar ORDERXY#)
       MAKEGROB        ( #alto #ancho --> grob )
       ORDERXY#        ( #x1 #y1 #x2 #y2 --> #x1 #y1 #x2 #y2 )
                        Ordena dos puntos para dibujar una lnea
       PIXOFF          ( #x #y --> )
                        Borra un pixel en el grob de texto
       PIXOFF3         ( #x #y --> )
                        Borra un pixel en el grob grfico
       PIXON           ( #x #y --> )
                        Activa un pixel en el grob de texto
       PIXON?          ( #x #y --> flag )
                        Devuelve TRUE si el pixel del grob de texto est
                        activado.
       PIXON?3         ( #x #y --> flag )
                        Devuelve TRUE si el pixel del grob grfico est
                        activado
       PIXON3          ( #x #y --> )
                        Activa un pixel en el grob grfico
       SUBGROB         ( grob #x1 #y1 #x2 #y2 --> subgrob )
       Symb>HBuff      ( symb --> )
                        Muestra symb en el HARDBUFF en el formato del
                        Escritor-de-Ecuaciones. Puede que aumente HARDBUFF,
                        as que, ejecutar RECLAIMDISP despus.



                                 Pgina 103






       TOGLINE         ( #x1 #y1 #x2 #y2 --> )
                        Cambia el estado (encendido/apagado) de los pixels de
                        una lnea del grob de texto.
       TOGLINE3        ( #x1 #y1 #x2 #y2 --> )
                        Cambia el estado (encendido/apagado) de los pixels de
                        una lnea del grob grfico.

      NOTA:  #x2 debe ser mayor que #x1 para dibujar la lnea!


      20.8.3   Dimensiones de los Grobs

      Las siguientes palabras devuelven o verifican informacin sobre el
      tamao:

       CKGROBFITS      ( grob1 grob2 #n #m --> grob1 grob2' #n #m )
                        Trunca grob2 si no cabe en grob1
       DUPGROBDIM      ( grob --> grob #alto #ancho )
       GBUFFGROBDIM    ( --> #alto #ancho )
                        Devuelve las dimensiones del grob grfico
       GROBDIM         ( grob --> #alto #ancho )
       GROBDIMw        ( grob --> #ancho )


      20.8.4   Grobs Incorporados

      Las siguientes palabras se refieren a los grobs incorporados:

       BigCursor       Cursor 5x9 (recuadro hueco)
       CROSSGROB       Smbolo "+" 5x5
       CURSOR1         Cursor de Insercin 5x9 (flecha)
       CURSOR2         Cursor Sobreescribir 5x9 (recuadro slido)
       MARKGROB        Smbolo "X" 5x5 
       MediumCursor    Cursor 5x7 (recuadro hueco)
       SmallCursor     Cursor 3x5 (recuadro hueco)
























                                 Pgina 104




      20.8.5   Utilidades para Mostrar Mens

      Las etiquetas de men son grobs de 8 filas de alto y 21 pixels de
      ancho. Las columnas de las etiquetas de men en HARDBUFF2 son:

                         Decimal
                         -------  
               ZERO         0   Tecla de men 1
               TWENTYTWO   22   Tecla de men 2
               # 0002C     44   Tecla de men 3
               # 00042     66   Tecla de men 4
               # 00058     88   Tecla de men 5
               # 0006E    110   Tecla de men 6

      La rutina DispMenu.1 vuelve a mostrar el men actual; la rutina
      DispMenu vuelve a mostrar el men actual y tambin llama a SetDA3Valid
      para "congelar" la lnea de men de la pantalla.

      Las siguientes palabras convierten objetos a etiquetas de men y
      muestran las etiquetas en el nmero de columna dado:      

       Grob>Men       ( #col 8x21grob --> )
                         Muestra un grob de 8x21 (solo!)
       Id>Men         ( #col Id --> )
                        Llama al Id y muestra la etiqueta estndar o la
                        etiqueta de directorio, dependiendo del contenido de
                        Id.
       Seco>Men       ( #col seco --> )
                        Evala el secundario y usa el resultado para hacer y
                        mostrar la etiqueta de men apropiada.
       Str>Men        ( #col $ --> )
                        Hace y muestra una etiqueta de men estndar

      Las siguientes palabras convierten cadenas de texto en las diferentes
      clases de grobs de teclas de mens disponibles:

       MakeBoxLabel    ( $ --> grob )  Recuadro con una bala (cuadradito) en
                                       su interior.
       MakeDirLabel    ( $ --> grob )  Recuadro con una barra de directorio
       MakeInvLabel    ( $ --> grob )  Etiqueta blanca (Solucionador)
       MakeStdLabel    ( $ --> grob )  Etiqueta negra (estndar)


      20.9  Desplazar la Pantalla

      Estn disponibles las siguientes palabras para desplazar la pantalla:

       SCROLLDOWN      ( *Desplaza un pixel hacia abajo con repeticin* )
       SCROLLLEFT      ( *Desplaza un pixel a la izquierda con repeticin* )
       SCROLLRIGHT     ( *Desplaza un pixel a la derecha con repeticin* )
       SCROLLUP        ( *Desplaza un pixel hacia arriba con repeticin* )

       JUMPBOT         ( *Mueve la ventana al extremo inferior del grob* )
       JUMPLEFT        ( *Mueve la ventana al extremo izquierdo del grob* )
       JUMPRIGHT       ( *Mueve la ventana al extremo derecho del grob* )
       JUMPTOP         ( *Mueve la ventana al extremo superior del grob* )

      Las palabras SCROLL* comprueban si se mantienen pulsadas sus teclas
      cursor (flecha) correspondientes y repiten su accin hasta que se
      alcanza el extremo del grob o se suelta la tecla.

                                 Pgina 105





      El siguiente ejemplo ilustra una serie de operaciones con grficos y el
      uso del bucle externo parametrizado que proporciona desplazamiento para
      el usuario.

       N.T.> POL = Bucle Externo Parametrizado.

       *---------------------------------------------------------     
       *
       * Incluye el fichero de cabecera KEYDEFS.H que define palabras como
       * kcUpArrow (cdigodeteclaFlechaArriba) para nmeros de teclas fsicas
       *
       INCLUDE KEYDEFS.H
       *
       * Incluye los ocho caracteres necesarios para la carga binaria
       *
       ASSEMBLE
               NIBASC  /HPHP48-D/
       RPL
       *
       * Empieza el secundario
       *
       ::
         RECLAIMDISP           ( *Reclama la pantalla alfa* )
         ClrDA1IsStat          ( *Desactiva temporalmente el reloj* )
       *                       ( *Prubalo eliminando ClrDA1IsStat* )
         ZEROZERO              ( #0 #0 )
         150 150 MAKEGROB      ( #0 #0 150x150grob )
         XYGROBDISP            (  )
         TURNMENUOFF           ( *Apaga la lnea de mens* )
       *
       * Dibuja lneas diagonales.  Recuerda que LINEON precisa que #x2>#x1!
       *
         ZEROZERO              ( #x1 #y1 )
         149 149               ( #x1 #y1 #x2 #y2 )
         LINEON                ( *Dibuja la lnea* )
         ZERO 149              ( #x1 #y1 )
         149 ZERO              ( #x1 #y1 #x2 #y2 )
         LINEON                ( *Dibuja la lnea* )
       *
       * Pone el texto
       *
         HARDBUFF
         75 50 "SCROLLING"     ( HBgrob 75 150 "SCROLLING" )
         150 CENTER$3x5        ( HBgrob )
         75 100 "EXAMPLE"      ( HBgrob 75 100 "EXAMPLE" )
         150 CENTER$3x5        ( HBgrob )
         DROPFALSE             ( FALSE )
         { LAM Exit } BIND     ( *Une la bandera de salida del POL* )
         ' NOP                 ( *No hace nada en pantalla*  )
         ' ::                  ( *Controlador de las teclas fsicas*   )
           kpNoShift #=casedrop
             ::
                kcUpArrow    ?CaseKeyDef
                                 :: TakeOver SCROLLUP ;






                                 Pgina 106




                kcLeftArrow  ?CaseKeyDef
                                 :: TakeOver SCROLLLEFT ;
                kcDownArrow  ?CaseKeyDef
                                 :: TakeOver SCROLLDOWN ;
                kcRightArrow ?CaseKeyDef
                                 :: TakeOver SCROLLRIGHT ;
                kcOn         ?CaseKeyDef
                                 :: TakeOver
                                    TRUE ' LAM Exit STO ;
                kcRightShift   #=casedrpfls
                DROP 'DoBadKeyT
             ;
           kpRightShift #=casedrop
             ::
                kcUpArrow    ?CaseKeyDef
                                 :: TakeOver JUMPTOP ;
                kcLeftArrow  ?CaseKeyDef
                                 :: TakeOver JUMPLEFT ;
                kcDownArrow  ?CaseKeyDef
                                 :: TakeOver JUMPBOT ;
                kcRightArrow ?CaseKeyDef
                                 :: TakeOver JUMPRIGHT ;
                kcRightShift #=casedrpfls
                DROP 'DoBadKeyT
             ;
           2DROP 'DoBadKeyT
         ;
         TrueTrue              ( *Banderas de control de Teclas* )
         NULL{}                ( *Ninguna Tecla de men ("blanda") aqu*  )
         ONEFALSE              ( *primera fila, no suspender* )
         ' LAM Exit            ( *Condicin de salida de la Aplicacin* )
         ' ERRJMP              ( *Controlador de errores* )
         ParOuterLoop          ( *Ejecuta el ParOuterLoop (el POL)* )
         TURNMENUON            ( *Restaura la fila de mens* )
         RECLAIMDISP           ( *Borra y devuelve la pantalla a su tamao* )
       ;

























                                 Pgina 107




      El cdigo de arriba, si se almacena en un fichero llamado SCROLL.S se
      puede compilar as:

       RPLCOMP SCROLL.S
       SASM SCROLL.A
       SLOAD -H SCROLL.M

      Este ejemplo tambin supone que el fichero KEYDEFS.H est en el mismo
      directorio o que el fichero fuente se ha modificado para reflejar la
      ubicacin de KEYDEFS.H. El fichero de control de la carga SCROLL.M se
      parece a esto:

       OU SCROLL
       LL SCROLL.LR
       SU XR
       SE ENTRIES.O
       RE SCROLL.O

      El fichero final, SCROLL, se puede cargar en modo binario a la HP 48
      para probarlo.

      Cuando se est ejecutando SCROLL, las teclas de flecha (cursor)
      desplazan la pantalla y las teclas de flecha desplazadas a la derecha
      mueven la ventana al extremo correspondiente. La tecla [ATTN] termina
      el programa.

      Para ms detalles acerca del ParOuterLoop, ver el captulo "Control del
      Teclado".

































                                 Pgina 108




      21.   Control del Teclado

      Un programa que precisa entradas del usuario por teclado puede escoger
      entre tres tcnicas bsicas disponibles en el RPL interno, listadas en
      orden de complejidad creciente:


         1. Esperar una pulsacin de tecla individual, luego decidir que
            hacer con ella.

         2. Llamar a la forma interna de INPUT.

         3. Establecer un Bucle Externo Parametrizado (POL) para controlar un
            entorno de aplicacin completo.

      Las siguientes secciones discuten el esquema de numeracin interno de
      las teclas y cada una de las tres estrategias anteriores de
      procesamiento de las teclas.


      21.1  Ubicacin de las Teclas

      La palabra de usuario WAIT devuelve un nmero real que es est
      codificado de la forma rc.p dnde:

                         r = La fila de la tecla
                         c = La columna de la tecla
                         p = El plano de desplazamiento

          +--------+------------------+---+---------------------+
          |   p    |Planos Principales| p |    Planos Alfa      |
          +--------+------------------+---+---------------------+
          | 0 o 1  | Sin desplazar    | 4 |Alfa                 |
          |   2    | Despla-izquierda | 5 |Alfa despla-izquierda|
          |   3    | Despla-derecha   | 6 |Alfa despla-derecha  |
          +--------+------------------+---+---------------------+


      Internamente, las posiciones de las teclas se representan con dos
      enteros binarios: #KeyCode (#CdigoTecla), que define una tecla fsica
      y #Plane (#Plano), que define el plano de desplazamiento.

      El fichero KEYDEFS.H, suministrado con el compilador RPL, define los
      siguientes trminos para los planos de las teclas:

       DEFINE  kpNoShift        ONE  
       DEFINE  kpLeftShift      TWO
       DEFINE  kpRightShift     THREE
       DEFINE  kpANoShift       FOUR
       DEFINE  kpALeftShift     FIVE
       DEFINE  kpARightShft     SIX

      N.T.> Dnde:
                     kp          = Plano de la Tecla
                     A           = Alfa activado
                     LeftShift   = Desplazado a la izquierda
                     RightShift  = Desplazado a la derecha
                     NoShift     = Sin desplazar



                                 Pgina 109





      Las teclas se numeran internamente de 1 a 49 empezando en la esquina
      superior izquierda del teclado. Las definiciones principales de las
      teclas tambin se dan en KEYDEFS.H. He aqu algunas de ellas:

       DEFINE  kcMenuKey1       ONE
       DEFINE  kcMenuKey2       TWO
       DEFINE  kcMenuKey3       THREE
       DEFINE  kcMenuKey4       FOUR
       DEFINE  kcMenuKey5       FIVE
       DEFINE  kcMenuKey6       SIX
       DEFINE  kcMathMenu       SEVEN
       DEFINE  kcPrgmMenu       EIGHT
       DEFINE  kcCustomMenu     NINE
            ...
       DEFINE  KcPlus           FORTYNINE

      Se recomienda el uso de estas definiciones en el cdigo fuente a fin de
      hacerlo ms legible.

      La traduccin entre la numeracin interna de las teclas y la numeracin
      rc.p se puede llevar a cabo con dos palabras:

       Ck&DecKeyLoc    ( %rc.p --> #CdigoTecla #Plano )
       CodePl>%rc.p    ( #CdigoTecla #Plano --> %rc.p )


      21.2  Esperar una Tecla

      Si una aplicacin necesita esperar a que se pulse una sola tecla, como
      por ejemplo una decisin del tipo si-no-attn, lo mejor es usar la
      palabra WaitForKey, que devuelve la tecla pulsada en formato completo
      (tecla + plano). WaitForKey tambin mantiene a la HP48 en un estado de
      bajo consumo hasta que se pulsa una tecla y controla los indicadores
      alfa y desplazamiento as como el procesado de alarmas.

      Estn disponibles las siguientes palabras:

       CHECKKEY        ( --> #CdigoTecla TRUE )
                       ( --> FALSE )
                        Devuelve, pero no la saca, la siguiente tecla en el
                        bfer.
       FLUSHKEYS       ( --> )
                        Vaca el bfer de teclado
       GETTOUCH        ( --> #CdigoTecla TRUE )
                       ( --> FALSE )
                        Devuelve y saca la siguiente tecla del bfer.
       KEYINBUFFER?    ( --> FLAG )
                        Devuelve TRUE si hay una tecla en el bfer de
                        teclado, si no, devuelve FALSE.
       ATTN?           ( --> flag )
                        Devuelve TRUE si se ha pulsado [ATTN]
       ATTNFLGCLR      ( --> )
                        Borra la bandera de la tecla attn (no saca la tecla
                        attn del bfer)
       WaitForKey      ( --> #CdigoTecla #Plano )
                        Devuelve la siguiente tecla que se pulse en formato
                        completo (tecla + plano)



                                 Pgina 110






      21.3  InputLine

      La palabra InputLine es el ncleo de la palabra de usuario INPUT as
      como tambin del apuntador para solicitar nombres de ecuaciones (NEW).
      InputLine hace lo siguiente:

         +  Muestra el apuntador en el rea de pantalla 2a,

         +  Activa los modos de entrada del teclado,

         +  Inicializa la lnea de edicin,

         +  Acepta la entrada del usuario hasta que se pulsa [ENTER]
            explcita o implcitamente,

         +  Analiza, evala o solamente devuelve la entrada del usuario en la
            lnea de edicin,

         +  Devuelve TRUE si se sali con Enter o FALSE si se abort con
            Attn.

      A la entrada la pila debe contener lo siguiente:

   $Prompt     El apuntador que se mostrar durante la entrada del usuario
   $EditLine   El contenido inicial de la lnea de edicin
   CursorPos   La posicin inicial del cursor en la lnea de edicin,
               especificada como un nmero carcter entero binario o con una
               lista de dos elementos que son los nmeros enteros binarios
               fila y columna. En todos los nmeros, #0 indica el final de la
               lnea de edicin, fila o columna.
   #Ins/Rep    El modo insercin/sobreescritura inicial:
                  #0    el modo ins/sob actual
                  #1    modo insercin
                  #2    modo sobreescritura
   #Entry      El modo de entrada inicial:
                  #0    modo de entrada actual ms modo programa
                  #1    entrada programa/inmediata
                  #2    entrada programa/algebraica
   #AlphaLock  El modo Alfa inicial:
                  #0    modo alfa actual
                  #1    bloqueo alfa activado
                  #2    bloqueo alfa desactivado
   ILMenu      El men InputLine inicial en el formato especificado por el
               "ParOuterLoop"
   #ILMenuRow  El nmero de fila inicial del men InputLine en le formato
               especificado por el "ParOuterLoop"
   AttnAbort?  Una bandera que especifica si pulsando Attn mientras existe
               una lnea de edicin no nula, abortara el "InputLine" (TRUE)
               o simplemente borrara la lnea de edicin (FALSE)
   #Parse      Como procesar la lnea de edicin resultante:
                  #0    Devolver la lnea de edicin como una cadena de texto
                  #1    Devolver la lnea de edicin como una cadena de texto
                        Y como un objeto analizado
                  #2    Analizar y evaluar la lnea de edicin.





                                 Pgina 111






      InputLine devuelve diferentes resultados, dependiendo del valor inicial
      de #Parse:

    #Parse  Pila               Descripcin
    ------  -----------------  ------------------------------
      #0    $EditLine TRUE     Lnea de edicin
      #1    $EditLine ob TRUE  Lnea de edicin y lnea de edicin analizada
      #2    Ob1 ... Obn TRUE   Objeto u objetos resultantes
            FALSE              Pulsada Attn para abortar la edicin


      21.3.1   Ejemplo de InputLine

      La llamada ejemplo a InputLine mostrada a continuacin le pide al
      usuario un nombre de variable. Si el usuario entra un nombre vlido, se
      devuelven el nombre y TRUE, si no, se devuelve FALSE.

         ( --> Ob TRUE | FALSE )
       ::
         "Enter name:"  ( *Cadena del apuntador* )
         NULL$          ( *Ningn nombre por defecto* )
         ONEONE         ( *Posicin inicial de la lnea de edicin y del
                        cursor* )
         ONEONE         ( *Modo Insercin y entrada programa/inmediata* )
         NULL{}         ( *Sin men de edicin* )
         ONE            ( *Fila del men* )
         FALSE          ( *Attn borra la lnea de edicin* )
         ONE            ( *Devuelve la lnea de edicin y el ob analizado* )
         InputLine      ( ($editline ob TRUE) | (FALSE) )
         NOTcaseFALSE   ( *Sale si se pulsa Attn* )
         SWAP NULL$?    ( *Sale si la lnea de edicin est en blanco* )
         casedrop FALSE
         DUPTYPEIDNT?   ( *Comprueba si el ob es un id* )
         caseTRUE       ( *S, sale y TRUE* )
         DROPFALSE      ( *No, elimina el ob y FALSE* )
       ;























                                 Pgina 112






      21.4  El Bucle Externo Parametrizado

      En esta seccin, el trmino "bucle externo parametrizado" se usa para
      referirse al uso de la palabra RPL "ParOuterLoop" o al uso combinado de
      las utilidades fundamentales que lo componen (descritas ms abajo),
      todo lo cual se puede ver como palabras que toman el control del
      teclado y de la pantalla hasta que se cumple una condicin
      especificada.

      El bucle externo parametrizado, "ParOuterLoop", toma nueve argumentos
      en este orden:

   AppDisplay     El objeto de actualizacin de la pantalla que se evala
                  antes de la evaluacin de cada tecla. "AppDisplay" debera
                  controlar la actualizacin de la pantalla no controlada por
                  las teclas mismas y tambin debera realizar un control
                  especial de errores.

   AppKeys        Las asignaciones de las teclas fsicas, un objeto
                  secundario con el formato que se describe ms abajo.

   NonAppKeyOK?   Una bandera que especifica si las teclas fsicas no
                  asignadas por la aplicacin deben realizar sus acciones por
                  defecto o ser canceladas.

   DoStdKeys?     Una bandera que se usa conjuntamente con "NonAppKeyOK? que
                  especifica si las teclas que no usa la aplicacin usan las
                  definiciones estndar de las teclas en lugar del procesado
                  de teclas por defecto.

   AppMenu        La especificacin de las teclas de men, un secundario o
                  una lista con el formato especificado en el documento de
                  asignaciones de teclas de men, o FALSE

   #AppMenuRow    El nmero de fila del men inicial de la aplicacin. En la
                  mayora de las aplicaciones, debe ser el entero binario
                  uno.

   SuspendOK?     Una bandera que especifica si cualquier comando de usuario
                  que creara un entorno suspendido y restaurara el bucle
                  externo del sistema debera generar en su lugar un error o
                  no.

   ExitCond       Un objeto que se evala a TRUE cuando se va a salir del
                  bucle externo o si no, FALSE. "ExitCond" se evala antes de
                  cada actualizacin de la pantalla y de cada evaluacin de
                  tecla de la aplicacin.

   AppError       El objeto controlador de errores que se evala si se
                  produce un error durante la parte del bucle externo
                  parametrizado de evaluacin de una tecla .

      El bucle externo parametrizado mismo no devuelve ningn resultado. Sin
      embargo, cualquiera de las teclas usadas por la aplicacin puede
      devolver resultados a la pila de datos o de cualquier manera que se
      quiera.



                                 Pgina 113







      21.4.1   Utilidades del Bucle Externo Parametrizado

      La palabra del bucle externo parametrizado "ParOuterLoop" consiste
      enteramente en llamadas (con el adecuado control de errores) a sus
      cuatro palabras de utilidades RPL, que son, en orden:

          POLSaveUI  Salva el actual interface de usuario (UI) en un entorno
                     temporal. No toma argumentos y no devuelve ningn
                     resultado.

          POLSetUI   Dispone (configura) el interface de usuario actual de
                     acuerdo a los mismos parmetros que requiere el
                     "ParOuterLoop". No devuelve ningn resultado.

          POLKeyUI   Muestra, lee y evala teclas, controla errores y sale de
                     acuerdo al interface de usuario especificado por
                     "POLStetUI". No toma ningn argumento ni retorna ningn
                     resultado.

          POLRestoreUI  Restaura el interface de usuario salvado por
                        "POLSaveUI" y abandona el entorno temporal. No toma
                        ningn argumento ni devuelve ningn resultado.

      (Adems de las cuatro utilidades de arriba, se usa la utilidad
      "POLResUI&Err" para proteger el interface de usuario salvado en el caso
      de un error que no se controla dentro del bucle externo parametrizado.
      Vase "Operacin del Bucle Externo Parametrizado" y "Control de Errores
      con las Utilidades", ms abajo)

      Estas utilidades las pueden usar las aplicaciones que requieren un
      mayor control sobre el interface de usuario. Por ejemplo:

         +  Para una ejecucin ptima, una aplicacin puede crear un entorno
            temporal con variables temporales con nombres nulos despus de
            llamar a "POLSaveUI", luego acceder a las variables con nombres
            nulos "dentro" de "POLKeyUI", ya que solo "POLSaveUI" crea un
            entorno temporal del bucle externo parametrizado y solo
            "POLRestoreUI" accede al mismo entorno.

         +  Para evitar gastos innecesarios y que consumen tiempo, una
            aplicacin que usa mltiples bucles externos parametrizados
            consecutivos (no anidados) puede llamar a "POLSaveUI" al
            principio de la aplicacin, luego llamar a "POLSetUI" y a
            "POLKeyUI" mltiples veces a lo largo de la aplicacin y
            finalmente llamar a "POLRestoreUI" al final de la aplicacin.













                                 Pgina 114






      21.4.2   Examen del Bucle Externo Parametrizado

      El bucle externo parametrizado opera como se esboza a continuacin.

            ("POLSaveUI")
            Salva el interface del sistema o del usuario de la aplicacin
            actual

            Si se produce un error

              ("POLSetUI")
               Configura el interface de usuario de la nueva aplicacin

              ("POLKeyUI")
               Mientras "ExitCond" se evale a FALSE 
                  {
                     Evala "AppDisplay"
                     Si se produce un error
                        Lee y evala una tecla
                     Entonces
                        Evala "AppError"
                  }

            Entonces

               Restaura el interface de usuario y ERRJMP

            ("POLRestoreUI")
            Restaura el interface de usuario salvado

      El bucle externo parametrizado crea un entorno temporal cuando salva el
      interface de usuario actual y abandona este entorno cuando restaura un
      interface de usuario salvado. Esto significa que las palabras que
      operan en el entorno temporal ms reciente, tales como "1GETLAM", NO se
      deberan usar "dentro" del bucle externo parametrizado (o sea, en una
      definicin de tecla o en el objeto de actualizacin de la pantalla de
      la aplicacin) A MENOS QUE el entorno temporal deseado se cree DESPUES
      DE llamar a "POLSaveUI" y se abandone antes de llamar a "POLRestoreUI".
      En los entornos temporales creados antes de llamar al bucle externo
      parametrizado, las aplicaciones deberan crear y operar con variables
      temporales con nombre.


















                                 Pgina 115






      21.4.3   Controlar Errores con las Utilidades

      Para asegurar que puede restaurar adecuadamente un interface de usuario
      si se produce un error dentro de una aplicacin, el bucle externo
      parametrizado protege el interface de usuario salvado estableciendo una
      trampa de error inmediatamente despus de su llamada a "POLSaveUI",
      como se muestra a continuacin:

       ::
         POLSaveUI             ( salva el interface de usuario actual )
         ERRSET                ( prepara la restauracin del interface de
                                 usuario salvado en caso de error )
           ::
             POLSetUI          ( Configura el interface de usuario de la
                                 aplicacin )
             POLKeyUI          ( muestra, lee y evala )
           ;
         ERRTRAP               ( si error, entonces restaura el interface de
                                 usuario salvado y da error )
           POLResUI&Err
         POLRestoreUI          ( restaura el interface de usuario salvado )
       ;


      El propsito  de la utilidad soportada "POLResUI&Err" es restaurar el
      interface de usuario salvado por "POLSaveUI" y luego dar error.

      Las aplicaciones que usan las utilidades del bucle externo
      parametrizado en vez del "ParOuterLoop" TIENEN que incluir este mismo
      nivel de proteccin del interface de usuario salvado en el control de
      errores .


      21.4.4   La Pantalla

      No hay ninguna pantalla por defecto en el bucle externo parametrizado;
      la aplicacin es la responsable de establecer la pantalla inicial y de
      actualizarla.

      Hay dos maneras en que una aplicacin puede actualizar la pantalla: con
      el parmetro del bucle externo "AppDisplay" o con las asignaciones de
      teclas. Por ejemplo, si el usuario pulsa la tecla flecha-derecha para
      mover un resalte de una columna de matriz a otra, la asignacin de la
      tecla flecha-derecha puede o bien pasar informacin a "AppDisplay" (a
      menudo de modo implcito) para manejar el cambio o el objeto de
      asignacin de la tecla puede cambiar l mismo la pantalla. Ambos
      mtodos tienen sus ventajas en diferentes circunstancias.












                                 Pgina 116






      21.4.5   Control de Errores

      El parmetro de control de errores del bucle externo "AppError" es
      responsable de procesar cualquier error generado durante la evaluacin
      de teclas dentro del bucle externo parametrizado. Si ocurre un error,
      se evala  "AppError". "AppError" debera determinar el error
      especfico y actuar en consecuencia. Si una aplicacin no puede manejar
      algunos errores, entonces "AppError" se debe especificar como "ERRJMP".


      21.4.6   Asignaciones de Teclas Fsicas

      Cualquier tecla de la HP 48, en cualquiera de los seis planos (sin
      desplazamiento, desplazada a la izquierda, desplazada a la derecha,
      alfa sin desplazar, alfa desplazada a la izquierda y alfa desplazada a
      la derecha) puede asignarse durante la ejecucin del bucle externo
      parametrizado. El parmetro del bucle externo "AppKeys" especifica las
      teclas a asignar y sus nuevas asignaciones.

      Si una tecla no est asignada por una aplicacin y el parmetro del
      bucle externo "NonAppKeyOK?" es TRUE, entonces se produce el proceso
      estndar o por defecto, de acuerdo con el parmetro del bucle externo
      "DoStdKeys?". Por ejemplo, si el modo de teclas de usuario est
      activado y la tecla tiene una asignacin de usuario, entonces se
      procesa la tecla de usuario si "DoStdKeys?" es FALSE o se procesa la
      tecla estndar si "DoStdKeys?" es TRUE. Si "NonAppKeyOK?" es FALSE,
      entonces todas las teclas que no son de la aplicacin emiten un pitido
      de advertencia de tecla cancelada y no hacen nada ms.

      En general, NonAppKeyOK? debe ser FALSE para mantener un control total.





























                                 Pgina 117






      Las asignaciones de teclas de la aplicacin se especifican con el
      objeto secundario "AppKeys" que se pasa al bucle externo parametrizado.
      El procedimiento debe tomar como sus argumentos un cdigo de tecla y
      una especificacin del plano y debe devolver la definicin deseada de
      la tecla y TRUE si la aplicacin define la tecla o FALSE si la
      aplicacin no lo hace. Especficamente, el diagrama de la pila del
      procedimiento de asignacin de teclas debe parecerse a esto:

            ( #CdigoTecla #Plano --> DefTecla TRUE )
            ( #CdigoTecla #Plano --> FALSE )

      La definicin de tecla resultante "DefTecla" ser procesada por el
      controlador principal de teclas "DoKeyOb".

      Las asignaciones de teclas de la aplicacin especificadas como
      procedimientos tienen generalmente una lgica de la forma

            Si #Plano NO est Desplazado  (o primer plano que nos interesa)
            Entonces
              Procesa #CdigoTecla en el plano no desplazado
            Si no
               Si #Plano est  DesplazadoIzquierda (o siguiente plano que nos
                                                   interesa)
               Entonces
                  Procesa #CdigoTecla en el plano desplazadoIzquierda
                  ...
               Si no
                  seal sin definicin

      Esto se puede implementar en RPL de la forma       

            kpNoShift   #=casedrop :: (procesa el plano nodesplazado) ;
            kpLeftShift #=casedrop :: (procesa el plano desplaz-Izq.) ;
            2DROP FALSE

      Cada controlador de un plano tiene generalmente una lgica de la forma

  Si #CdigoTecla es 7  (o el primer cdigo de tecla que nos interesa)
  Entonces
      Devuelve la definicin del cdigo de tecla 7 y TRUE
  Si no
     Si #CdigoTecla es 20  (o el siguiente cdigo de tecla que nos interesa)
     Entonces
        Devuelve la definicin del cdigo 20 y TRUE
     Si no
        Seal sin definicin

      Esto se puede implementar en RPL de la siguiente forma:

            kcMathMenu ?CaseKeyDef :: TakeOver (procesa MTH) ;
            kcTan      ?CaseKeyDef :: TakeOver (procesa TAN) ;
            ( todas las dems teclas )
            DROP FALSE






                                 Pgina 118






      Para ahorrar cdigo y hacer las definiciones de teclas ms legibles, la
      palabra de control de estructuras "?CaseKeyDef" substituye la porcin 

            #=casedrop :: ' <DefTecla> TRUE ;

      del cdigo con 

            ?CaseKeyDef <DefTecla>

      Ms especficamente, ?CaseKeyDef" se usa de la forma 

             ... #CdigoTecla #TestCdigoTecla ?CaseKeyDef <DefTecla> ...

      If "#CdigoTecla" es igual a "#TestCdigoTecla", entonces "?CaseKeyDef"
      elimina "#CdigoTecla" y "#TestCdigoTecla", sube "DefTecla" y TRUE, y
      sale del secundario que la llam.  Si no, "?CaseKeyDef" elimina slo a
      "#TestCdigoTecla", se salta "DefTecla" y contina.


      21.4.7   Asignaciones de Teclas de Mens

      Una aplicacin puede especificar una asignacin inicial cualquiera de
      las teclas de men en cualquiera de los tres planos (normal, deszp.izq.
      y deszp.der.) para que se inicialice cuando se inicia el bucle externo
      parametrizado. El parmetro del bucle externo "AppMenu" especifica el
      objeto de inicializacin (una lista o un secundario) para el men de la
      aplicacin o FALSE, indicando que se dejar intacto el men actual.
      Cuando se sale del bucle externo parametrizado, se restaura
      automticamente el men anterior.

      Si "AppMenu" es una lista nula, entonces se hace un conjunto de seis
      asignaciones de teclas nulas de men. Si "AppMenuu" es FALSE, entonces
      se mantiene el men presente cuando se llama al bucle externo
      parametrizado.

      NOTA: las asignaciones de teclas fsicas (teclas "duras"/hardkeys)
      tienen prioridad sobre las asignaciones de teclas de men (teclas
      "blandas"/softkeys). Esto significa que el controlador de teclas
      fsicas debe incluir la siguiente lnea si se van a procesar teclas de
      men:

                DUP#<7 casedrpfls

      El parmetro AppMenu toma la siguiente forma:

       {
         Definicin de la Tecla de Men 1
         Definicin de la Tecla de Men 2
         ...
         Definicin de la Tecla de Men n
       }

      Donde cada definicin de tecla de men toma una de las cuatro formas
      siguientes:





                                 Pgina 119






         NullMenuKey

         { ObjEtiqueta :: TakeOver (Accin) ; }

         { ObjEtiqueta {
                      :: TakeOver (Accin Primaria) ;
                      :: TakeOver (Accin Deszp.Izq.) ;
                    }

         { ObjEtiqueta {
                      :: TakeOver (Accin Primaria) ;
                      :: TakeOver (Accin Desp.Izq.) ;
                      :: TakeOver (Accin Desp.Der.) ;
                    }
         }

      Un ObjEtiqueta puede ser cualquier objeto, pero normalmente es una
      cadena de caracteres o un grob de 8x21. Ver el ejemplo que hay ms
      adelante que ilustra el uso de teclas de men. La palabra NullMenuKey
      inserta una tecla de men en blanco que pita cuando se pulsa.


      21.4.8   Evitar Entornos Suspendidos

      Una aplicacin puede tener que permitir evaluar comandos y objetos de
      usuario arbitrarios, pero no querr que el entorno actual sea
      suspendido por los comandos "HALT" o "PROMPT". Si el parmetro del
      bucle externo "SuspendOK?" es FALSE, entonces cualquier comando que
      suspendera el entorno genera el error "HALT not Allowed" (HALT no
      Permitido), permitiendo que "AppError" lo maneje. Si "SuspendOK?" es
      TRUE, entonces la aplicacin debe estar preparada para controlar las
      consecuencias. Aqu los peligros son muchos y graves.

      En todas la aplicaciones previsibles, "SupendOK?" debe ser FALSE.


      21.4.9   Especificar una Condicin de Salida

      El parmetro "ExitCond" del bucle externo es un objeto que se evala a
      TRUE cuando se va a salir del bucle externo o a FALSE si no es as.
      "ExitCond" se evala antes de cada evaluacin de tecla.

















                                 Pgina 120






      21.4.10  Ejemplo de ParOuterLoop

       *---------------------------------------------------------

       *
       * Incluye el fichero cabecera KEYDEFS.H, que define palabras como
       * kcUpArrow para nmeros fsicos de teclas.
       *
       INCLUDE KEYDEFS.H
       *
       * Incluye los ocho caracteres necesarios para la carga binaria
       *
       ASSEMBLE
               NIBASC  /HPHP48-D/
       RPL
       *
       * Inicia el secundario
       *
       ::
         RECLAIMDISP           ( *Llama la pantalla alfa* )
         ClrDA1IsStat          ( *Desactiva temporalmente el reloj* )
       *                       ( *Prubalo sin ClrDA1IsStat* )
         ZEROZERO              ( #0 #0 )
         150 150 MAKEGROB      ( #0 #0 150x150grob )
         XYGROBDISP            (  )
       *
       * Dibuja lneas diagonales.  Recuerda que LINEON precisa que
       *  #x2>#x1 !
       *
         ZEROZERO              ( #x1 #y1 )
         149 149               ( #x1 #y1 #x2 #y2 )
         LINEON                ( *Dibuja lnea* )
         ZERO 149              ( #x1 #y1 )
         149 ZERO              ( #x1 #y1 #x2 #y2 )
         LINEON                ( *Dibuja lnea* )
       *
       * Pone texto
       *
         HARDBUFF
         75 50 "SCROLLING"     ( HBgrob 75 150 "SCROLLING" )
         150 CENTER$3x5        ( HBgrob )
         75 100 "EXAMPLE"      ( HBgrob 75 100 "EXAMPLE" )
         150 CENTER$3x5        ( HBgrob )
         DROPFALSE             ( FALSE )
         { LAM Exit } BIND     ( *Une la bandera de salida del POL* )
         ' DispMenu.1          ( *La Accin de Pantalla muestra el men* )
         ' ::                  ( *Controlador de las teclas fsicas*   )
           kpNoShift #=casedrop
             ::
                DUP#<7 casedrpfls ( *habilita las teclas de mens* )
                kcUpArrow    ?CaseKeyDef
                                 :: TakeOver SCROLLUP ;
                kcLeftArrow  ?CaseKeyDef
                                 :: TakeOver SCROLLLEFT ;
                kcDownArrow  ?CaseKeyDef
                                 :: TakeOver SCROLLDOWN ;



                                 Pgina 121






                kcRightArrow ?CaseKeyDef
                                 :: TakeOver SCROLLRIGHT ;
                kcOn         ?CaseKeyDef
                                 :: TakeOver
                                    TRUE ' LAM Exit STO ;
                kcRightShift   #=casedrpfls
                DROP 'DoBadKeyT
             ;
           2DROP 'DoBadKeyT
         ;
         TrueTrue              ( *Banderas del control de teclado* )
         {
           { "TOP" :: TakeOver JUMPTOP ; }
           { "BOT" :: TakeOver JUMPBOT ; }
           { "LEFT" :: TakeOver JUMPLEFT ; }
           { "RIGHT" :: TakeOver JUMPRIGHT ; }
           NullMenuKey
           { "QUIT" :: TakeOver TRUE ' LAM Exit STO ; }
         }
         ONEFALSE              ( *Primera fila, no suspender* )
         ' LAM Exit            ( *Condicin de salida de la Aplicacin* )
         ' ERRJMP              ( *Controlador de Errores* )
         ParOuterLoop          ( *Ejecuta el ParOuterLoop* )
         RECLAIMDISP           ( *Cambia el tamao y borra la pantalla* )
         SetDAsBAD             ( *Redibuja la Pantalla* )
       ;

      Si se almacena el cdigo anterior en un fichero llamado SCRSFKY.S se
      puede compilar as:

       RPLCOMP SCRSFKY.S
       SASM SCRSFKY.A
       SLOAD -H SCRSFKY.M

      Este ejemplo tambin supone que el fichero KEYDEFS.H o bien est en el
      mismo directorio o se ha modificado el fichero fuente para reflejar la
      ubicacin de KEYDEFS.H. El fichero de control de la carga SCRSFKY.M se
      parece a esto:

       OU SCRSFKY
       LL SCRSFKY.LR
       SU XR
       SE ENTRIES.O
       RE SCRSFKY.O

      El fichero final, SCRSFKY, se puede cargar en modo binario en la HP 48
      y probarse.

      Cuando se est ejecutando SCRSFKY, las teclas de flecha desplazan la
      pantalla y las teclas de men etiquetadas mueven la ventana al extremo
      correspondiente. La tecla [ATTN] finaliza la ejecucin del programa.









                                 Pgina 122



      22.   Comandos del Sistema

      Las siguientes palabras ponen, comprueban o controlan varias
      condiciones o modos del sistema.

       ALARM?          ( --> flag )
                        Devuelve TRUE si se ha cumplido una alarma.
       AtUserStack     ( --> )
                        Declara propiedad del usuario todos los objeto de la
                        pila.
       CLKTICKS        ( --> hxs )
                        Devuelve una cadena hex de 13 nibbles que refleja el
                        nmero de marcas desde el 01/01/0000. Son 8192 marcas
                        por segundo.
       ClrSysFlag      ( # --> )
                        Borra la bandera del sistema (#1 a #64)
       ClrUserFlag     ( # --> )
                        Borra la bandera de usuario (#1 a #64)
       DATE            ( --> %fecha )
                        Devuelve un nmero real con la fecha
       DOBEEP          ( %frecuencia %duracin --> )
                        Comando BEEP
       DOBIN           ( --> )
                        Pone la base en modo BINario
       DODEC           ( --> )
                        Pone la base en modo DECimal
       DOENG           ( # --> )
                        Pone la pantalla en modo ENG con # (0-11) dgitos.
       DOFIX           ( # --> )
                        Pone la pantalla en modo FIX con # (0-11) dgitos.
       DOHEX           ( --> )
                        Pone la base en modo HEXadecimal
       DOOCT           ( --> )
                        Pone la base en modo OCTal
       DOSCI           ( # --> )
                        Pone la pantalla en modo SCI con # (0-11) dgitos
       DOSTD           ( --> )
                        Pone la pantalla en modo STD
       DPRADIX?        ( --> flag )
                        Devuelve TRUE  si la coma actual es .
                        Devuelve FALSE si la coma actual es ,
       SETDEG          ( --> )
                        Pone el modo de ngulo en DEGREES (SEXAGESIMALES)
       SETGRAD         ( --> )
                        Pone el modo de ngulo en GRADS (CENTESIMALES)
       SETRAD          ( --> )
                        Pone el modo de ngulo en RADIANS (RADIANES)
       SLOW            ( --> )
                        Retardo de 15 milisegundos
       TOD             ( --> %time )
                        Devuelve la hora del da de la forma h.ms
       TestSysFlag     ( # --> flag )
                        Devuelve TRUE si la bandera del sistema # est
                        activada
       TestUserFlag    ( # --> flag )
                        Devuelve TRUE si la bandera de usuario # est
                        activada
       VERYSLOW        ( --> )
                        Retardo de 300 milisegundos
       VERYVERYSLOW    ( --> )
                        Retardo de 3 segundos

                                 Pgina 123






       WORDSIZE        ( --> # )
                        Devuelve el ancho de palabra binario
       dostws          ( # --> )
                        Almacena el ancho de palabra binario
       dowait          ( %segundos --> )
                        Espera durante %segundos en estado de sueo ligero.
                         





   














































                                 Pgina 124