NOTAS DE IMPLEMENTACIÓN

El intérprete TINY BASIC fue diseñado por Dennis Allison como un
analizador sintáctico de descenso recursivo. Parte de la elegante
simplicidad de este diseño se perdió al añadirle sintaxis más compleja,
pero la forma básica se conserva. El intérprete de lenguaje (IL) es
especialmente adecuado para el análisis sintáctico de descenso recursivo
de TINY BASIC debido a la naturaleza recursiva general de sus
procedimientos y a la simplicidad de los tokens TINY BASIC. El lenguaje
IL está optimizado para la interpretación de TINY. La experiencia ha
demostrado que la dificultad de añadir nuevas funciones al lenguaje es
desproporcionada con respecto a la naturaleza de estas. Normalmente es
necesario añadir subrutinas de lenguaje máquina adicionales para
soportar las nuevas funciones. A menudo, la dificultad supera las
ventajas.

Consideremos, por ejemplo, la aritmética de punto flotante. Esta es una
adición solicitada con frecuencia. Sin embargo, para implementar el
punto flotante, se deben superar los siguientes problemas:

1. Tamaño de la variable. Si bien 16 bits no permiten números muy
grandes, son adecuados para enteros pequeños, como los necesarios para
juegos y aplicaciones de control industrial, los dos entornos para los
que TINY es más adecuado. Sin embargo, los números de punto flotante
significativos no caben en menos de 20 bits, y 32 bits es un límite
inferior mucho más razonable. 26 variables de cuatro bytes cada una
equivalen a 104 bytes, un tamaño no demasiado grande para aprovechar el
direccionamiento de la página 00. Sin rehacer todo el intérprete de ML,
sería necesario colocar dos bytes donde se encuentran las variables y
los otros dos en el espacio entre 00C8 y 00FB. La pila de expresiones
puede resultar demasiado pequeña para expresiones muy complejas de
variables de punto flotante de longitud doble. Esto tendería a limitar
el tamaño permitido de las líneas de entrada, que comparten el mismo
espacio de trabajo con la pila de expresiones.

2. Rutinas de manejo de números. No solo sería necesario reescribir las
rutinas aritméticas que controlan los códigos de operación AD, SU, MP y
DV, sino también modificar todos los demás códigos de operación que
trabajan con números en la pila. De lo contrario, el programa podría
tener dificultades para ejecutar un GOSUB en la línea 1.23E2. Quizás una
alternativa más sencilla sería conservar los códigos de operación
existentes y añadir las rutinas de punto flotante en los huecos del
conjunto de instrucciones de IL, incluyendo una para fijar un número de
punto flotante, así como la carga y el almacenamiento de variables, y
las conversiones de impresión y constantes. Es posible que no haya
suficientes códigos de operación sin usar para realizar esto sin
sacrificar las funciones existentes.

3. El código de evaluación de expresiones en el intérprete de IL
necesitaría una revisión para distinguir entre los requisitos de enteros
y de punto flotante, y para seleccionar los códigos de operación
adecuados.

En resumen, añadir operaciones de punto flotante a TINY es probablemente
factible, aunque no fácil.

Por otro lado, las operaciones con cadenas o matrices probablemente no
sean prácticas dentro de los límites del sistema actual. Si bien todas
las variables en TINY están predefinidas, las matrices y las cadenas de
longitud variable requerirían rutinas de asignación y desasignación de
memoria, punteros de dirección y tablas de dimensiones. Es concebible
que este espacio se tome de la memoria no utilizada del programa de
usuario, ya sea al final del programa (modificando el puntero en
0024-0025 hexadecimal) o debajo de la pila GOSUB (modificando el puntero
en 0022-0023 hexadecimal). En este último caso, el asignador de memoria
necesitaría mover la pila y también modificar el puntero de pila y el
contenido de 0026-0027 hexadecimal. Lograr que el sistema sea
invulnerable a errores de programación sería extremadamente difícil. Las
mejoras que podrían ser considerablemente más sencillas y que quizás
deberían considerarse primero son una función AND lógica (como
intrínseca) o la indirección de datos del tipo utilizado en NIBL.

Añadir una función intrínseca consiste principalmente en reconocer el
nombre de la función dentro del procedimiento de análisis FACTor, llamar
a EXPR para evaluar cada argumento y, a continuación, realizar la
evaluación. En el caso de una función AND lógica, se necesitaría una
rutina de lenguaje máquina para la evaluación. Esto puede implementarse
de dos maneras: el código de operación US existente puede incorporarse a
la evaluación, donde el intérprete de IL sabe dónde se encuentra la
subrutina; o bien, puede definirse un nuevo código de operación. La
siguiente secuencia ilustra la técnica anterior (suponiendo que el
código AND en lenguaje máquina se encuentra en la ubicación 0003):

       :F20    BC F30 "AND("   RECONOCE NOMBRE FUNCION
               LN 3            DIRECCION DE CARGA PARA USR
               JS EXPR         OBTIENE PRIMER ARGUMENTO
               JS ARG          OBTIENE SEGUNDO ARGUMENTO
               BC * ")"        DEBE SER PARENTESIS ABIERTA
               US              VE A HACERLO
               RT              RETORNA A TERM.
       :F30    ...             (DESCANSA DE LO HECHO)

El operador de indirección "@" podría manejarse de manera similar:

       :STMT   BC TLET "LET@" EVALUA ALMACEN INDIRECTO
               LN 280         SI, PONE DIRECCION POKE
               JS EXPR        OBTIENE DIRECCION
               BC * "="       SGTE DEBE SER IGUAL
               JS EXPR        OBTIENE VALOR
               BE *           ESO DEBE SER FIN DE LINEA
               US             ALMACENA EL BYTE BAJO
               SP             LIMPIA EL STACK
               NX             FINALIZA LA DECLARACION
       :TLET   BC GOTO "LET"  ...ETC.

La indirección en la búsqueda también es sencilla:

       :F40    BC F5 "@"      ES INDIRECTA?
               LN 276         SI, OBTIENE DIRECCION PEEK
               JS EXPR        OBTIENE DIRECCION DE BYTE
               DS             (DUMMY)
               US             VE A OBTENERLA
               RT
       :F5     BC             ...ETC.

Al agregar subrutinas de ML, puede ser útil saber dónde encontrar
algunos de los punteros internos utilizados por TINY. El programa IL
generalmente se ubica al final del código ML. Su dirección se almacena
en los dos bytes que preceden al código de Inicio en Frío. En otras
palabras, para encontrar la dirección base de IL (o cambiarla), siga el
JMP en hexadecimal 0100-0103 y busque dos bytes antes de su destino.
Esta es la única copia de la dirección, y los cambios aquí afectan a
todo el intérprete.

Las primeras instrucciones de la rutina de Inicio en Frío definen los
límites inferiores del espacio de usuario, por lo que, si es necesario
agregar código, se puede modificar para dejar espacio.

La tabla de direcciones de códigos de operación se ubica cerca del
inicio del intérprete ML (justo después de las rutinas PEEK y POKE). Las
primeras seis direcciones seleccionan las instrucciones de bifurcación.
La mayoría de los códigos de operación no utilizados saltan a la misma
dirección. Cada rutina de servicio de código de operación se codifica
como una subrutina.

Aquí se definen algunas de las ubicaciones de memoria de la página 00
que podrían ser de interés (todas las direcciones están en hexadecimal):

     0020-0021 Inicio del espacio de programa de usuario
     0022-0023 Fin del espacio de programa de usuario
     0024-0025 Fin del programa BASIC, se añade SPARE
     0026-0027 Principio de la pila BASIC
     0028-0029 Número de línea BASIC actual
     002A-002B Contador de programa IL
     002C-002D Puntero BASIC
     002E-002F Puntero guardado
     0030-007F Línea de entrada y pila de expresiones
     0080-0081 Semilla de número aleatorio
     0082-00B5 Variables
     00BF      Contador de columna de salida y modo de cinta

Otros parámetros importantes tales como la bandera de modo RUN, el
puntero de la pila de operandos, y el puntero de fin de línea de entrada
se colocan en locaciones distintas, dependiendo de las versiones.


                LISTADO DE ENSAMBLADOR DE TINY BASIC

El siguiente es un listado en ensamblador de la versión distribuida
actual de TINY BASIC.