Programando en SYSTEM RPL
Funcionamiento del compilador JAZZ
Mario de Lama malar@arrakis.es
http://www.arrakis.es/~malar
Regresar
La librería JAZZ
6.5 (135KB) tiene el número 992 y ocupa 71925 by. La librería
HPTABS (con las tablas de etiquetas o nemotécnicos) tiene el número
993 y ocupa 34138 by y la librería de fuentes pequeñas UFL
es la 257 y ocupa 3066 by (vienen en el paquete de JAZZ). Para aquellos
que no tengan tarjeta de expansión de memoria les va a ser imposible
el trabajar con la librería JAZZ completa y tendrán que optar
por la versión light
(125KB) que puede ser instalada con o sin editor ED (también
viene con JAZZ), en ambos casos te puedes olvidar del debugger. Te recomiendo
que si es este tu caso uses la versión con ED, te ocupará
45401.5 by frente a los 29901.5 sin el editor pero si tienes que programar
con el editor de la calculadora vas listo. Resumiendo, para gente con tarjeta
de memoria:
JAZZ (71925) + HPTABS (34138) + UFL (3066) = 109129 by
Los que no tengan la tarjeta:
JAZZlight_con_ED (45401.5) + HPTABS (34138) + UFL (3066) = 82605.5
by
También recomendaría tener, al menos, la librería
1219 HACK v9.2 (91KB)
que te ocupa 17664 by
Una vez todo en la calculadora (si no sabes como se
instalan las librerías aprende primero User y luego prueba con System)
ve a la librería JAZZ y verás que la primera variable es
ASS. Es el comando que compila los programas, sirve tanto para system como
para ML o para crear librerías aunque esto último es mucho
más fácil con la librería HACK. Muchos otros comandos
sirven para system y ML pero yo siempre me voy a referir a la parte system.
Si quieres saber más de ellos ve a la documentación de JAZZ
que es de donde estoy extrayendo el presente documento.
Para escribir el código fuente debes hacerlo en una cadena que
comience por "::" (DOCOL) y termine con ";" (SEMI). El punto y coma último
tampoco es necesario. Para compilarlo pon la cadena en 1: y presiona ASS,
verás que bonita colección de External obtienes. Vamos a
hacer la prueba, escribe lo siguiente:
":: CK1 DUP ;"
Aquí siempre importa si una letra es mayúscula o minúscula,
irás viendo que hasta los espacios y saltos de línea son
importantes a veces. Ahora presiona ASS y tendrás en la pila tu
primer programa system. Si pones el comando User DUP en una lista { DUP
} y ejecuta OBJ-> DROP. Tendrás:
1: DUP
Ejecuta el comando DIS de JAZZ y verás
que obtienes el mismo código ":: CK1 DUP ;"
Si el flag 1 está fijado puedes ver el desarrollo del proceso
de compilación en el área de estado de la calculadora pero
no te lo recomiendo ya que el proceso se ralentiza mucho. Si durante la
compilación se encuentra un error nos aparece una pantalla como
la de la Fig.1:
En la parte izquierda de la primera línea del área de estado
nos aparece el mensaje de error, en este caso "Invalid Token", en la derecha
aparece la línea/posición en que se ha encontrado el error
"4/00030". En la izquierda de la segunda línea se nos ofrece el
objeto sospechoso "CK&DISPATCH12". En 2: está el código
fuente y en 1: la posición del error, de forma que si ejecutamos
ED (el editor) el cursor se pone directamente en la posición 30.
Podéis ver en la Fig.2 que la C de CK&DISPATCH12 está
invertida. Si dudamos de cómo se escribe el comando podemos borrar
parte de él dejando, por ejemplo, CK&DISPAT. Si presionamos
ahora la tecla PRG de la calculadora nos aparece la Fig.3 con todas las
etiquetas de los comandos que comienzan por esa cadena. Nos desplazamos
con los cursores hasta dejar en 1ª posición el deseado, en
este caso CK&DISPATCH1 y presionamos ENTER, a continuación ON
para regresar al editor. Da lo mismo que la cadena "pista" CK&DISPAT
estuviera en mayúsculas o minúsculas, desaparece y en su
lugar aparece la etiqueta correctamente escrita como vemos en la Fig.4:
 |
Fig. 4 |
Ahora si podemos presionar ENTER para regresar a la pila y volver a compilar
el fuente (en ED no funciona ON para salir sin guardar los cambios, siempre
se sale con ENTER).
Os aconsejo que estudieis la documentación del editor ED (en
la documentación de JAZZ). Tiene numerosas funciones que nos facilitan
en gran medida la programación. Unos ejemplos:
-
Presiona STO mientras estás en él: Sales a la pila. Para
volver a entrar presiona CONT.
-
Con la tecla CST (MEXEC) ejecutas el macro de pulsaciones
que inicias con 'CST desplazada a la izquierda' (MSTART) y 'terminas con
CST desplazada a la derecha' (MEND).
-
....
Los comentarios (texto que no se compilará)
pueden introducirse de dos formas:
-
Líneas que comienzan por *
-
Cualquier texto encerrado entre paréntesis ( )
Es muy conveniente al programar en system el utilizar la base hexadecimal
en vez de la decimal.
Cuando deseamos introducir una cadena de caracteres
debemos escribirla:
$ "string" (Poniendo un espacio tras $ y antes de abrir comillas)
Para facilitar el trabajo podemos presionar, con ED en modo alfa, la
tecla "comillas dobles" (tecla "-" desplazada a la derecha) y veremos como
aparece la cadena anterior. Si, también en modo alfa, presionamos
tecla "-" desplazada a la izquierda nos aparecen los delimitadores de los
objetos secondary ¿Qué son?
todo objeto entre DOCOL y SEMI:
::
;
Esto es: El equivalente System de los programas User. Para saber qué
prólogo hay que poner a cada tipo de datos lo mejor es poner el
dato deseado en la pila y descompilarlo con DIS. Lo editamos y vemos su
estructura.
Cuando deseemos introducir un comando User en el
código sólo debemos anteponerle el caracter "x". Por ejemplo,
para introducir el comando PICT deberemos compilar
::
xPICT
;
La palabra INCLOB seguida de un nombre de variable
global (ID en system) incluye el contenido de dicha variable en el punto
en el que se encuentre la etiqueta INCLOB. Ejemplo: Siendo A una variable
que contiene: << 2 ->LIST >> si compilamos:
::
%1 %2
INCLOB A
;
se obtiene el secondary:
1 2 << 2 ->LIST >>
Cuando dentro de la variable no se encuentra un objeto
si no código fuente, la etiqueta a poner es INCLUDE. Ejemplo: Siendo
A una variable que contiene: "%2 x->LIST" si compilamos:
::
%1 %2
INCLUDE A
;
se obtiene el secondary:
1 2 2 ->LIST
Cuando deseamos hacer una macro utilizaremos DEFINE
etiqueta código (todo en una sola fila). En todo lugar del
código en el que pongamos la etiqueta el compilador la reemplazará
por el código asociado. Ejemplo: Si compilas:
::
DEFINE 4dup DUPDUP DUP
4dup
;
y posteriormente lo descompilas obtienes:
::
DUPDUP
DUP
;
Recuerda que también puedes establecer macros con ED y los comandos
MEXEC, MSTART y MEND, todos ellos en la tecla CST.
Las variables temporales (equivalentes a las variables
locales de User) pueden ser con nombre o anónimas (NULLLAM). Estas
últimas son más rápidas y ocupan menos que las otras
pero, al no tener nombre, son más difíciles de usar. JAZZ
introduce una fácil forma de usar las variables temporales anónimas.
Para introducirlas normalmente escribiríamos:
::
' (el siguiente comando no se evalúa, sólo se pone en la pila)
NULLLAM (pone NULLLAM en la pila)
TWO (pone el binary integer 2)
NDUPN (duplica NULLLAM)
DOBIND (crea las variables)
2GETLAM (trae a la pila el contenido de la 2ª variable)
1PUTLAM (almacena este valor en la 1ª variable)
ABND (destruye las variables)
;
Con las macros para variables temporales de JAZZ escribiríamos
::
{{ A B }} (no dejar espacios entre las llaves y si entre llave y nombre)
B (trae a la pila el contenido de la 2ª variable)
A! (almacena este valor en la 1ª variable)
ABND (destruye las variables)
;
Podeis compilar y descompilar este segundo código. Obtendreis el
primero. Para más información ver el apartado 2.2.1 de la
documentación de JAZZ
Se puede usar JAZZ sin ED, RPL.TAB o DIS.TAB pero
no es nada conveniente. Como habeis podido ver, ED es un editor genial
para la programación y necesita para ejecutarse de la librería
de fuentes pequeña UFL. También la necesitan el comando EC
(sirve para ver el contenido de RPL.TAB) y VV que es un visor de texto
y gráficos.
RPL.TAB es una librería que incorpora las direcciones de memoria
de los comandos system y su etiqueta de forma que cuando ASS compila se
reemplazan las etiquetas por las direcciones de memoria. Si no tenemos
RPL.TAB, JAZZ compilará el fuente pero este sólo puede estar
formado por las direcciones de memoria de cada comando y descompilará
en una cadena formada sólo por direcciones de memoria. Como os podeis
imaginar sería casi imposible programar así. RPL.TAB puede
modificarse para añadir, quitar o cambiar etiquetas.
EC es un browser muy útil para ver las etiquetas y direcciones
de esta tabla, si damos al cursor derecho entramos en el código
de la etiqueta que hay en primer lugar del browser. Volvemos de nuevo al
estado normal con ENTER. También podemos poner en la pila la dirección,
la etiqueta o ambas cosas del comando deseado. Es también muy conveniente
tener DIS.TAB si queremos descompilar rápidamente. Gracias a ella
DIS hace una búsqueda binaria de las etiquetas en vez de secuencial.
El comando SDB inicia un debugger que vale su peso
en oro. Veamos una somera explicación de sus comandos:
-
->SST Ejecuta el siguiente comando mostrandolo en la 1ª línea
del área de estado. En la 2ª muestra el/los siguientes. Si
se presiona desplazado a la derecha ejecuta el resto de comandos del actual
flujo (normalmente el actual secondary) como si
fueran un sólo objeto
-
->IN Si es posible entra en el siguiente comando como si fuera una
subrutina (que normalmente lo es) y lo ejecuta paso a paso.
-
SNXT Nos muestra el siguiente comando a ejecutarse.
-
SST-> Ejecuta los comandos siguientes uno tras otro como si fueramos
presionando ->SST cada poco tiempo. Cada pulsación posterior cambia
al modo rápido/lento. Para interrumpir este proceso presiona una
tecla que no influya en el desarrollo del programa. Por ejemplo [7] no
influye, sólo aparece en la línea de comandos y presionando
[ON] desaparece y hemos interrumpido el proceso, [ENTER] duplica el objeto
de 1: y luego no sabremos si el comando debe o no ser duplicado. También
puedes poner un punto de ruptura con el comando SBRK (mira el 5º comando
siguiente).
-
IN-> Ejecuta los comandos siguientes como si fueramos presionando
->IN cada poco tiempo. Cada pulsación posterior cambia al modo rápido/lento.
Se interrumpe de igual manera que SST->.
-
DB Incicia el debugger del lenguaje ML en el siguiente objeto Code.
-
KILL Finaliza la ejecución del programa en el punto actual
y sale del debugger.
-
SKIP Salta el siguiente comando. Si la presionamos desplazada a
la derecha salta el resto del actual flujo.
-
SEXEC Ejecuta el objeto 1: de la pila de datos como el siguiente
comando.
-
SBRK Toma el objeto de 1: como punto de ruptura, esto es, cuando
se ejecuta SST-> o IN-> y se encuentra este objeto, se detiene la ejecución
de dichos comandos.
-
LOOPS Nos muestra un browser con el entorno de bucles actual. Podemos
desplazarnos con los cursores arriba y abajo. Para salir presionar cualquier
otra tecla. Presionandola desplazada a la derecha pone el actual entorno
en la pila.
-
LAMS Funciona igual que LOOPS pero en el entorno de variables temporales.
Para desplazarnos dentro del entorno presionamos los cursores arriba y
abajo. Para acceder a otros entornos anteriores o posteriores de variables
temporales: cursores izquierdo y derecho. Presionandola desplazada a la
derecha pone el actual entorno en la pila.
-
IN? Se activa o desactiva presionando alternativamente (aparece
o desaparece la caja en el menú). Si está activado ->IN no
entra nunca en los secondaries. También
previene que SST-> e IN-> entren en las subrutinas ROM.
El comando SSTK nos introduce
en un nuevo Kernel con una pila de 5 niveles y, si el flag 3 está
desactivado, permite ver los programas como si estuvieran descompilados
con DIS. Desaparecen los External.
Regresar