Dudas
Como introducir un Code o External en un programa User

Mario de Lama   malar@arrakis.es
http://www.arrakis.es/~malar

>Hola, seguí tu recomendacion y estoy programando en USER antes que
>en SYS, pero tengo una preguntica.
>He visto algunos programas en USER y he encontrado dentro del programa la
>palabra Code ( creo que eso es un programa que está "como comprimido",
>perdona mi ignorancia en esa palabra, ya que segun los argumentos que
>esten en la pila, cuando se ejecuta esa parte del programa ( Code ) este
>devuelve un resultado a la pila.

Al final de mi pasado mail te comento de pasada que los programas en System aparecen en la pila como External y los que están desarrollados en ML (Machine Language) aparecen como Code. Por tanto no están comprimidos sino que son programas creados en lenguaje máquina (bastante más complicado, peligroso y rápido que el System)

>Conozco un programa llamado CODER que toma un programa y lo "mete" en esa
>palabra ( espero que me entiendas ).

CODER es un programa de Simone Rapisarda & James Cloos que codifica una cadena (GD 5). Creo que te refieres a CODE, de Richard Steventon & Joe Horn que, efectivamente, "transforma" cualquier objeto del nivel 1 en un Code (puedes encontrarlo en el GD 11).

>Mi pregunta es ¿Cómo puedo colocar un programa que este "metido" en Code
>como un subprograma de uno principal? Ejemplo
>
>IF 8 9 == THEN Code END
>
>Como te dije anteriormente Code es un programa dentro del programa mayor y
>no un nombre de variable local que va a ser llamado.
>
>Algo similar encontre como te lo muestro en el siguiente ejemplo,
>
>IF 8 9 == THEN "BZ A-"*+..." Code END ( es solo un ejemplo )
>
>Ves que "BZ A-"*+..." es algo comprimido con BZ4 y que luego Code lo
>descomprime.
>
>?????? COMO HACEN ESO ????????

Ese objeto Code es el programa UBZ metido en medio del código User. No sería difícil introducir un Code o un External en el código User si lo tenemos en la pila cuando estamos editándolo. Sólo debiéramos ir al menú EDIT y presionar ^|STK, entraríamos en la pila, iríamos con los cursores hasta el nivel donde se encuentra el objeto y presionaríamos ECHO, finalmente al presionar ENTER regresaríamos al modo de edición del programa y veríamos que el objeto de marras está ya en el código de nuestro programa. Pega: esto no funciona con objetos que no sean User, el compilador los interpreta como nombres de variables y no como Code o External y al ejecutar el programa nos encontraríamos que en vez de ejecutarse UBZ en la pila nos aparece 'Code'. Tampoco podemos introducir el carácter nulo ya que el editor de la HP no puede editarlo.

Tampoco sería difícil si el comando LIST-> (o el OBJ->) funcionara con un programa igual que con una lista. Desharíamos el programa, colocaríamos en el nivel 1 el objeto que deseáramos y luego iríamos en la pila hasta el lugar deseado, presionaríamos ROLLD y ya con el objeto en su lugar sólo deberíamos modificar el número que LIST-> nos devuelve en 1: (según hayamos añadido o quitado elementos del programa). Finalmente la cosa fallaría ya que no tenemos tampoco el comando User equivalente a ->LIST que nos transforma la pila en un programa, pero bueno, son detalles :-)

En User no podemos hacer esto porque OBJ-> no funciona con programas, pero en System existe "INNERCOMP" (al que podemos llamar con #054AFh SYSEVAL)

Su uso: Ponemos un programa en el nivel 1, por ejemplo << 1 2 3 >>, y ejecutamos #054AFh SYSEVAL, como resultado tendremos el programa deshecho en la pila y en el nivel 1 un binary integer (el equivalente al clásico tipo de dato integer de cualquier lenguaje de programación) que nos indica el número de elementos:

6: <<
5: 1
4: 2
3: 3
2: >>
1: <5d>   @ o <5h> si tenemos elegida la base hexadecimal

Esta pila es lo que se conoce por metaobjeto.

Estos binary integers no pueden manipularse con User. Ahora sólo queda poner el Code o External deseado en la pila y llevarlo a su lugar con ROLLD, luego aumentamos el binary a <6d> y ya está. Bueno, nos queda volver a transformar el metaobjeto en programa con la palabra de System "::N", o llamando a su dirección de memoria con #05445h SYSEVAL.

Como es un rollo hacer todo esto (también habría que modificar los binary integers con SYSEVAL), hay gente que ya ha pensado en ello y ha creado programas que además de funcionar bien hacen chequeos de datos para impedir que se nos borre la memoria. Si usas la librería <-LIB-> v2.3 (18k) que te envío puedes, además de hacer y deshacer librerías y muchas otras cosas, usar OB-> para deshacer cualquier cosa y ->PRG para rehacerla (son comandos de la librería).

A pesar de todo, la cosa no te será fácil del todo ya que si cogemos tu ejemplo << IF 8 9 == THEN "BZ A-"*+..." Code END >> y lo deshacemos en la pila con OB-> tendremos:

10: <<
9: IF
8: 8
7: 9
6: ==
5: THEN
4: "BZ A-"*+..." Code
3: END
2: >>
1: 9

Esta vez en vez de un integer tenemos un real, que ya si podemos manipular.

Según esto, todo lo que hay entre THEN y END es un sólo objeto, quiere esto decir que si quieres meter otra cosa en esta cláusula has de tomar "BZ A-"*+..." Code del nivel 4: y deshacerlo con OB->, poner lo que quieras en el lugar deseado y volver a rehacerlo con PRG-> (no hay que poner delimitadores << >>), luego llevarlo hasta el nivel 4: y volver a rehacerlo todo. Si la cláusula IF estuviese dentro de, por ejemplo, un bucle START NEXT, te quedaría en la pila:

n: <<
....

i: START
i-1: ...... THEN "BZ A-"*+..." Code END .........
i-2: NEXT
...

1: n+1

Tendrías que deshacer unos cuantos objetos, manipularlos, colocarlos en el lugar debido y rehacerlos. Es un poco lioso pero ...

Finalmente, otra forma de hacerlo sería descompilar con JAZZ nuestro programa y el Code o External, tendremos dos cadenas de caracteres que uniremos sumándolas. Las editamos con ED (viene con JAZZ) o con String Writer (ya que puede haber caracteres nulos) y sólo tenemos que cortar y pegar donde deseemos el código descompilado del Code o External. Finalmente lo volvemos a compilar todo y ya está.

>Gracias por tu atencion.

A mandar que para eso estamos.

>pta : el curso de USER que tienes en tu pagina es muy bueno.

Gracias, tú si sabes apreciar lo bueno :-)
Si tienes más dudas ya sabes dónde estoy, un saludo

Soy humano, también me gustan los halagos (N. del T., vamos, mía :-)


Regresar