Palabras para ampliar Abersoft Forth
Descripción del contenido de la página
Algunas palabras sencillas para añadir funcionalidades a Abersoft Forth, un fig-Forth para ZX Spectrum.
Nota: En 2015 escribí la librería Afera, que entre sus muchos módulos incluye casi todo el código que se muestra en esta página y en muchos casos mejorado.
Una de las cualidades de Forth es que podemos ampliarlo sin límites o reescribirlo como queramos, incluso al nivel del compilador.
Entre mis viejos papeles he descubierto algunos listados de Abersoft Forth, el Forth que más usé con la ZX Spectrum, con palabras que le añaden alguna funcionalidad. Las copio a continuación. Algunas de ellas tienen la fecha en que las escribí, que también incluyo por curiosidad; otras no las escribí yo sino que las copié de otras fuentes (que cito) para tenerlas a mano e incorporarlas a mis programas.
Comentarios
Esta es mi definición de la palabra \
, para crear comentarios hasta el final de la línea:
: \
IN @ DUP C/L >
IF B/BUF SWAP MOD
ELSE C/L SWAP -
THEN IN +!
; IMMEDIATE
Pila de datos
Dos maneras ligeramente diferentes que se me ocurrieron para calcular la profundidad de la pila:
: DEPTH ( -- u )
( 1985-12-10)
SP@ S0 @ - 2 / ABS
;
: DEPTH ( -- u )
( 1985-12-10)
SP@ S0 @ - -2 /
;
Y dos palabras clásicas para manipular la pila de datos, PICK
y ROLL
(aunque la definición de ROLL
se me resistió y quedó incompleta):
: PICK ( u -- x )
( 1987-01-09)
2 * 2 + SP@ + @
;
: ROLL ( u -- )
( 1987-01-09)
( boceto; no funciona)
2 * 4 + DUP SP@ + DUP @ ROT 1 - DUP 2 + ROT 2 - CMOVE DROP
;
Números seudo-aleatorios
Estas palabras proceden de Bertie, el juego de demostración que viene con Abersoft Forth. Sólo he cambiado las direcciones de las variables del sistema por constantes, para aumentar la legibilidad del código.
RND
devuelve un número seudoaleatorio positivo menor que el que se le entrega como parámetro:
23670 CONSTANT SEED ( ZX Spectrum system variable)
: RND ( u1 -- u2 )
SEED @ 75 U* 75 0 D+
OVER OVER U< - - 1 - DUP SEED !
U* SWAP DROP
;
RANDOM
modifica la semilla de cálculo de RND
con un valor imprevisible:
23672 CONSTANT FRAMES ( ZX Spectrum system variable)
: RANDOM ( -- )
FRAMES @ SEED !
;
Impresión de código fuente
Dos palabras que escribí para listar más cómodamente las pantallas de código en la impresora. Están inspiradas por dos palabras homónimas de MMS- Forth, cuya mención encontré en la página 60 del libro Introduction to Forth de Ken Knecht:
: PLIST ( u -- )
1 LINK LIST 0 LINK
;
: PLISTS ( u1 u2 -- )
1+ SWAP DO I PLIST LOOP
;
Operadores aritméticos
Operadores para comparar números:
: >= ( n1 n2 -- f )
OVER OVER > ROT ROT SWAP = OR
;
: <= ( n1 n2 -- f )
OVER OVER < ROT ROT SWAP = OR
;
: <> ( n1 n2 -- f )
= NOT
;
Una palabra para obtener el signo de un número de forma análoga a como se hace en Sinclair BASIC:
: SGN ( n1 -- n2 )
1 +-
;
Operadores lógicos
Tres definiciones triviales para enriquecer el repertorio:
: NOR ( n1 n2 -- n3 )
OR NOT
;
: NAND ( n1 n2 -- n3 )
AND NOT
;
: XNOR ( n1 n2 -- n3 )
XOR NOT
;
Gráficos
Gráficos definidos por el usuario
Una palabra para facilitar la creación de gráficos definidos por el usuario (UDG). Procede del manual de Abersoft Forth (página 11).
: DEFINE ( u0 u1 u2 u3 u4 u5 u6 u7 u8 -- )
( u0 ... u7 = graphic definition bytes )
( u8 = graphic number, from 0 to 21 )
8 * UDG + DUP 8 + SWAP
DO I C! LOOP
;
Líneas
Abersoft Forth incluye la palabra DRAW
para dibujar líneas, pero lo hace a unas coordenadas de pantalla absolutas. En Sinclair BASIC el comando DRAW
usa coordenadas relativas a la posición del último punto dibujado.
DRAWL
viene como ejemplo en el manual de Abersoft Forth (página 9); dibuja una línea entre dos coordenadas absolutas:
: DRAWL ( x2 y2 x1 y1 -- )
PLOT DRAW
;
Para dibujar líneas con coordenadas relativas, y así hacer más fácil la adaptación de algunos programas escritos en Sinclair BASIC, escribí la palabra NDRAW
. El nombre se refiere a «normal draw», para acordarme de que se trataba de cómo lo hacía «normalmente» en BASIC, aunque RDRAW
sería un nombre mejor. NDRAW
Lee de la variable del sistema correspondiente las coordenadas del último punto dibujado y con ellas calcula las del punto final de la línea:
23677 CONSTANT COORDS ( ZX Spectrum system variable)
COORDS CONSTANT X-COORD
COORDS 1+ CONSTANT Y-COORD
: NDRAW ( n1 n2 -- )
Y-COORD C@ + SWAP X-COORD C@ +
SWAP DRAW
;
Y lógicamente esta es la versión de DRAWL
para dibujar la línea de forma relativa:
: NDRAWL ( n1 n2 x y -- )
PLOT NDRAW
;
Gráficos al estilo de Logo
En su día sentí cierta curiosidad por el lenguaje de programación Logo, pero no llegó a cuajar (tras haber aprendido Forth cualquier otro lenguaje me parecía, y me sigue pareciendo, demasiado limitado). Uno de los pocos frutos de aquel interés fue escribir algunas palabras en Forth para la ZX Spectrum parecidas a comandos gráficos de Logo. En ellas está incluida una nueva versión de la palabra que dibuja líneas con coordenadas relativas, ya explicada anteriormente.
( Logo-Forth )
( Copyright [C] 1985, 2009 Marcos Cruz, http://programandala.net )
( Abersoft Forth, Sinclair ZX Spectrum )
( 1985-05-20 First version )
( 2009-05-27 Improved with the following words: X! Y! COORDS X-COORD Y-COORD RELATIVE )
: TASK ;
23677 CONSTANT COORDS ( ZX Spectrum system variable)
COORDS CONSTANT X-COORD
COORDS 1+ CONSTANT Y-COORD
: X@ ( -- b ) X-COORD C@ ;
: Y@ ( -- b ) Y-COORD C@ ;
: X! ( b -- ) X-COORD C! ;
: Y! ( b -- ) Y-COORD C! ;
: RELATIVE ( x1 y1 -- x2 y2 ) Y@ + SWAP X@ + SWAP ;
: RDRAW ( x y -- ) RELATIVE DRAW ;
: SETXY ( x y -- ) RELATIVE PLOT ;
: RIGHT ( u -- ) 0 RDRAW ;
: LEFT ( u -- ) -1 * 0 RDRAW ;
: UP ( u -- ) 0 SWAP RDRAW ;
: DOWN ( u -- ) -1 * 0 SWAP RDRAW ;
: PAT ( x y -- ) Y! X! ;
: RPAT ( x y -- ) Y@ + Y! X@ + X! ;
: RPLOT ( u -- ) 0 SETXY ;
: LPLOT ( u -- ) -1 * 0 SETXY ;
: UPLOT ( u -- ) 0 SWAP SETXY ;
: DPLOT ( u -- ) -1 * 0 SWAP SETXY ;
Entrada de datos
Dos palabras para pedir al usuario la entrada de un número, de doble o simple precisión. Están inspiradas por la palabra #IN
de MMS-Forth, cuya mención encontré en la página 55 del libro Introduction to Forth de Ken Knecht:
: D#IN ( -- d )
PAD 1+ 64 EXPECT
.0 PAD (NUMBER) DROP
;
: #IN ( -- n )
D#IN DROP
;
Otras
Tres palabras sencillas que existen en algunos otros sistemas Forth:
: MEM ( -- )
FREE . ." BYTES FREE"
;
: HOME ( -- )
0 DUP AT
;
: C? ( a -- )
C@ .
;
Una curiosidad trivial; una palabra que hace la misma función que ."
pero que empieza a imprimir en una nueva línea:
: " ( -- )
( 1986-06-12)
CR [COMPILE] ."
; IMMEDIATE
Y por último un añadido más moderno (2015-03-11), la definición de la palabra estándar CHAR
:
: CHAR ( -- c )
BL WORD HERE 1+ C@
;