Imagen

IS-FORTH

Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Diferencias entre algunas palabras aparentemente iguales del Ace Forth/Is-Forth: (II)

INTERPRET No existe en el Ace Forth, pero es lo más parecido a LINE del JA en versión ISF. (LINE no existe en ISF)
LIST En ISF lista el bloque cuyo número toma de la pila. En Ace descompila y lista el fuente de la palabra con el nombre suministrado.
NUMBER En ISF espera en la pila la dirección de una cadena de texto contada y devuelve su equivalente numérico entero de doble precisión (o sencilla si no se pone el punto). En el Ace acepta un número textual en el búfer de entrada y lo convierte en un entero sencillo o en un coma flotante según el caso, dejando una clave encima indicando de cual se trata.
OUT No tienen nada que ver en una y otra máquina. En el ISF es un contador asociado a EMIT y en el Ace escribe valores en los puertos del JA. En el ISF la palabra P! es la equivalente al OUT del JA y P@ es la equivalente del ISF al IN del JA (escriben y leen de puertos respectivamente)
PAD Son muy parecidas. La principal diferencia es que en el JA su posición es fija mientras en ISF va cambiando a medida que el diccionario aumenta. De hecho, el PAD del ISF empieza 32 bytes después del final del diccionario.
RECURSE En el JA no existe, pues no es necesaria. En el ISF permite hacer Recursión. En vez de llamar a la palabra que estás definiendo (que daría error al interpretarla) usas RECURSE y solucionado.
Ej:
En el JA:

Código: Seleccionar todo

: TEST 2 . TEST ;
En el ISF:

Código: Seleccionar todo

: TEST 2 . RECURSE ;
WORD Son muy parecidas. Hay diferencias a nivel interno que vale la pena saber. En el JA WORD pone la cadena contada que genera en el PAD mientras en el ISF la coloca justo después del diccionario.
Por lo dicho sobre el PAD, si el texto que toma WORD en el ISF es más largo de 32 caracteres, empezará a sobreescribir el PAD
Una diferencia importante es que el JA antes que WORD escriba en el PAD lo rellena con espacios en blanco. Mientras WORD en el ISF no lo hace. Puede haber "basura" después del texto ingresado.
retrovader
Mensajes: 85
Registrado: 01 May 2020 08:36

Re: IS-FORTH

Mensaje por retrovader »

Tu te acabas de encontrar un manual de Forth y nos esta vacilando, verdad??? :)

Es broma... Es muy interesante... me estas picando la curiosidad por este lenguaje...
Se nota que lo conoces en profundidad. -thumbup
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Elurdio escribió:···
Lo que me interesaría es una manera de, desde el IS-FORTH, poder acceder a un fichero en el disco duro que no sean los BLOCKS allí guardados. Algo equivalente al "Load/Save Memory Blokc" del EightyOne o mejor aún, poder leer/escribir ficheros desde IS-FORTH (aunque me conformo con lo primero)
···
Hoy me he entretenido en repasarme el manual del IS-FORTH (*), concretamente los capítulos "Chapter 9-Using Enterprise's Special Features" y "Entreprise-Specific Forth Words" y contienen información suficiente para poder abrir/cerrar/leer/escribir ficheros.

He hecho algunas pruebas sencillas y parece que no habrá problema para hacer palabras que me permitan leer/escirbir ficheros desde IS-FORTH.

Concretamente he usados estas palabras:

OPENOUT Abre el fichero para escritura. Espera en la pila la dirección de la cadena de texto contada que contiene el nombre del fichero a abrir y el número del canal del disco (en mi caso y por defecto es 106). Opera con el directorio de trabajo que tengas configurado.
PUT Escribe un byte en el fichero. Espera en la pila el byte a escribir y el número de canal
CLOSE Cierra el canal cuyo número toma de la pila.
OPENIN Abre el fichero para lectura. Espera en la pila la dirección de la cadena de texto contada que contiene el nombre del fichero a abrir y el número del canal del disco (en mi caso y por defecto es 106). Opera con el directorio de trabajo que tengas configurado.
GET Lee un byte del fichero. Espera en la pila el número de canal.

Y ésta que no la he probado aún pero puede ser útil:

#STATUS Espera el número de canal en la pila y devuelve 0 si hay un carácter listo para leer, 255 para "End Of File" o uno en cualquier otro caso.

He hecho esta sencilla prueba:
ep2.png
ep2.png (8.53 KiB) Visto 1517 veces
Y se ha impreso en pantalla: CDEFok como cabía esperar.

Además, he mirado el directorio de trabajo y allí está el fichero con el contenido correspondiente.

Otra palabra interesante es:

CAPTURE que espera en la pila dos canales haciendo que las siguientes lecturas del primer canal pasen a provenir del segundo (el de más arriba en la pila).

(*) Estaría bien disponer de una versión "searchable"
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Ahora que sé como trabajar directamente con ficheros en IS-FORTH pongo como pasar código máquina generado en el TASM a una palabra tipo primitiva.

Este método es mucho mejor que los anteriores, pues pasa directamente el código máquina desde el fichero .bin generado por TASM al PF de la palabra del IS-FORTH que lo ejecutará. No hay límite de tamaño, pues no pasa por ningún BLOCK, ni hay que convertir a texto los bytes, como en los anteriores.

Primero creamos la palabra >MC que nos carga el contenido del fichero .bin en el campo de parámetros de una palabra tipo CREATE. Esta palabra espera tres números en la pila, de último a primero:
  • Dirección del PF de la palabra definida con CREATE
  • Dirección de una cadena de texto contada con el nombre del fichero .bin.
  • Número de bytes del fichero .bin (exacto)
He incluido en el BLOCK la definición de >MC pero se puede definir aparte, pues es una palabra de uso general. La creación de la primitiva en código máquina son la tres últimas líneas.

Suponemos que vamos a llamar a nuestra primitiva en c.m. MIMC y que el fichero .bin se llama uloopmc.bin y tiene un tamaño de 66 bytes. Hacemos:
  • Definimos MIMC como tipo CREATE con un PF de 66 bytes.
  • Ejecutamos >MC con los tres parámetros que necesita (MIMC deja en la pila la dirección de su PF)
  • Modificamos el Code Field de MIMC para convertirla en una palabra Primitiva (hacemos que su Code Field apunte 4 bytes más allá de su CFA que es donde empieza su PF)
mimc2.png
mimc2.png (15.39 KiB) Visto 1499 veces
Ya tenemos la primitiva MIMC que ejecuta el código máquina que generamos con TASM

NOTA: Si se prefiere, se puede borrar >MC tras crear la primitiva. Para ello basta con definir MIMC antes que >MC:
mimc3.png
mimc3.png (14.16 KiB) Visto 1483 veces
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Diferencias entre algunas palabras aparentemente iguales del Ace Forth/Is-Forth: (III)

' Se pronuncia "tick". En ISF devuelve el CFA de la palabra que toma del búfer de entrada. Si no existe da error. Si no hay ninguna palabra, devuelve a la pila el número 52438 (hex CCD6). Es parecida al FIND del JA. En el JA no existe pero se puede definir según el Forth-79: Devuelve el PFA (Parameter Field Address) de la palabra que toma del búfer de entrada. Si no existe o no hay nada da error. En modo compilación se comporta diferente: Compila el PF de la siguiente palabra en el diccionario como un literal.
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Elurdio escribió:En cuanto a escribir los BLOCKS en un editor externo, hago esto:
  • Han de ser ficheros de 1024 bytes de tamaño o mayores (rellenando con espacios vale).
  • Se han de llamar n.4TH dónde n es el número de BLOCK
  • Se han de colocar en el Working Directory del IS-FORTH
····
Como método alternativo, he probado de crear el fuente en un fichero de texto y cargarlo en el IS-FORTH mediante la palabra CAPTURE.

Funcionar, funciona. Pero hay una pega. Cuando lo entras así, es como si lo teclearas en el búfer de entrada directamente. Y en el ISF en el búfer de entrada no se pueden entrar palabras a medias. O sea, en el JA puedo entrar la definición:

: TEST DUP + ; <ENTER>

o bien puedo hacer:

: TEST <ENTER>
DUP + ; <ENTER>

y obtengo lo mismo. Pero en el ISF NO se puede hacer. Si lo hago "partido" como en el ejemplo aparentemente todo ha ido bien pero la palabra no funciona como se espera. Si la palabra contiene estructuras de control (IF/DO/BEGIN) y se parte una de ellas da error directamente.

El problema es que no se puede ejecutar un ENTER en el búfer de entrada hasta que no está completa la definición. Por lo que no puede haber ningún código 13 (el ENTER) en el texto fuente dentro de una definición. Y sucede continuamente, pues en el texto fuente cada vez que salto línea me pone un código de salto de línea y uno retorno de carro (13).

Otra limitación, al menos tal como lo tengo yo (puede que se pueda configurar de alguna manera que aún desconozco), es que ninguna línea de código fuente debe superar los 80 caracteres.

Si el fuente solo fuera una lista de números, por ejemplo, que necesitan entrarse en la pila, no hay problema con los CR.

La "solución" que he encontrado es un poco "basta". Lo que hago es escribir el fuente normalmente y dónde ha de ir un <ENTER> escribo ENTER. Por ejemplo:

: TEST
DUP +
; ENTER

: TEST2
SWAP -
; ENTER
·
·
etc.

Además, me aseguro que ninguna línea llega a 80 caracteres.

Al final del texto fuente hay que colocar esta línea de código:

105 105 CATPURE ENTER

Luego, una vez tengo todo el fuente, lo abro con el HEXEDIT (un editor hexadecimal) y hago un Reemplazar todos los "0D" (código 13) con "20" (espacio). A continuación hago Reemplazar todos los ENTER (en hex: 454E544552) por 0D y ya tengo el fichero listo, con solo Retorno de Carros (13) en dónde tienen que estar (dónde escribí ENTER).

Para cargarlo en el IS-FORTH escribo esto en un BLOCK y lo cargo con LOAD:

Código: Seleccionar todo

 " fIlename" 106 OPENIN
 105  106  CAPTURE
dónde <filename> es el nombre del fichero completo (eg." MISDATOS.TXT") Ojo: Ha de haber un espacio (y solo uno) entre las comillas izquierdas y el nombre del fichero.

justo después de pulsar el LOAD empezará la carga/interpretación desde el fichero.

Al terminar hacer:

106 CLOSE

Un caso real:

Este es el fichero fuente para hacer los benchmarks de Forth. Originalmente cada definición era una sola línea. Aquí, cuando ha sido necesario, se han partido algunas para que no pasen de 80 caracteres por línea. Además he añadido la palabra ENTER para terminar cada definición (el ENTER se convertirá en un solo carácter)

Código: Seleccionar todo

: TIMEX_INI 255 TIMER SET ; ENTER
: TIMEX 255 TIMER ASK - ; ENTER
: INCREM TIMEX_INI 10000 0 DO 10 0 DO 9 1+ LOOP SP! LOOP TIMEX ; ENTER 
: TEST> TIMEX_INI 10000 0 DO 10 0 DO  9 9 > LOOP SP! LOOP TIMEX ; ENTER 
: TEST< TIMEX_INI 10000 0 DO 10 0 DO  9 9 < LOOP SP! LOOP TIMEX ; ENTER 
: ARITHMETIC TIMEX_INI 10000 0 DO  9 2 / 3 * 4 + 5 - SP! LOOP TIMEX ; ENTER 
: WHILE-LOOP TIMEX_INI 10000 0 DO 
 1 BEGIN 1+ DUP 11 < WHILE REPEAT SP! LOOP
 TIMEX; ENTER 
: UNTIL-LOOP TIMEX_INI 10000 0 DO 20 BEGIN 1- DUP 11 < UNTIL SP! LOOP TIMEX ; ENTER 
: MAGNIFIER TIMEX_INI
 20 0 DO 10000 0 DO SP! LOOP
 LOOP TIMEX 2 /   ; ENTER 
: DO-LOOP TIMEX_INI 10000 0 DO 10 0 DO LOOP SP! LOOP TIMEX ; ENTER 
: LITERAL TIMEX_INI 10000 0 DO 10 0 DO 9 LOOP SP! LOOP TIMEX ; ENTER 
5  VARIABLE V ENTER 
: VARI TIMEX_INI 10000 0 DO 10 0 DO V LOOP SP! LOOP TIMEX ; ENTER 
: LITERAL-STORE TIMEX_INI 10000 0 DO 10 0 DO 9 V ! LOOP SP! LOOP TIMEX  ; ENTER 
: VARI-FETCH TIMEX_INI 10000 0 DO 10 0 DO V @ LOOP SP! LOOP TIMEX ; ENTER 
9 CONSTANT K ENTER 
: CONST TIMEX_INI 10000 0 DO 10 0 DO K LOOP SP! LOOP TIMEX ; ENTER 
: DUPLIX TIMEX_INI 10000 0 DO 10 0 DO 9 DUP LOOP SP! LOOP TIMEX ; ENTER 
: INCREM TIMEX_INI 10000 0 DO 10 0 DO 9 1+ LOOP SP! LOOP TIMEX ; ENTER 
: TEST> TIMEX_INI 10000 0 DO 10 0 DO  9 9 > LOOP SP! LOOP TIMEX ; ENTER 
: TEST< TIMEX_INI 10000 0 DO 10 0 DO  9 9 < LOOP SP! LOOP  TIMEX ; ENTER 
: ARITHMETIC TIMEX_INI 10000 0 DO  9 2 / 3 * 4 + 5 - SP! LOOP TIMEX ; ENTER 
: WHILE-LOOP TIMEX_INI 10000 0 DO 1 BEGIN 1+ DUP 11 < WHILE REPEAT SP! LOOP 
 TIMEX ; ENTER 
: UNTIL-LOOP TIMEX_INI 10000 0 DO 20 BEGIN 1- DUP 11 < UNTIL SP! LOOP TIMEX ; ENTER 
: TEN ; ENTER 
: NINE TEN ; ENTER 
: EIGHT NINE ; ENTER 
: SEVEN EIGHT ; ENTER 
: SIX SEVEN ; ENTER 
: FIVE SIX ; ENTER 
: FOUR FIVE ; ENTER 
: THREE FOUR ; ENTER 
: TWO THREE ; ENTER 
: ONE TWO ; ENTER 
: DICTIO TIMEX_INI 10000 1 DO ONE SP! LOOP TIMEX ; ENTER 

105 105 CAPTURE  ENTER 
Una vez transformado con el HEXEDIT queda así:
(Cuando se ven varias líneas dentro de una misma definición, si se mira con HEXEDIT se verá que están hechas solo con "line Feed" (ASCII 10). No hay ni un solo ASCII 13 excepto donde había antes un ENTER)

Código: Seleccionar todo

: TIMEX_INI 255 TIMER SET ; 

: TIMEX 255 TIMER ASK - ; 

: INCREM TIMEX_INI 10000 0 DO 10 0 DO 9 1+ LOOP SP! LOOP TIMEX ; 
  
: TEST> TIMEX_INI 10000 0 DO 10 0 DO  9 9 > LOOP SP! LOOP TIMEX ; 
  
: TEST< TIMEX_INI 10000 0 DO 10 0 DO  9 9 < LOOP SP! LOOP TIMEX ; 
  
: ARITHMETIC TIMEX_INI 10000 0 DO  9 2 / 3 * 4 + 5 - SP! LOOP TIMEX ; 
  
: WHILE-LOOP TIMEX_INI 10000 0 DO  
 1 BEGIN 1+ DUP 11 < WHILE REPEAT SP! LOOP 
 TIMEX; 
  
: UNTIL-LOOP TIMEX_INI 10000 0 DO 20 BEGIN 1- DUP 11 < UNTIL SP! LOOP TIMEX ; 
  
: MAGNIFIER TIMEX_INI 
 20 0 DO 10000 0 DO SP! LOOP 
 LOOP TIMEX 2 /   ; 
  
: DO-LOOP TIMEX_INI 10000 0 DO 10 0 DO LOOP SP! LOOP TIMEX ; 
  
: LITERAL TIMEX_INI 10000 0 DO 10 0 DO 9 LOOP SP! LOOP TIMEX ; 
  
5  VARIABLE V 
  
: VARI TIMEX_INI 10000 0 DO 10 0 DO V LOOP SP! LOOP TIMEX ; 
  
: LITERAL-STORE TIMEX_INI 10000 0 DO 10 0 DO 9 V ! LOOP SP! LOOP TIMEX  ; 
  
: VARI-FETCH TIMEX_INI 10000 0 DO 10 0 DO V @ LOOP SP! LOOP TIMEX ; 
  
9 CONSTANT K 
  
: CONST TIMEX_INI 10000 0 DO 10 0 DO K LOOP SP! LOOP TIMEX ; 
  
: DUPLIX TIMEX_INI 10000 0 DO 10 0 DO 9 DUP LOOP SP! LOOP TIMEX ; 
  
: INCREM TIMEX_INI 10000 0 DO 10 0 DO 9 1+ LOOP SP! LOOP TIMEX ; 
  
: TEST> TIMEX_INI 10000 0 DO 10 0 DO  9 9 > LOOP SP! LOOP TIMEX ; 
  
: TEST< TIMEX_INI 10000 0 DO 10 0 DO  9 9 < LOOP SP! LOOP  TIMEX ; 
  
: ARITHMETIC TIMEX_INI 10000 0 DO  9 2 / 3 * 4 + 5 - SP! LOOP TIMEX ; 
  
: WHILE-LOOP TIMEX_INI 10000 0 DO 1 BEGIN 1+ DUP 11 < WHILE REPEAT SP! LOOP  
 TIMEX ; 
  
: UNTIL-LOOP TIMEX_INI 10000 0 DO 20 BEGIN 1- DUP 11 < UNTIL SP! LOOP TIMEX ; 
  
: TEN ; 
  
: NINE TEN ; 
  
: EIGHT NINE ; 
  
: SEVEN EIGHT ; 
  
: SIX SEVEN ; 
  
: FIVE SIX ; 
  
: FOUR FIVE ; 
  
: THREE FOUR ; 
  
: TWO THREE ; 
  
: ONE TWO ; 
  
: DICTIO TIMEX_INI 10000 1 DO ONE SP! LOOP TIMEX ; 
  
105 105 CAPTURE  
  
Afortunadamente el HEXEDIT guarda automáticamente una copia (.BAK) del fichero tal como era antes de la conversión. Así podemos modificarlo si hiciera falta y volverlo a convertir.

La ventaja de este método es que el fichero fuente puede ser tan grande como se quiera.
La pega es que es un auténtico ENGORRO a falta de que encontrar una manera de salvar el problema con los CR en medio de las definiciones que no implique el tratamiento con HEXEDIT.
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Definición de ULIST
"User's List"
Igual que VLIST pero solo muestra las palabras definidas por el Usuario.
ep3.png
ep3.png (7.57 KiB) Visto 1411 veces
Editado
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Estructura de una Palabra

Consta de dos partes: El Header (Cabecera) y el Parameter Field (Campo de Parámetros)

En IS-FORTH la estructura de la cabecera de una palabra es más sencilla que en el Jupiter Ace:
isfword2.png
isfword2.png (30.33 KiB) Visto 1427 veces
Cabecera (Header)
El primer byte contiene el número de caracteres del Nombre de la palabras. En el ejemplo n=4 pues TEST tiene cuatro letras. Si la palabra es INMEDIATA entonces se le suma 128 a n. Así, si TEST fuera una palabra inmediata entonces n=4+128=132. Por lo que el tamaño máximo de un nombre son 127 letras. 128 equivale a poner a 1 el bit #7 (el de más a la izquierda) del byte n.

A continuación vienen los caracteres del Nombre: TEST en el ejemplo

Luego viene el Link Field (LF) (2 bytes) que es una dirección que apunta al inicio de la palabra anterior a ésta en el diccionario. O sea, el LF apunta al byte de tamaño del Nombre de la palabra anterior a ésta. La dirección de memoria en la que está el LF se llama Link Field Address (LFA).

Le sigue el Code Field (CF) (2 bytes) que es la dirección del código máquina que se ha de ejecutar cuando se ejectute esta palabra. La diercción de memoria en la que está el CF se llama Code Field Address (CFA).

Parameter Field
Empieza justo después de la cabecera (Header) y su estructura depende del tipo de palabra. Es el cuerpo de la palabra.
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Ahora puedo explicar el funcionamiento detallado de ULIST

DECIMAL es para asegurarnos que estamos en base 10.

CURRENT @ @
La variable del sistema CURRENT contiene la dirección de un campo del vocabulario actual (FORTH por defecto) cuyo contenido apunta al inicio de la última palabra (la más reciente) del susodicho vocabulario.
NOTA: ULIST se ha definido pensando que estamos en el vocabulario FORTH.

Ahora tenemos en la pila la dirección de inicio de la última palabra. Iniciamos un bucle BEGIN/WHILE/REPEAT que comprueba antes de cada iteración que la palabra empieza en una dirección mayor que 10329 (hex 2859) que es la dirección de inicio de la palabra ASSEMBLER (la última palabra del diccionario vacío, sin ninguna definición de usuario aún).

DUP C@ 127 AND
Pone en la pila el byte de tamaño del nombre y nos quedamos solo los bits #6 al #0. Descartamos el bit #7 que determina si la palabra es inmediata o no. Así tenemos en la pila la dirección de inicio y el tamaño del nombre.

OVER 1+ OVER TYPE SPACE
Copiamos la dirección más uno, para apuntar al inicio del nombre y colocamos arriba una copia del tamaño de la palabra, tal como espera TYPE para imprimir el nombre. Imprimimos un espacio se separación.

+ 1+ @
Tenemos en la pila la dirección del inicio de la palabra y el tamaño del nombre. Los sumamos y le añadimos uno para tener la dirección del LFA de la palabra. Con @ obtenemos el LF que nos apunta al inicio de la palabra anterior. Con este dato en la pila ya podemos repetir el bucle.

Al terminar eliminamos la dirección que nos queda en la pila con DROP
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

ULIST es una de las primeras palabras FORTH que hice para el Jupiter Ace y que publiqué en el post de utilidades del mismo. He pensado en adaptar otras e irlas publicando aquí.

Pero sucede que la mayor parte de mi labor se ha enfocado a utilidades para el Ace Forth, sobre todo atendiendo a su "particularidades". En concreto, los cutaro "proyectos" principales que llevé a cabo:
  1. Cargador de Código Fuente
  2. Extractor de Código Fuente
  3. Extractor de Palabras
  4. Extractor de Diccionario
Son en el entorno del IS-FORTH o bien de poca utilidad, o bien de utilidad nula. El (1) y el (3) caerían en la primera categoría y el (2) y el (4) en la última respectivamente.

El (1) es de poca utilidad, pues ISF trabaja "per se" con código fuente y lo carga sin problemas. En el caso de querer hacerlo de modo "externo" ya he explicado un par de maneras posibles. Ambas no tienen nada que ver con mi aportación (1).

El (2) NO tiene ningún sentido en el ISF

El (3) Podría tener una utilidad "marginal" para conocer que palabras necesita una concreta para funcionar. Pero dado que el ISF no tiene la palabra COMPILER sería imposible analizar las palabras compilantes de usuario, lo que limita aún más su ya de por sí reducida utilidad.

El (4), al que considero mi obra principal, aquí es de NULA utilidad.

Otras cosas que hice más concretas, tales como los bucles ULOOP/+ULOOP/NEXT resulta que en el ISF ya trabajan así (los bucles son unsigned) y en cuanto la palabra NEXT que hice: En el ISF la palabra LEAVE ya se comporta como mi combinación LEAVE NEXT del JA.

Así pues, poco puedo adaptar de lo por mí hecho para el JA.
Avatar de Usuario
gflorez
Mensajes: 1701
Registrado: 12 Sep 2014 19:58

Re: IS-FORTH

Mensaje por gflorez »

Que guarrada.... resulta que no hace falta que adaptes ISF a tu gusto porque ya hace casi todo lo que quieres.....

Me alegro muchísimo, y espero que sigas "sacándole defectos".
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

gflorez escribió:Que guarrada.... resulta que no hace falta que adaptes ISF a tu gusto porque ya hace casi todo lo que quieres.....
:lol: :lol: :lol:
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Elurdio escribió:Definición de ULIST
"User's List"
Igual que VLIST pero solo muestra las palabras definidas por el Usuario.
Haciendo pruebas de carga de ficheros que generaban palabras mal cargadas en el diccionario he visto que en algunos casos ULIST falla mientras VLIST no. Comprobando la cabecera de la que provoca el fallo en ULIST, cuyo nombre tiene 4 letras, veo que tiene un byte de tamaño del nombre de hex 44=68 decimal. Haciendo pruebas he concluido que ISF admite nombres de como máximo 31 caracteres. Igual lo pone en el manual, pero no lo he visto. Por eso VLIST funcionaba con esa palabra, pues debe hacer un 31 AND en lugar del 127 AND que hace ULIST.

Esta es la versión correcta de ULIST
ep4.png
ep4.png (7.57 KiB) Visto 1366 veces
NOTA: Es un tontería, pero me ha hecho perder un buen rato...

La palabra para indicar que hay que seguir cargando el siguiente BLOCK es --> y no -> como dice el manual.
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Elurdio escribió:·····
Otras cosas que hice más concretas, tales como los bucles ULOOP/+ULOOP/NEXT resulta que en el ISF ya trabajan así (los bucles son unsigned) y en cuanto la palabra NEXT que hice: En el ISF la palabra LEAVE ya se comporta como mi combinación LEAVE NEXT del JA.
···
Examinando lo hecho para el Jupiter Ace con más detenimiento, veo que NEXT podría ser también útil en el ISF.

NEXT pasa a la siguiente iteración del bucle directamente, sin que se ejecute nada de lo que hay entre medio y pueden haber varios NEXT dentro de un mismo bucle. Es la combinación LEAVE NEXT del JA la que equivale al LEAVE del ISF. Pero en ISF, NEXT tiene su propio nicho como tal.

La cosa va a ser entretenida, pues tengo que estudiar como va el tema del funcionamiento interno del DO/LOOP/+LOOP/LEAVE del ISF para que ULOOP/+ULOOP (así lo llamaré) sea compatible con DO y LEAVE.

Además está todo el tema "opcional" de la versión en código máquina de ULOOP/+ULOOP, y digo "opcional" porque me hago unos líos con el c.m. en el ISF por su enfoque tan diferente de las pilas con respecto al JA que me lo pensaré antes de meterme con ello.

En fin, que ya tengo algo que hacer en ISF para entretenerme un poco, que es de lo que se trata.
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Elurdio escribió:···
Examinando lo hecho para el Jupiter Ace con más detenimiento, veo que NEXT podría ser también útil en el ISF.
···
He estado estudiando como trabaja la parte compilante de los LEAVE en el ISF.

Hay una posición de memoria (hex 022C de 2 bytes) reservada para esta labor. La llamaré (L)

Cada vez que se abre un DO se ponen en la pila tres números: el valor de HERE, la posición del último LEAVE del Bucle anidado anterior (si estamos en el más externo, valdrá 0) y el código 2.

Cada vez que encuentra un LEAVE mira el valor de (L). Si vale 0 apunta la dirección de LEAVE en (L). Si es distinto de 0, quiere decir que tiene el valor de un LEAVE anterior guardado. Entonces lo que se hace es poner en el Operand Field del LEAVE que está en la dirección guardada en (L) el valor de la dirección de este nuevo LEAVE. Luego apuntamos en (L) la dirección de este nuevo LEAVE. Lo que estamos haciendo es que cada LEAVE apunte al siguiente LEAVE y así sucesivamente. El último LEAVE apuntará al final del BUCLE (al LOOP que le corresponde). Así cuando se ejecuta un LEAVE, éste saltará al siguiente, y éste al siguiente, y así hasta que el último salta al LOOP correspondiente.

Si se abre un nuevo DO mientras no se ha cerrado el anterior (un bucle anidado) entonces se ponen en la pila los tres números comentados antes. En este caso el segundo número tendrá la dirección del último LEAVE del bucle anidado inmediatamente exterior a éste. Ahora que ya lo tenemos "a salvo" podemos poner (L) a cero y seguir como en el caso anterior.

Y así sucesivamente hasta que encontramos el primer LOOP. Este cerrará el LEAVE apuntado por (L) y entonces saca de la pila el valor que se salvó del último LEAVE del bucle anterior y lo coloca en (L) y continuamos procesando...

etc.

Visto lo cual, y otras cosas que no comento aquí, de momento dejo aparcado esto, pues es mucho lío para tan poco aporte de NEXT al ISF.
Elurdio
Mensajes: 1022
Registrado: 07 Dic 2021 21:33
Ubicación: Barcelona

Re: IS-FORTH

Mensaje por Elurdio »

Sigo tan "veleta" como siempre. Dije que dejaba el tema del NEXT aparcado pero en realidad sigo dándole vueltas.

Me he aprendido un MANTRA:

Código: Seleccionar todo

: MANTRA
  BEGIN
    CR ." Esto es IS-FORTH"
    CR ." NO estamos en el JUPITER ACE" 
    0
  UNTIL
;
Y más en este caso, pues con el tema de las palabras compilantes las diferencias se acentúan como ya comenté en su día.

En fin, que sigo con el tema. A ver que saco en claro. Ya tengo algún enfoque de como hacerlo.
Responder

Volver a “Software Enterprise”