Un problema más grave que tuve tras sustituir Gforth 0.7.3 por Gforth
0.7.9 fue que algunos programas «estallaban» porque dependían del tamaño
de _colon-sys_, el parámetro de Forth estándar que las palabras `:` y
`:noname` dejan en la pila de control, para ser consumido por `;`.
Este es un pedazo de código, extraído de un proyecto, de los que
dependen de _colon-sys_:
----
: (apart-colon-sys) ( x1 x2 colon-sys -- x1 colon-sys x2 )
( x1 colon-sys x2 -- colon-sys x2 x1 )
[ /colon-sys 2 + ] literal roll ;
: apart-colon-sys ( a xt colon-sys -- colon-sys a xt )
(apart-colon-sys) (apart-colon-sys) ;
: :init ( a -- )
:noname apart-colon-sys (:init) postpone [:init] ;
\ Start a definition that will initialize entity _a_ to its default
\ data. The definition is finished by `;`.
\
\ XXX TODO -- Rewrite, simplify: don't depend on _colon-sys_.
----
`:init` es una palabra que sirve para crear palabras sin nombre que
deberán hacer ciertas acciones predeterminadas al inicio de su ejecuten.
Para configurar esas acciones `:init` necesita usar tanto el _xt_
devuelto por `:noname` como el parámetro recibido en la pila. Pero antes
el _colon-sys_ dejado por `:noname` debe ser apartado para que no
estorbe...
Por cierto, el código asume que la pila de control está implementada en
la pila de datos, lo que no tiene por qué ser el caso. No obstante, se
trataba de un apaño provisional para hacer que el código funcionara.
Así, para salir del paso, había creado la constante `/colon-sys` con el
tamaño en celdas que ocupa el citado parámetro estándar, cuyo tamaño
depende de cada sistema Forth, y que en su día averigüé haciendo algunas
pruebas. Fue una ingenuidad suponer que ese valor no podía cambiar en
futuras versiones de Gforth, como así ha sido. Cuando descubrí que esa
era precisamente la causa del problema, sustituí la constante
`/colon-sys` por el siguiente cálculo, en un módulo de mi librería
Galope:
----
depth value /colon-sys ( -- n )
\ _n_ is the size of _colon-sys_ in cells.
:noname [ depth /colon-sys - 1- to /colon-sys ] ; drop
\ Calculate `/colon-sys`.
----
Parece que funciona bien.
De todas maneras he buscado en las fuentes de Gforth, por si acaso hay
algún método indocumentado de obtener el valor de _colon-sys_, pero no
lo he encontrado.
--
Marcos Cruz
http://programandala.net