A raíz de una consulta que he recibido, se me ocurre que para quien esté
empezando a conocer cómo funciona Forth por dentro, es útil usar una
herramienta que descompile o "destripe" las palabras compiladas en el
diccionario.

El resultado depende del tipo de palabra y de la herramienta utilizada
para destriparla, que generalmente se llama `see` (y de hecho ese es su
nombre en Forth estándar). Por ejemplo, para ver de qué palabras consta
la palabra `create`, haríamos esto:

  see create

Los Forth modernos tienen palabras `see` muy potentes, que son capaces
de destripar cualquier cosa, incluso mostrar el desensamblado de las
palabras que están escritas en ensamblador.

Pero, para empezar, lo más interesante es probar a descompilar nuestras
propias palabras creadas con `:`.

Aunque hay muchas formas de hacer un Forth, en un Forth clásico una
palabra creada con `:` tiene primero la dirección del intérprete de este
tipo de palabras, y después la lista de las direcciones de las palabras
de las que consta.  Así, a partir de esa lista, se puede saber el nombre
de esas palabras y reconstruir el código fuente.

Pero no es tan sencillo, pues algunas palabras no compilan su propia
dirección sino la dirección de otra (o de otras varias).

Por ejemplo, la palabra `if` compila una palabra que generalmente se
llama `0branch` o `?branch`, y después deja un hueco para que `then` o
`else` lo rellenen (en tiempo de compilación) con su propia dirección
dentro de la palabra que está siendo creada.  Así, cuando la palabra que
contiene el `if` funcione, hará o no un salto, al lugar indicado por
`then` o `else`, dependiendo de lo que haya en la pila. Por ello al
descompilar esta palabra no se verá un `if` sino un `0branch` seguido
por una celda que contiene una dirección de memoria.

Una herramienta para descompilar palabras tiene que reconocer esos casos
y mostrar correctamente el `if` original, aunque también las hay más
sencillas, que solo mostrarían el `0branch` y la dirección de memoria
que lo sigue.

Esto que he explicado sobre `if` se aplica a cualquier estructura de
control (`do`, `begin`, `case`...), pues lo que hacen las estructuras de
control es compilar saltos condicionales.

En mi librería Afera para Abersoft Forth incluí una versión adaptada y
mejorada de una antigua herramienta llamada `decode`. Solo destripa
palabras creadas con `:`, y además lo hace de la forma sencilla, es
decir, sin reconstruir las estructuras de control originales. El código
fuente puede ser útil para quienes quieran conocer cómo funciona una
herramienta de este tipo, y así hacerse una mejor idea de cómo Forth
compila las palabras con `:`:

  http://programandala.net/es.programa.afera.html

Otra palabra útil para familiarizarse con las interioridades de Forth es
`dump`, que muestra el contenido de una zona de memoria. Por ejemplo,
para ver 32 octetos a partir de la dirección 16384 haríamos así:

  16384 32 dump

Y por supuesto la podemos usar para ver las direcciones de las palabras
de que consta una palabra, por ejemplo, compilada con `:`:

  : mipalabra  drop dup rot ;

En fig-Forth y Forth-79 haríamos así, para ver los 6 octetos del campo
de datos de `mipalabra`, que contiene las tres direcciones de ejecución
de las tres palabras de que consta (`drop`, `dup` y `rot`):

  ' mipalabra 6 dump

En Forth-83 haríamos así:

  ' mipalabra >body 6 dump

En la mayoría de los sistemas estándar más recientes (Forth-94 y
Forth-2012) debería funcionar el mismo código de Forth-83, pues aunque
se supone que `>body` solo funciona con palabras creadas con `create`,
en la práctica suele funcionar también con palabras creadas con `:`.

-- 
Marcos Cruz
http://programandala.net

Responder a