Un intérprete de BASIC es un intérprete que permite a los usuarios introducir y ejecutar programas en el lenguaje BASIC y fue, durante la primera parte de la era de las microcomputadoras , la aplicación predeterminada que ejecutaban las computadoras. Se esperaba que los usuarios utilizaran el intérprete de BASIC para introducir programas o para cargarlos desde un medio de almacenamiento (inicialmente, cintas de casete y , luego, disquetes ).
Los intérpretes BASIC tienen una importancia histórica. El primer producto de Microsoft que salió a la venta fue un intérprete BASIC ( Altair BASIC ), que allanó el camino para el éxito de la empresa. Antes de Altair BASIC, los microordenadores se vendían como kits que debían programarse en código de máquina (por ejemplo, el Apple I ). Durante el período de Altair, los intérpretes BASIC se vendían por separado, convirtiéndose en el primer software vendido a individuos en lugar de a organizaciones; Apple BASIC fue el primer producto de software de Apple. Después del MITS Altair 8800 , se esperaba que los microordenadores se entregaran con sus propios intérpretes BASIC (por ejemplo, el Apple II , que tenía múltiples implementaciones de BASIC). Una reacción negativa contra el precio del Altair BASIC de Microsoft también llevó al desarrollo temprano de software colaborativo, para implementaciones Tiny BASIC en general y Tiny BASIC de Palo Alto en particular.
Los intérpretes de BASIC dejaron de usarse a medida que las computadoras crecían en potencia y sus programas asociados se volvían demasiado largos para escribirlos como un formato de distribución razonable. El software venía cada vez más precompilado y se transmitía en disquetes o a través de sistemas de tablones de anuncios , lo que hacía que la necesidad de listas de fuentes fuera menos importante. Además, los shells de comandos cada vez más sofisticados como MS-DOS y la GUI de Mac se convirtieron en la interfaz de usuario principal , y la necesidad de que BASIC actuara como shell desapareció. El uso de intérpretes de BASIC como lenguaje principal e interfaz para los sistemas había desaparecido en gran medida a mediados de la década de 1980.
BASIC ayudó a impulsar la era del tiempo compartido, se volvió popular en la era de las microcomputadoras, luego se desvaneció para convertirse en otra aplicación en la era de DOS y GUI, y hoy sobrevive en algunos nichos relacionados con el desarrollo de juegos, la retrocomputación y la enseñanza.
BASIC, que en un principio se implementó como un sistema de compilación y ejecución en lugar de como un intérprete, surgió como parte de un movimiento más amplio hacia los sistemas de tiempo compartido . General Electric , que había trabajado en el Dartmouth Time Sharing System y su asociado Dartmouth BASIC , escribió su propio sistema operativo subyacente y lanzó un sistema de tiempo compartido en línea conocido como Mark I que incluía un compilador BASIC (no un intérprete) como uno de sus principales puntos de venta. Otras empresas en el campo emergente siguieron rápidamente su ejemplo. A principios de la década de 1970, BASIC era prácticamente universal en los ordenadores mainframe de uso general. [1]
BASIC, como lenguaje simplificado diseñado con edición de línea integrada en mente, era naturalmente adecuado para ser portado al mercado de minicomputadoras , que estaba surgiendo al mismo tiempo que los servicios de tiempo compartido. Estas máquinas tenían una memoria principal muy pequeña , quizás tan poco como 4 KB en la terminología moderna, y carecían del almacenamiento de alto rendimiento como los discos duros que hacen que los compiladores sean prácticos. En contraste, un intérprete ocuparía menos recursos computacionales, a expensas del rendimiento. En 1968, Hewlett Packard presentó el HP 2000 , un sistema que se basaba en su intérprete HP Time-Shared BASIC . [2] En 1969, Dan Paymar e Ira Baxter escribieron otro intérprete BASIC temprano para Data General Nova . [3]
Un reticente fue Digital Equipment Corporation (DEC), el principal vendedor de minicomputadoras. Habían lanzado un nuevo lenguaje conocido como FOCAL , basado en el JOSS anterior desarrollado en una máquina DEC en el Stanford Research Institute a principios de los años 1960. JOSS era similar a BASIC en muchos aspectos, y FOCAL era una versión diseñada para funcionar en sistemas de memoria muy pequeña, en particular el PDP-8 , que a menudo se entregaba con 4 KB de memoria principal . A finales de los años 1960, los vendedores de DEC, especialmente en el departamento de ventas educativas, descubrieron que sus clientes potenciales no estaban interesados en FOCAL y buscaban sus sistemas en otra parte. Esto impulsó a David H. Ahl a contratar a un programador para producir un BASIC para el PDP-8 y otras máquinas DEC. En menos de un año, todo el interés en alternativas como JOSS y FOCAL había desaparecido. [4]
La introducción de los primeros microordenadores a mediados de los años 70 continuó el crecimiento explosivo de BASIC, que tenía la ventaja de que era bastante conocido por los jóvenes diseñadores y aficionados a la informática que se interesaban por los microordenadores, muchos de los cuales habían visto BASIC en minis o mainframes. BASIC era uno de los pocos lenguajes que era lo suficientemente de alto nivel para ser utilizado por personas sin formación y lo suficientemente pequeño para caber en los microordenadores de la época. En 1972, HP presentó la calculadora de escritorio programable HP 9830A con un intérprete BASIC Plus en memoria de sólo lectura (ROM). [5]
En junio de 1974, Alfred Weaver, Michael Tindall y Ronald Danielson de la Universidad de Illinois en Urbana-Champaign demostraron que era posible producir "un intérprete de lenguaje BASIC para el microprocesador Intel 8008", en su artículo del mismo nombre, aunque su aplicación se implementó en un simulador 8008 para el IBM 360/75 y requirió 16 KB. [6]
En enero de 1975 se anunció el Altair 8800 , lo que desencadenó la revolución de los microordenadores . Gates, Allen y Monte Davidoff escribieron conjuntamente una de las primeras versiones de BASIC para microordenadores para su recién formada empresa, Micro-Soft. Esta versión fue lanzada por MITS en formato de cinta perforada para el Altair 8800 poco después de la propia máquina, [7] lo que demuestra que BASIC es el lenguaje principal de los primeros microordenadores.
En marzo de 1975, Steve Wozniak asistió a la primera reunión del Homebrew Computer Club y comenzó a formular el diseño de su propio ordenador. Los miembros del club estaban entusiasmados con Altair BASIC. [8] Wozniak concluyó que su máquina tendría que tener un BASIC propio. En ese momento trabajaba en Hewlett Packard y utilizó su dialecto de miniordenador, HP Time-Shared BASIC , como base para su propia versión. Integer BASIC se publicó en casete para Apple I y se suministró en ROM cuando se envió el Apple II en el verano de 1977. [9]
Otros miembros del Homebrew Computer Club comenzaron a hacer circular copias de Altair BASIC en cinta de papel, lo que provocó que Gates escribiera su Carta abierta a los aficionados , quejándose de este temprano ejemplo de piratería de software . En parte como respuesta a la carta de Gates, y en parte para hacer un BASIC aún más pequeño que pudiera funcionar de manera útil en máquinas de 4 KB, [a] Bob Albrecht instó a Dennis Allison a escribir su propia variación del lenguaje. Cómo diseñar e implementar una versión reducida de un intérprete para el lenguaje BASIC fue tratado en artículos de Allison en los primeros tres números trimestrales del boletín de People's Computer Company publicado en 1975 y las implementaciones con código fuente publicadas en Dr. Dobb's Journal of Tiny BASIC Calisthenics & Orthodontia: Running Light Without Overbyte . Esto condujo a una amplia variedad de Tiny BASIC con características agregadas u otras mejoras, con versiones conocidas de Tom Pittman y Li-Chen Wang , ambos miembros del Homebrew Computer Club. [10] Tiny BASIC se publicó abiertamente y Wang acuñó el término "copyleft" para alentar a otros a copiar su código fuente. Aficionados y profesionales crearon sus propias implementaciones, lo que convirtió a Tiny BASIC en un ejemplo de un proyecto de software libre que existía antes del movimiento del software libre .
Muchas empresas desarrollaron intérpretes de BASIC. En 1976, SCELBI introdujo SCELBAL para el 8008 [11] y la Universidad de Idaho y el Laboratorio Lawrence Livermore anunciaron que publicarían en el dominio público el BASIC LLL, que incluía soporte de punto flotante. [12] En 1977, el Apple II y el TRS-80 Model I tenían cada uno dos versiones de BASIC, una versión más pequeña introducida con los lanzamientos iniciales de las máquinas y una versión con licencia de Microsoft introducida más tarde a medida que aumentaba el interés en las plataformas.
Microsoft adaptó su intérprete al MOS 6502 , que rápidamente se convirtió en uno de los microprocesadores más populares de la era de los 8 bits. Cuando empezaron a aparecer nuevos microordenadores, como el Commodore PET , sus fabricantes licenciaron un Microsoft BASIC, personalizado para las capacidades del hardware. En 1978, MS BASIC era un estándar de facto y prácticamente todos los ordenadores domésticos de los años 1980 lo incluían en la ROM . En 1980, como parte de un acuerdo de licencia más amplio que incluía otros lenguajes y PC DOS , IBM rechazó una propuesta de Atari y en su lugar licenció MS-BASIC sobre su propia implementación, lanzando finalmente cuatro versiones de IBM BASIC , cada una mucho más grande que los intérpretes anteriores (por ejemplo, Cartridge BASIC ocupaba 40 KB). [13] Don Estridge , líder del equipo de IBM PC , dijo: "IBM tiene un BASIC excelente: es bien recibido, se ejecuta rápidamente en computadoras mainframe y es mucho más funcional que los BASIC de microcomputadoras... Pero [su] número de usuarios era infinitesimal comparado con el número de usuarios de Microsoft BASIC. Microsoft BASIC tenía cientos de miles de usuarios en todo el mundo. ¿Cómo se puede discutir eso?" [14] (Véase Microsoft BASIC para la historia posterior de estas diferentes implementaciones.)
Muchos vendedores "discutieron con eso" y usaron otras empresas o escribieron sus propios intérpretes. En septiembre de 1978, Shepardson Microsystems estaba terminando el BASIC estructurado de 16K de Cromemco para las máquinas de bus Cromemco S-100 basadas en Z80 . [15] [16] Paul Laughton y Kathleen O'Brien crearon entonces Atari BASIC [17] como esencialmente una versión reducida de Cromemco BASIC portada al 6502. [18] En 1979, Warren Robinett desarrolló el cartucho de programación BASIC para Atari, Inc. , aunque sólo admitía programas con 9 líneas de código (64 caracteres en total). También en 1979, Texas Instruments lanzó TI BASIC con su TI-99/4 , que vendería casi 3 millones de sistemas cuando se renovó como TI-99/4A. Sinclair BASIC fue desarrollado para el ZX-80 por John Grant y Steve Vickers de Nine Tiles. En 1980, Sophie Wilson de Acorn Computers desarrolló Atom BASIC , que luego desarrolló en BBC BASIC , uno de los primeros intérpretes en ofrecer programación estructurada en BASIC, con procedimientos y funciones / con nombre, bucles y estructuras inspiradas en COMAL . [19] [20] Jan Jones desarrolló SuperBASIC , otro BASIC británico que soporta programación estructurada, para Sinclair QL . En 1983, Randall Hyde desarrolló SmartBASIC para Coleco Adam . [21] Richard Clayton, Chris Hall y Paul Overell desarrollaron Mallard BASIC para BBC Micro y Locomotive BASIC para Amstrad CPC , ambos con comandos de soporte para un sistema de archivos indexado ISAM . [22] En 1985, MetaComCo lanzó ABasiC para Amiga y ST BASIC para Atari ST . DEF PROC
DEF FN
REPEAT UNTIL
IF THEN ELSE
En 1978, David Lien publicó la primera edición de The BASIC Handbook: An Encyclopedia of the BASIC Computer Language , que documentaba palabras clave de más de 78 computadoras diferentes. En 1981, la segunda edición documentaba palabras clave de más de 250 computadoras diferentes, lo que mostraba el crecimiento explosivo de la era de las microcomputadoras. [23]
Con el surgimiento de los sistemas operativos de disco y, posteriormente, de las interfaces gráficas de usuario , los intérpretes de BASIC se convirtieron en solo una aplicación entre muchas, en lugar de proporcionar el primer mensaje que un usuario podría ver al encender una computadora.
En 1983, debutó la computadora portátil TRS-80 Modelo 100 , con su implementación en Microsoft BASIC que es notable por dos razones. En primer lugar, los programas se editaban utilizando el editor de texto simple, TEXT, en lugar de escribirse línea por línea (pero aún se requerían los números de línea). [24] En segundo lugar, este fue el último producto de Microsoft que Bill Gates desarrolló personalmente. [25] [26]
También en 1983, Microsoft comenzó a incluir GW-BASIC en el DOS. Funcionalmente idéntico a IBM BASICA , su intérprete BASIC era un ejecutable completamente autónomo y no necesitaba la ROM Cassette BASIC que se encontraba en el IBM PC original . Según Mark Jones Lorenzo, dado el alcance del lenguaje, "GW-BASIC es posiblemente el non plus ultra de la familia de BASIC de numeración de línea de Microsoft que se remonta al Altair, y quizás incluso del BASIC de numeración de línea en general". [27] Con el lanzamiento de MS-DOS 5.0, el lugar de GW-BASIC fue ocupado por QBasic .
MacBASIC ofrecía un entorno de desarrollo totalmente interactivo para el ordenador Macintosh original y fue desarrollado por Donn Denman, [28] Marianne Hsiung, Larry Kenyon y Bryan Stearns. [29] MacBASIC se lanzó como software beta en 1985 y se adoptó para su uso en lugares como el departamento de informática del Dartmouth College , para su uso en un curso introductorio de programación. Estaba condenado a ser el segundo BASIC desarrollado por Apple que se canceló en favor de un BASIC de Microsoft. En noviembre de 1985, Apple terminó abruptamente el proyecto como parte de un acuerdo con Microsoft para extender la licencia de BASIC en el Apple II . [30] [31]
\
Los intérpretes de BASIC no fueron sólo un desarrollo estadounidense/británico. En 1984, Hudson Soft lanzó Family BASIC en el mercado japonés para la consola de videojuegos Family Computer de Nintendo, una implementación de solo números enteros diseñada para la programación de juegos, basada en Hudson Soft BASIC para Sharp MZ80 (con palabras clave en inglés). [32] Turbo-Basic XL es un superconjunto compatible de Atari BASIC, desarrollado por Frank Ostrowski y publicado en la edición de diciembre de 1985 de la revista informática alemana Happy Computer , lo que lo convierte en uno de los últimos intérpretes publicados como un programa de escritura . El lenguaje incluía un compilador además del intérprete y presentaba comandos de programación estructurada. Otros autores lanzaron varias versiones modificadas que funcionaban con diferentes sistemas DOS. En Francia, François Lionet y Constantin Sotiropoulos desarrollaron dos intérpretes de BASIC con un enfoque en multimedia: STOS BASIC para Atari ST , en 1988, [33] y AMOS BASIC para Amiga , en 1990.
En mayo de 1991, Microsoft lanzó Visual Basic , un lenguaje de programación controlado por eventos de tercera generación conocido por su modelo de programación Modelo de objetos componentes (COM). [34] Visual Basic admitía el desarrollo rápido de aplicaciones (RAD) de aplicaciones de interfaz gráfica de usuario (GUI) , el acceso a bases de datos mediante objetos de acceso a datos , objetos de datos remotos u objetos de datos ActiveX , y la creación de controles y objetos ActiveX . Visual Basic se utilizó para desarrollar aplicaciones internas propietarias, así como aplicaciones publicadas.
En 1993, Microsoft lanzó Visual Basic para Aplicaciones , un lenguaje de programación para aplicaciones de Microsoft Office , que reemplaza y amplía las capacidades de lenguajes de programación de macros específicos de aplicaciones anteriores , como WordBASIC de Word (que se había introducido en 1989).
En 1996, Microsoft lanzó VBScript como una alternativa a JavaScript para agregar funcionalidad interactiva del lado del cliente a las páginas web vistas con Internet Explorer . [35]
En 1999, Benoît Minisini lanzó Gambas como una alternativa para los desarrolladores de Visual Basic que habían decidido migrar a Linux . [36]
En 2000, Lee Bamber y Richard Vanner lanzaron DarkBASIC , un sistema de creación de juegos para Microsoft Windows , con IDE y herramientas de desarrollo adjuntos. [37]
En 2001, se lanzó SmallBASIC para Palm PDA . [38] Otro intérprete de BASIC para Palm fue HotPaw BASIC, una rama de Chipmunk Basic .
En 2002, Emmanuel Chailloux, Pascal Manoury y Bruno Pagano publicaron un Tiny BASIC como ejemplo de desarrollo de aplicaciones con Objective Caml . [39]
En 2011, Microsoft lanzó Small Basic (distinto de SmallBASIC), junto con un plan de estudios de enseñanza [40] y una guía introductoria [41] diseñada para ayudar a los estudiantes que han aprendido lenguajes de programación visual como Scratch a aprender programación basada en texto. [42] El IDE asociado proporciona un entorno de programación simplificado con funcionalidades como resaltado de sintaxis , finalización inteligente de código y acceso a la documentación en el editor. [43] El lenguaje tiene solo 14 palabras clave. [44] En 2019, Microsoft anunció Small Basic Online (SBO), que permite a los estudiantes ejecutar programas desde un navegador web . [45] [46]
En 2014, Robin H. Edwards lanzó Arduino BASIC para Arduino , y ahora una implementación ampliamente bifurcada. [47] Otra implementación que usa el mismo nombre fue adaptada de Palo Alto Tiny BASIC en 1984 por Gordon Brandly para su 68000 Tiny BASIC, luego portado a C por Mike Field. [48]
Muchos intérpretes BASIC ahora están disponibles para teléfonos inteligentes y tabletas a través de la App Store de Apple o de la tienda Google Play para Android.
Hoy en día, la codificación de intérpretes BASIC se ha convertido en parte del hobby de la retroinformática . Los lenguajes de programación de nivel superior en sistemas con amplia memoria RAM han simplificado la implementación de intérpretes BASIC. Por ejemplo, la gestión de líneas es sencilla si el lenguaje de implementación admite matrices dispersas , la gestión de variables es sencilla con matrices asociativas y la ejecución del programa es fácil con funciones eval . Como ejemplos, véase el proyecto de código abierto Vintage BASIC, escrito en Haskell [49] o el OCaml Tiny BASIC.
Inicialmente, los intérpretes se incluían con el hardware de las computadoras o se desarrollaban como un servicio personalizado, antes de que a fines de los años 1960 surgiera una industria que producía software empaquetado de forma independiente para organizaciones. [50] Los intérpretes BASIC primero se vendieron por separado de las microcomputadoras, luego se integraron, antes de volver a venderse como aplicaciones en la era DOS.
A medida que el mercado se fue orientando hacia las ROM, el tamaño de las mismas pasó a dominar las decisiones sobre el tamaño que podía tener un intérprete de BASIC. Como las RAM se vendían en chips de 4 KB, Altair BASIC se presentó inicialmente en ediciones separadas para 4K, 8K y 12K; esto se trasladó a los chips ROM, ya que los fabricantes decidían cuántos chips ROM podían incluir en su diseño, en función de los objetivos de precio y otras limitaciones.
La primera implementación de BASIC, Dartmouth BASIC , fue un compilador. Generalmente, los compiladores examinan el programa completo en un proceso de varios pasos y generan un segundo archivo que se puede ejecutar directamente en el lenguaje de máquina subyacente del ordenador anfitrión sin hacer referencia al código fuente. Este código suele estar formado por llamadas a rutinas preescritas en el sistema de ejecución del lenguaje . El ejecutable normalmente será más pequeño que el código fuente que lo creó.
La principal desventaja de los compiladores, al menos en el contexto histórico, es que requieren grandes cantidades de memoria temporal. A medida que el compilador trabaja, va produciendo un archivo de salida en constante crecimiento que se guarda en la memoria junto con el código fuente original. La memoria adicional para búsquedas temporales, en particular los números de línea en el caso de BASIC, aumenta el requisito de memoria. Las computadoras de la época tenían cantidades muy pequeñas de memoria; en términos modernos, un mainframe típico podría tener del orden de 64 KB. En un sistema de tiempo compartido, el caso de la mayoría de los BASIC de la década de 1960, esa memoria se compartía entre muchos usuarios.
Para que un compilador funcionara, los sistemas debían tener algún tipo de almacenamiento secundario de alto rendimiento , normalmente un disco duro . La edición de programas se llevaba a cabo en un entorno dedicado que escribía el código fuente del usuario en un archivo temporal. Cuando el usuario ejecutaba el programa, el editor salía y ejecutaba el compilador, que leía ese archivo y generaba el código ejecutable; finalmente, el compilador salía y ejecutaba el programa resultante. Dividir la tarea de esta manera reducía la cantidad de memoria necesaria para cualquiera de las partes del sistema BASIC en general; en un momento dado, solo se tenía que cargar el editor, el compilador o el entorno de ejecución, el resto estaba en el almacenamiento.
Mientras que los mainframes tenían pequeñas cantidades de memoria, los miniordenadores tenían cantidades aún más pequeñas: los sistemas de 4 y 8 KB eran típicos en la década de 1960. Pero lo que es mucho más importante, los miniordenadores tendían a carecer de cualquier forma de almacenamiento de alto rendimiento; la mayoría de los primeros diseños utilizaban cintas perforadas como sistema de almacenamiento primario, y los sistemas de cinta magnética estaban destinados a la gama alta del mercado. En este entorno, un sistema que escribiera el código fuente, lo compilara y luego ejecutara el resultado habría tardado minutos. Debido a estas limitaciones, proliferaron los intérpretes.
Los intérpretes realizan básicamente las mismas tareas básicas que los compiladores: leen el código fuente y lo convierten en instrucciones ejecutables que invocan funciones de tiempo de ejecución. La principal diferencia es el momento en que realizan las distintas tareas. En el caso de un compilador, todo el código fuente se convierte durante lo que al usuario le parece una única operación, mientras que un intérprete convierte y ejecuta el código fuente una instrucción a la vez. El código de máquina resultante se ejecuta, en lugar de generarse, y luego ese código se descarta y el proceso se repite con la siguiente instrucción. Esto elimina la necesidad de algún tipo de almacenamiento secundario mientras se crea un ejecutable. La principal desventaja es que ya no se pueden separar las diferentes partes del proceso general: el código necesario para convertir el código fuente en operaciones de máquina se debe cargar en la memoria junto con el tiempo de ejecución necesario para realizarlo y, en la mayoría de los casos, también el editor de código fuente.
Producir un lenguaje con todos estos componentes que pueda caber en una pequeña cantidad de memoria y aún tenga lugar para el código fuente del usuario es un gran desafío, pero elimina la necesidad de almacenamiento secundario y fue la única solución práctica para las primeras minicomputadoras y la mayor parte de la historia de la revolución de las computadoras domésticas .
El diseño de lenguajes para los primeros intérpretes a menudo implicaba simplemente hacer referencia a otras implementaciones. Por ejemplo, las referencias de Wozniak para BASIC eran un manual de HP BASIC y una copia de 101 BASIC Computer Games . Basándose en estas fuentes, Wozniak comenzó a esbozar un diagrama de sintaxis para el lenguaje. [51] No sabía que el BASIC de HP era muy diferente de la variedad DEC BASIC utilizada en 101 Games . Los dos lenguajes se diferenciaban principalmente en términos de manejo de cadenas y estructuras de control. [52] Data General Business Basic , una implementación de solo números enteros, fue la inspiración para Atari BASIC. [53]
En contraste, Dennis Allison , un miembro de la facultad de Ciencias de la Computación de la Universidad de Stanford , escribió una especificación para una versión simple del lenguaje. [54] Allison fue instado a crear el estándar por Bob Albrecht del Homebrew Computer Club , quien había visto BASIC en minicomputadoras y sintió que sería la combinación perfecta para nuevas máquinas como Altair. El diseño propuesto por Allison solo usaba aritmética de números enteros y no admitía matrices o manipulación de cadenas. El objetivo era que el programa cupiera en 2 a 3 kilobytes de memoria. El diseño general de Tiny BASIC fue publicado en la edición de septiembre de 1975 del boletín de People's Computer Company (PCC).
La gramática se enumera a continuación en la forma Backus–Naur . [55] En la lista, un asterisco (" *
") denota cero o más del objeto a su izquierda, excepto el primer asterisco en la definición de " term
", que es el operador de multiplicación; los paréntesis agrupan objetos; y un épsilon (" ε
") significa el conjunto vacío. Como es común en la notación de gramática de lenguajes informáticos, la barra vertical (" |
") distingue alternativas, al igual que el hecho de estar enumerados en líneas separadas. El símbolo " CR
" denota un retorno de carro .
línea :: = número declaración CR | declaración CR declaración :: = PRINT lista-expr IF expresión relop expresión THEN declaración GOTO expresión INPUT lista-var LET var = expresión GOSUB expresión RETURN CLEAR LIST RUN END lista-expr :: = ( cadena | expresión ) ( , ( cadena | expresión ) ) * lista-var :: = var ( , var ) * expresión :: = ( +|-|ε ) término (( +|- ) término ) * término :: = factor (( * | / ) factor ) * factor :: = var | número | ( expresión ) var :: = A | B | C ... | Y | Z número :: = dígito dígito * dígito :: = 0 | 1 | 2 | 3 | ... | 8 | 9 relop :: = < ( >| = |ε ) | > ( <| = |ε ) | =
Esta sintaxis, tan simple como era, agregó una innovación: GOTO
podía GOSUB
tomar una expresión en lugar de un número de línea, proporcionando un GOTO [56] asignado en lugar de la declaración switch de la ON-GOTO/GOSUB
estructura más típica de BASIC.
Sinclair BASIC utilizó como definición de lenguaje el estándar Minimal BASIC del American National Standards Institute (ANSI) de 1978, pero en sí mismo era una implementación incompleta con solo aritmética de números enteros. [57] El estándar ANSI se publicó después del diseño de la primera generación de intérpretes para microcomputadoras.
Componentes comunes de un intérprete BASIC: [58]
Los primeros microordenadores carecían de herramientas de desarrollo y los programadores desarrollaban su código en miniordenadores o a mano. Por ejemplo, Dick Whipple y John Arnold escribieron Tiny BASIC Extended directamente en código de máquina, utilizando octal . [59] Robert Uiterwyk escribió a mano MICRO BASIC para el SWTPC (un sistema 6800 ) en un bloc de notas. [60] Steve Wozniak escribió el código para Integer BASIC a mano, traduciendo las instrucciones del código ensamblador a sus equivalentes en código de máquina y luego cargando el resultado en su ordenador. [61] (Debido a esto, el programa era muy difícil de cambiar y Wozniak no pudo modificarlo lo suficientemente rápido para Steve Jobs , quien posteriormente licenció BASIC de Microsoft. [62] )
Gates y Allen no tenían un sistema Altair en el que desarrollar y probar su intérprete. Sin embargo, Allen había escrito un emulador Intel 8008 para su proyecto anterior, Traf-O-Data , que se ejecutaba en un ordenador de tiempo compartido PDP-10 . Allen adaptó este emulador basándose en la guía del programador de Altair, y desarrollaron y probaron el intérprete en el PDP-10 de Harvard. [63] Cuando Harvard dejó de utilizar este sistema, Gates y Allen compraron tiempo de ordenador a un servicio de tiempo compartido en Boston para completar la depuración de su programa BASIC. Gates afirmó, en su Carta abierta a los aficionados en 1976, que el valor del tiempo de ordenador para el primer año de desarrollo de software era de 40.000 dólares. [64]
No es que Allen no supiera programar a mano en lenguaje de máquina. Mientras se encontraba en la aproximación final al aeropuerto de Albuquerque en un viaje para demostrar el funcionamiento del intérprete, Allen se dio cuenta de que había olvidado escribir un programa de arranque para leer la cinta en la memoria. Escribiendo en lenguaje de máquina 8080, Allen terminó el programa antes de que el avión aterrizara. Sólo cuando cargó el programa en un Altair y vio un mensaje que le preguntaba por el tamaño de la memoria del sistema supo que el intérprete funcionaba en el hardware del Altair. [65] [66]
Una de las versiones más populares de Tiny BASIC fue Palo Alto Tiny BASIC, o PATB para abreviar. PATB apareció por primera vez en la edición de mayo de 1976 de Dr. Dobbs , escrita en un lenguaje ensamblador personalizado con mnemotecnia no estándar. Li-Chen Wang había codificado su intérprete en un sistema de tiempo compartido con un ensamblador genérico.
Una excepción al uso del ensamblaje fue el uso de ALGOL 60 para el intérprete Paisley XBASIC para los grandes sistemas de Burroughs . [67] Otra excepción, y programa de escritura en lenguaje natural , fue Classic BASIC, escrito por Lennart Benschop en Forth y publicado en la revista holandesa de Forth Vijgeblad (número 42, 1993). [68]
El código fuente de los intérpretes era a menudo de código abierto (como en el caso de Tiny BASIC) o lo publicaban posteriormente los autores. El código fuente completo y anotado y las especificaciones de diseño de Atari BASIC se publicaron en The Atari BASIC Source Book en 1983. [69]
Algunos intérpretes BASIC fueron codificados en la representación intermedia de una máquina virtual para agregar una capa de abstracción y concisión por encima del lenguaje de máquina nativo .
Aunque las máquinas virtuales se habían utilizado en sistemas de compilación y ejecución como BASIC-PLUS , estas solo servían para ejecutar código BASIC, no para analizarlo. [70] Tiny BASIC, por el contrario, se diseñó para implementarse como una máquina virtual que analizara y ejecutara (interpretara) sentencias BASIC; en una implementación de este tipo, el intérprete Tiny BASIC se ejecuta en un intérprete de máquina virtual. [71] La longitud de todo el programa intérprete era de solo 120 operaciones de máquina virtual, que constaban de 32 comandos. [72] Por lo tanto, la elección de un enfoque de máquina virtual economizó espacio de memoria y esfuerzo de implementación, aunque los programas BASIC que se ejecutaban en él se ejecutaban algo lentamente. (Véase Tiny BASIC: Implementación en una máquina virtual para un extracto y comandos de muestra). Aunque la intención del diseño era que Tiny BASIC utilizara una máquina virtual, no todas las implementaciones lo hicieron; entre las que lo hicieron se encontraban Tiny BASIC Extended, 6800 Tiny BASIC, [73] y NIBL.
Para sus computadoras TI-99/4 y TI-99/4A , Texas Instruments diseñó una máquina virtual con un lenguaje llamado GPL, por "lenguaje de programación gráfica". [74] (Aunque se le culpó ampliamente por el lento desempeño de TI-BASIC , parte del problema era que la máquina virtual estaba almacenada en una ROM gráfica, que tenía una interfaz lenta de 8 bits.) [75]
Un malentendido sobre las ROM de Apple II llevó a algunos a creer que Integer BASIC utilizaba una máquina virtual, un lenguaje ensamblador personalizado contenido en las ROM de Apple y conocido como SWEET16 . SWEET16 se basa en códigos de bytes que se ejecutan dentro de una máquina virtual simple de 16 bits, por lo que la memoria podría ser direccionada a través de punteros indirectos de 16 bits y funciones matemáticas de 16 bits calculadas sin la necesidad de traducirlas al código subyacente de múltiples instrucciones de 8 bits 6502. [76] Sin embargo, SWEET16 no fue utilizado por el código básico de BASIC, aunque más tarde se utilizó para implementar varias utilidades, como una rutina de renumeración de líneas. [77]
La mayoría de las implementaciones de BASIC de la época actuaban como intérprete de lenguaje y editor de líneas . Cuando se ejecutaba BASIC, se mostraba un >
símbolo del sistema en el que el usuario podía introducir instrucciones. [78] Esto se conocía como " modo directo ". Al iniciar el sistema, un intérprete de BASIC pasaba por defecto al modo directo.
Las sentencias que se ingresaban con números iniciales se ingresaban en el almacenamiento del programa para su "ejecución diferida", [79] ya sea como líneas nuevas o reemplazando cualquiera que pudiera haber tenido el mismo número anteriormente. [80] Las sentencias que se ingresaban sin un número de línea se denominaban comandos y se ejecutaban inmediatamente. Los números de línea sin sentencias (es decir, seguidos de un retorno de carro ) eliminaban una línea almacenada previamente.
Cuando un programa estaba presente en la memoria y el usuario teclea el RUN
comando, el sistema entra en "modo indirecto". En este modo, se establece un puntero para que apunte a la primera línea del programa, por ejemplo, la línea 10. El texto original de esa línea se recupera del almacén y se ejecuta como si el usuario lo acabara de teclear en modo directo. Luego, el puntero avanza a la siguiente línea y el proceso continúa.
Diferentes implementaciones ofrecían otras capacidades de edición de programas. Altair BASIC 8K tenía un EDIT
comando para cambiar a un modo de edición para una línea. Integer BASIC, también incluía el comando para AUTO
ingresar automáticamente números de línea en un número inicial dado como AUTO 100
, agregando 10 al último número con cada nueva línea. AUTO 300,5
comenzaría a numerar en la línea 300 de cinco en cinco; 300, 305, etc. La numeración automática se desactivaba ingresando MAN
. [81] Algunos intérpretes ofrecían comandos o utilidades de renumeración de líneas.
Para ahorrar memoria RAM y acelerar la ejecución, todos los intérpretes de BASIC codificaban algunos caracteres ASCII de líneas en otras representaciones. Por ejemplo, los números de línea se convertían en números enteros almacenados como bytes o palabras , y a las palabras clave se les podían asignar tokens de un solo byte (por ejemplo, almacenándolos PRINT
como el valor de byte 145, en MS-BASIC). Estas representaciones se convertían luego de nuevo en texto legible al LIST
ejecutar el programa.
Como alternativa a la tokenización, para ahorrar RAM, las primeras implementaciones de Tiny BASIC como Extended Tiny BASIC, [82] Denver Tiny BASIC [83] y MINOL [84] truncaron las palabras clave: PR
for PRINT
, IN
for INPUT
, RET
for RETURN
. Las palabras clave completas y tradicionales no fueron aceptadas.
Por el contrario, el Tiny BASIC de Palo Alto aceptaba las palabras clave tradicionales pero permitía que cualquier palabra clave se abreviara a su cadena única mínima, con un punto final. Por ejemplo, PRINT
se podía escribir P.
, aunque PR.
y otras variaciones también funcionaban. Este sistema se mantuvo en el BASIC de nivel I para el TRS-80 , que utilizaba PATB, y también se encontró en el BASIC de Atari y en el BASIC de varias computadoras de bolsillo Sharp . [85]
Para expandir una abreviatura, el tokenizador de Atari BASIC busca en su lista de palabras reservadas para encontrar la primera que coincida con la parte suministrada. Los comandos más utilizados aparecen primero en la lista de palabras reservadas, con REM
al principio (se puede escribir como .
). Cuando el programa se LIST
edita más tarde, normalmente escribirá las palabras completas. Los BASIC de MS también permitían ?
una forma abreviada de PRINT
, pero la expandían al enumerarla, tratándola como una abreviatura, no como un sinónimo.
La mayoría de los intérpretes de BASIC realizan al menos alguna conversión del formato de texto original a varios formatos específicos de la plataforma. Tiny BASIC era el más simple: sólo convertía el número de línea de su formato decimal a binario. Por ejemplo, el número de línea "100" se convertía en un valor de un solo byte, $64, haciéndolo más pequeño para almacenar en memoria y más fácil de buscar en código de máquina (algunos diseños de Tiny BASIC permitían números de línea de sólo 1 a 254 o 255, aunque la mayoría usaban valores de doble byte y números de línea de al menos 1 a 999). El resto de la línea se dejaba en su formato de texto original. [86] De hecho, Dennis Allison argumentó que, dadas las limitaciones de memoria, la tokenización requeriría más código para implementarse del que ahorraría. [87]
Los MS-BASIC fueron un poco más allá, convirtiendo el número de línea en un valor de dos bytes y también convirtiendo palabras clave, como FOR
o PRINT
, en un valor de un solo byte, el "token". [88] El valor del token tenía el bit alto configurado para permitir que se lo distinguiera fácilmente en tiempo de ejecución. Todo lo demás en una línea se dejaba en su formato original, así que, por ejemplo, la línea:
10 PARA I=1 A 10
Sería tokenizado como:
$64$81$B211$A410
Tenga en cuenta que el espacio entre FOR
y I
permanece en la línea tokenizada, y los nombres de las variables y las constantes no están tokenizadas. El código que realizó esta tokenización, conocido como "el chunker", simplemente copió todo lo que no reconoció como un token en la salida, conservando los espacios tal como estaban. Esto significaba que PRINTA
se almacenaba en dos bytes, mientras que PRINT A
se almacenaba en tres bytes, y eliminar espacios era una forma común de mejorar el uso de la memoria. [89] Sinclair BASIC modificó esto ligeramente, eliminando espacios del código almacenado e insertándolos en el código durante un LIST
, de modo que PRINTA
apareciera como PRINT A
aún no ocupa el byte adicional en la memoria.
En cambio, el BASIC entero convertía la línea 10 GOTO 100
entera en tokens que podían leerse y ejecutarse inmediatamente. En el BASIC MS, la línea produciría $64 $89 100
, y en tiempo de ejecución el "100" tendría que convertirse a formato de 16 bits cada vez que se encontrara. En cambio, el BASIC entero también tokenizaba las variables numéricas, evitando esta conversión y acelerando la ejecución. El valor de dos bytes resultante se insertaba en el código tokenizado junto con un byte de prefijo que indicaba un número seguido. El prefijo era un valor entre $B0 y $B9 , siendo el último nibble del valor el primer dígito decimal del valor original. Los literales de cadena, como "HELLO WORLD", se codificaban en cambio configurando el bit alto de cada carácter para que se almacenara como $C1 . Los nombres de las variables se convertían de la misma manera, con las letras codificadas para tener su bit alto activado y todos los dígitos del nombre representados por los $B0 a $B9 correspondientes , de modo que la variable se codificara como $C1B5 (no se redujera a un token). [90] Hubo muchas otras optimizaciones; donde Microsoft BASIC tenía un token para la palabra clave , Integer BASIC tenía tres tokens: uno si la palabra clave no iba seguida de argumentos, uno si iba seguida de una expresión aritmética y uno si iba seguida de un literal de cadena. [91]A
A5
PRINT
Llevando esto aún más lejos, el tokenizador de Atari BASIC analiza la línea completa cuando se ingresa o modifica. Las constantes numéricas se analizan en su forma interna de 48 bits y luego se colocan en la línea en ese formato, mientras que las cadenas se dejan en su formato original, pero se les antepone un byte que describe su longitud. Las variables tienen un almacenamiento reservado a medida que se encuentran, en lugar de en tiempo de ejecución, y su nombre se reemplaza con un puntero a su ubicación de almacenamiento en la memoria. Shepardson se refirió a este concepto de tokenización temprana como un "intérprete de precompilación"; las declaraciones con errores de sintaxis en realidad no se podían almacenar, y el usuario era inmediatamente incitado a corregirlos. [92]
Algunos intérpretes, como los sistemas Sinclair, básicamente hacían que el usuario hiciera la tokenización proporcionando pulsaciones de teclas especiales para introducir palabras reservadas. Los comandos más comunes necesitan una sola pulsación de tecla; por ejemplo, pulsar solo Pal principio de una línea en un Spectrum produce el comando completo PRINT
. Los comandos menos frecuentes requieren secuencias de teclas más complejas. [93] Como cada línea comienza con una palabra clave, LET
no es opcional, después de que se escribe una palabra clave el sistema vuelve a aceptar texto carácter por carácter. Una ventaja de este enfoque es que el tokenizador no puede confundir cadenas con palabras clave. Por ejemplo, permite nombrar una variable PRINT
y mostrar su valor con PRINT PRINT
.
De manera similar, muchas " computadoras de bolsillo " utilizan una pulsación de una tecla (a veces precedida por varios tipos de teclas de mayúsculas) para producir un byte (el token de la palabra clave) que representa una palabra clave BASIC completa, como EXP, SQR, IF o PEEK , como los conjuntos de caracteres de las computadoras de bolsillo Sharp y TI-BASIC . La expansión BASIC para Bally Astrocade también utiliza esto.
Los números de línea válidos variaban de una implementación a otra, pero normalmente eran del 1 al 32767.
La mayor parte de la memoria utilizada por los intérpretes de BASIC se destinaba a almacenar la lista de programas en sí. Las instrucciones numeradas se almacenaban en orden secuencial en una matriz dispersa implementada como una colección lineal (técnicamente no era una lista , ya que ningún número de línea podía aparecer más de una vez).
Muchas implementaciones de Tiny BASIC almacenaban líneas de la siguiente manera:
Microsoft BASIC, a partir de Altair BASIC, almacenó líneas de la siguiente manera: [94]
Nivel básico de primaria: [95]
La longitud máxima de una línea variaba: 64 caracteres en Palo Alto Tiny BASIC, incluida la representación decimal del número de línea; 120 caracteres en Atari BASIC; 128 caracteres en Integer BASIC; [96] y 255 caracteres en MS-BASIC (sin incluir el número de línea).
Los intérpretes buscarían en el programa una línea a la vez, observando cada número de línea. Si fuera menor que el nuevo número de línea, las líneas posteriores se moverían en la memoria para dejar lugar al espacio requerido para la nueva línea. Si fuera el mismo número de línea, y no exactamente la misma longitud, las líneas subsiguientes tendrían que moverse hacia adelante o hacia atrás. [97] (Como el orden secuencial siempre se mantenía en la memoria, estas no eran listas enlazadas ).
En Tiny BASIC, estas búsquedas requerían comprobar cada byte de una línea: el puntero se incrementaba una y otra vez hasta que se encontraba un retorno de carro, para encontrar el byte antes de la siguiente línea. En Altair BASIC y LLL BASIC, por otro lado, el puntero se establecía en el inicio de la siguiente línea secuencial; esto era mucho más rápido, pero requería dos bytes por línea. Dado que se suponía que los programas Tiny BASIC tenían un tamaño de 4 KB o menos, esto se ajustaba a la filosofía de diseño general de Tiny BASIC de sacrificar el rendimiento a favor de minimizar el uso de memoria.
Cuando el usuario escribía LIST
en la línea de comando, el sistema recorría la matriz de líneas, utilizando uno de estos métodos, convertía el número de línea nuevamente a formato decimal y luego imprimía el resto del texto en la línea, decodificando cualquier token u otras representaciones codificadas.
A medida que los desarrolladores agregaron construcciones de programación estructurada a BASIC, a menudo eliminaron por completo la necesidad de números de línea y agregaron editores de texto y, más tarde, entornos de desarrollo integrados .
Dartmouth BASIC y HP-BASIC limitaban los nombres de las variables a un máximo de dos caracteres (una sola letra o una letra seguida de un dígito; por ejemplo, de la A a la Z9). MS-BASIC permitía nombres de variables compuestos por una letra seguida de una letra o un dígito opcional (por ejemplo, de la A a la ZZ), pero ignoraba los caracteres subsiguientes: por lo tanto, era posible escribir inadvertidamente un programa con las variables "LOSS" y "LOAN", que se tratarían como si fueran la misma; asignar un valor a "LOAN" sobrescribiría silenciosamente el valor previsto como "LOSS".
El BASIC de enteros era inusual en cuanto a que admitía nombres de variables de cualquier longitud (por ejemplo, SUM, GAMEPOINTS, PLAYER2), siempre que no contuvieran una palabra reservada. [98] En muchos de los primeros BASIC no se podían usar palabras clave en variables; "SCORE" se interpretaría como "SC" OR "E", donde OR era una palabra clave.
Las variables de cadena se distinguen generalmente en muchos dialectos de microcomputadoras de BASIC por tener $ como sufijo en su nombre, y los valores se identifican a menudo como cadenas al estar delimitados por "comillas dobles". Las implementaciones posteriores utilizarían otros signos de puntuación para especificar el tipo de una variable: A% para entero, A! para precisión simple y A# para precisión doble .
Con excepción de las matrices y (en algunas implementaciones) las cadenas, y a diferencia de Pascal y otros lenguajes de programación más estructurados, BASIC no requiere que se declare una variable antes de hacer referencia a ella. Los valores normalmente tendrán como valor predeterminado 0 (con la precisión adecuada) o la cadena nula.
Como Tiny BASIC sólo utilizaba 26 variables de una sola letra, las variables podían almacenarse como una matriz sin almacenar sus nombres correspondientes, utilizando una fórmula basada en el valor ASCII de la letra como índice. Tiny BASIC de Palo Alto llevó esto un paso más allá: los valores de dos bytes de las variables se ubicaban en la RAM dentro del programa, desde los bytes 130 (ASCII 65, 'A', multiplicado por dos) hasta 181 (ASCII 90, 'Z', multiplicado por dos, más uno por el segundo byte). [85]
La mayoría de los BASIC preveían la posibilidad de tener mucho más de 26 variables y, por lo tanto, necesitaban tablas de símbolos que reservaran capacidad de almacenamiento solo para aquellas variables utilizadas.
En LLL BASIC, cada entrada en la tabla de símbolos se almacenaba de la siguiente manera: [99]
A diferencia de la mayoría de los intérpretes de BASIC, UIUC BASIC tenía una función hash , que hacía un hash por la letra del nombre de la variable/función/matriz y luego realizaba una búsqueda lineal a partir de ahí. En UIUC BASIC, una entrada de la tabla de símbolos era: [58]
FN
; letra ASCII)En Atari BASIC, un conjunto de punteros (direcciones) indicaban diversos datos: los nombres de las variables se almacenaban en la tabla de nombres de variables (VNTP – 82, 83 16 ) y sus valores se almacenaban en la tabla de valores de las variables (apuntada en VVTP – 86, 87 16 ). Al indirigir los nombres de las variables de esta manera, una referencia a una variable necesitaba solo un byte para direccionar su entrada en la tabla apropiada. Las variables de cadena tenían su propia área.
Una optimización del rendimiento de BBC BASIC incluyó el uso de múltiples listas enlazadas para la búsqueda de variables en lugar de una única lista larga, como en Microsoft BASIC .
Debido a la pequeña capacidad de RAM de la mayoría de los sistemas utilizados originalmente para ejecutar intérpretes BASIC, se tuvieron que emplear técnicas de gestión de memoria inteligentes. Altair BASIC permitía a los usuarios recuperar el espacio para funciones trigonométricas si no se utilizaban durante una sesión. PATB colocaba el inicio de las subrutinas más comunes al principio del programa para que las utilizara el RST
código de operación 8080 de 1 byte en lugar del CALL
código de operación de 3 bytes. En LLL BASIC, algunas variables ocupaban las mismas ubicaciones de memoria, en los casos en que las diferentes variables se utilizaban solo en modo de comando o solo en tiempo de ejecución. [100]
El vídeo era a menudo direccionable desde la memoria, y ciertas funciones esotéricas estaban disponibles manipulando valores en valores de memoria específicos. Por ejemplo, las direcciones 32 a 35 contenían las dimensiones de la ventana de texto (en oposición a la ventana de gráficos) en Applesoft BASIC. El POKE
comando y la PEEK
función (adaptados de monitores de código de máquina como el monitor DECsystem-10 [101] ) proporcionaban acceso directo a la memoria, para una variedad de propósitos, [102] especialmente para modificar registros de hardware especiales mapeados en memoria para controlar funciones particulares de la computadora como los periféricos de entrada/salida. Los "mapas de memoria" (en el sentido arcaico de listas de direcciones de memoria y sus funciones) eran populares para su uso con PEEK y POKE , y uno de los mapas de memoria más conocidos es el libro Mapping the Atari , escrito por Ian Chadwick.
Algunas implementaciones del intérprete de Microsoft, por ejemplo las que se ejecutan en los modelos I/III de TRS-80 , requerían que el usuario especificara la cantidad de memoria que utilizaría el intérprete. Esto era para permitir que una región de memoria se reservara para la instalación de subrutinas de lenguaje de máquina que pudieran ser llamadas por el programa interpretado, para una mayor velocidad de ejecución. Cuando se encienden los modelos I/III, el usuario recibe el mensaje "¿Tamaño de memoria?" para este propósito.
El BASIC de enteros, como su nombre lo indica, utiliza números enteros como base para su paquete matemático. Estos se almacenaban internamente como un número de 16 bits, little-endian (como el 6502). Esto permitía un valor máximo para cualquier cálculo entre −32767 y 32767. Los cálculos que daban como resultado valores fuera de ese rango producían un error. [103]
La mayoría de los intérpretes Tiny BASIC (así como Sinclair BASIC 4K) admitían operaciones matemáticas utilizando únicamente números enteros, sin compatibilidad con coma flotante . El uso de números enteros permitía almacenar números en un formato de 16 bits mucho más compacto que podía leerse y procesarse más rápidamente que los formatos de coma flotante de 32 o 40 bits que se encontraban en la mayoría de los BASIC de la época. Sin embargo, esto limitaba su aplicabilidad como lenguaje de propósito general.
Las implementaciones de Business BASIC , como Data General Business Basic , también eran solo de números enteros, pero normalmente con una precisión mayor: "doble precisión", es decir, 32 bits (más o menos 2.147.483.648) y "triple precisión" (más o menos 1,4x10^14).
En ocasiones se utilizaron otros formatos de números informáticos . Por ejemplo, el MINOL Tiny BASIC sólo admitía bytes sin signo , [84] y el MICRO-BASIC Tiny BASIC utilizaba el formato decimal codificado en binario . [104] Pero el punto flotante acabaría predominando.
Una historia resume por qué el punto flotante se consideró tan importante. El prototipo original del TRS-80 Model I ejecutaba la versión de dominio público de Tiny BASIC de Li-Chen Wang . Esto requería solo 2 KB de memoria para el intérprete , dejando un promedio de otros 2 KB libres para programas de usuario en diseños de memoria comunes de 4 KB de las primeras máquinas. Durante una demostración a los ejecutivos, el entonces presidente de Tandy Corporation, Charles Tandy, intentó ingresar su salario pero no pudo hacerlo. Esto se debió a que Tiny BASIC usaba números enteros con signo de 2 bytes con un valor máximo de 32,767. El resultado fue una solicitud de matemáticas de punto flotante para la versión de producción. [105] Esto llevó a la sustitución del código entero de 16 bits existente con una versión que usaba números de punto flotante de precisión simple de 32 bits por parte del empleado de Tandy, Steve Leininger. [106]
SCELBAL utilizó rutinas de punto flotante publicadas por Wadsworth en 1975 en Machine Language Programming para el 8008 basadas en un formato de 32 bits (cuatro bytes) para cálculos numéricos, con una mantisa de 23 bits , un signo de 1 bit para la mantisa, un exponente de 7 bits y un signo de 1 bit para el exponente. Estas rutinas estaban organizadas en orden inverso, con el byte menos significativo de la mantisa en el primer byte, seguido por el byte del medio y luego el más significativo con el signo en el bit alto. El exponente venía al final, nuevamente con el signo en el bit alto. [107] El manual proporciona código ensamblador bien documentado para todo el paquete matemático, incluidos puntos de entrada y notas de uso. [108]
Los consultores solían encargarse de la aritmética de punto flotante , un dominio especializado bien estudiado y desarrollado para las aplicaciones científicas y comerciales que habían caracterizado a los mainframes. Cuando Allen y Gates estaban desarrollando Altair BASIC, su compañero de estudios de Harvard Monte Davidoff los convenció de que cambiaran de la aritmética de números enteros . Contrataron a Davidoff para que escribiera un paquete de punto flotante que pudiera caber dentro de los límites de memoria de 4 KB. Steve Wozniak recurrió a Roy Rankin de la Universidad de Stanford para implementar las funciones trascendentales LOG, LOG10 y EXP; [109] sin embargo, Wozniak nunca terminó de añadir soporte de punto flotante a Integer BASIC. LLL BASIC , desarrollado en la Universidad de Idaho por John Dickenson, Jerry Barber y John Teeter, recurrió a David Mead, Hal Brand y Frank Olken para su soporte de punto flotante. [110] Para UIUC BASIC, se licenció un paquete de punto flotante Datapoint 2200. [111]
En cambio, los sistemas de tiempo compartido solían depender del hardware. Por ejemplo, el GE-235 fue elegido para implementar la primera versión de Dartmouth BASIC específicamente porque incluía una " unidad aritmética auxiliar " para cálculos de punto flotante y de doble precisión. [112] [113]
Los primeros intérpretes utilizaban formatos de 32 bits, similares al formato binario de punto flotante de precisión simple IEEE 754 , que especifica:
Aquí está el valor 0,15625 almacenado en este formato:
Si bien los formatos de 32 bits eran comunes en esta era, las versiones posteriores de BASIC, comenzando con Microsoft BASIC para el MOS 6502 , generalmente adoptaron un formato de 40 bits (cinco bytes) para mayor precisión. [114]
Los operadores infijos incluían típicamente +
(suma), -
(resta), *
(multiplicación), /
(división) y exponente usando el ^
carácter . Las operaciones relativas incluían el conjunto estándar de =
, >
, <
, >=
, <=
, y para "no igual" <>
o el , inspirado en HP-TSB#
. [115] Los operadores binarios, como AND
, OR
y NOT
, no estaban en todas las implementaciones, y algunos hacían álgebra booleana y otros no.
La edición inicial de Dartmouth BASIC incluía las siguientes funciones: ABS
( valor absoluto ), ATN
( arcotangente ), COS
( coseno ), EXP
( e elevado a la potencia), INT
(trunca cualquier valor fraccionario y devuelve un entero), LOG
( logaritmo ), RND
( generador de números pseudoaleatorios ), SIN
( seno ), SQR
( raíz cuadrada ) y TAN
( tangente ). También incluía la DEF FN
instrucción para declarar funciones unilineales, que luego se denominarían FNA()
, FNB()
, etc.
Esta RND
función fue la más extendida en ser admitida en los primeros BASIC, aunque las implementaciones variaron:
RND
ignoró el parámetro y siempre devolvió un nuevo número pseudoaleatorio entre 0 y 1.RND(6)+1
simulaba un lanzamiento de dados y devolvía valores del 1 al 6.RND(6)
devolvería un valor de 1 a 6, y RND(1)
siempre devolvería 1. [117]La segunda versión de Dartmouth BASIC admitía matrices y operaciones con matrices , útiles para la solución de conjuntos de ecuaciones algebraicas lineales simultáneas; MAT
se admitían operaciones con matrices como asignación, suma, multiplicación (de tipos de matrices compatibles) y evaluación de un determinante.
Por el contrario, Tiny BASIC, tal como fue diseñado inicialmente, ni siquiera tenía matrices, debido a la limitada memoria principal disponible en los primeros microordenadores , a menudo de 4 KB, que tenía que incluir tanto al intérprete como al programa BASIC. Tiny BASIC de Palo Alto añadió una única matriz de longitud variable de números enteros, cuyo tamaño no tenía que ser dimensionado, pero utilizaba RAM que no utilizaban el intérprete ni el listado del programa A()
.
SCELBAL admitía múltiples matrices, pero en conjunto estas matrices no podían tener más de 64 elementos. Integer BASIC admitía matrices de una sola dimensión, limitadas en tamaño solo por la memoria disponible. [118] Tiny BASIC Extended admitía matrices bidimensionales de hasta 255 por 255. Altair BASIC 4K admitía solo matrices (de una dimensión) mientras que la versión 8K admitía matrices de hasta 34 dimensiones. [119]
Muchas implementaciones respaldaron la práctica de Dartmouth BASIC de no requerir que una matriz esté dimensionada, en cuyo caso se asumía que tenía 11 elementos (0 a 10); por ejemplo, {{{1}}}
crearía la matriz de 11 elementos como un efecto secundario.
El vector de dopaje de las matrices variaba de una implementación a otra. Por ejemplo, el vector de dopaje de una matriz Altair BASIC 4K: [94]
Luego los valores de la matriz en sí:
Las implementaciones que admitían matrices tenían que registrar la cantidad de dimensiones y el límite superior de cada dimensión. Además, como algunos intérpretes solo tenían un tipo de datos (ya sea de punto flotante o entero), el vector de datos solo necesitaba registrar la cantidad de dimensiones y el límite superior de cada dimensión. Los intérpretes con múltiples tipos de datos tenían que registrar el tipo de datos de la matriz.
Aunque Microsoft y otros BASIC admitían matrices, las operaciones con matrices no estaban integradas, sino que debían programarse explícitamente en los elementos de la matriz.
El BASIC Dartmouth original, algunos de sus descendientes inmediatos y las implementaciones de Tiny BASIC carecían de manejo de cadenas. Se desarrollaron dos escuelas de manejo de cadenas que competían entre sí, iniciadas por HP y DEC, aunque luego surgieron otros enfoques que requerían estrategias de implementación diferentes.
El manejo de cadenas más simple copió el BASIC de tiempo compartido de HP y definió las variables de cadena como matrices de caracteres que debían ser DIM
ensionadas antes de su uso. Las cadenas en HP TSB se tratan como una matriz de caracteres, hasta 72 en total, en lugar de un único objeto de múltiples caracteres. De manera predeterminada, se les asigna un carácter en la memoria y, si se necesita una cadena de mayor longitud, se deben declarar. Por ejemplo, se configurará una cadena que puede contener un máximo de 10 caracteres. [120]DIM A$[10]
Se accede a las subcadenas dentro de cadenas mediante una notación de " slicing ": o , donde la subcadena comienza con el carácter más a la izquierda especificado por el índice L y continúa hasta el carácter más a la derecha especificado por el índice R, o la forma donde la subcadena comienza en el carácter más a la izquierda especificado por el índice L y continúa hasta el final de la cadena. TSB acepta () o [] indistintamente. Los índices de matriz y subcadena comienzan con 1.A$(L,R)
A$[L,R]
A$[L]
Esto contrasta marcadamente con los BASIC que siguen el patrón DEC que utilizan funciones como LEFT$()
, MID$()
y RIGHT$()
para acceder a subcadenas. Adoptada posteriormente por ANSI BASIC, la notación de HP también se puede utilizar en el lado de destino de una instrucción LET
or INPUT
para modificar parte de un valor de cadena existente, por ejemplo or , lo que no se puede hacer con las primeras implementaciones de .100 A$[3,5]="XYZ"
120 B$[3]="CHANGE ALL BUT FIRST TWO CHARS"
LEFT$/MID$/RIGHT$
Las versiones posteriores de Dartmouth BASIC sí incluían variables de cadena. Sin embargo, no utilizaban las LEFT$/MID$/RIGHT$
funciones para manipular cadenas, sino que utilizaban el CHANGE
comando que convertía la cadena a y desde valores ASCII equivalentes. (Posteriormente adoptado tal como está por DEC y adaptado por HP, que cambió la palabra clave a CONVERT
. [120] ) Además, se podía utilizar la comilla simple para convertir una constante numérica en un carácter ASCII, lo que permitía construir una cadena en partes; A$='23 '64 '49 "DEF"
producía la cadena "ABCDEF", sin necesidad de la CHR$()
función. [120] Dartmouth BASIC Sexta Edición admitía SEG$
(para MID$
) y POS
(para INSTR
).
Integer BASIC, North Star BASIC [121] y Atari BASIC [122] imitaron el enfoque de HP, que nuevamente contrastaba con el estilo encontrado en los BASIC derivados de DEC , incluido Microsoft BASIC , donde las cadenas son un tipo intrínseco de longitud variable. [123]
Algunas de las implementaciones de Tiny BASIC admitían una o más matrices de enteros predefinidas, que podían usarse para almacenar códigos de caracteres, siempre que el lenguaje tuviera funcionalidad para ingresar y emitir códigos de caracteres (por ejemplo, Astro BASIC tenía KP
y TV
para este propósito).
El hecho de que las cadenas utilicen una cantidad fija de memoria independientemente de la cantidad de caracteres que se utilicen en ellas, hasta un máximo de 255 caracteres, puede haber desperdiciado memoria [124], pero tenía la ventaja de evitar la necesidad de implementar la recolección de basura del montón , una forma de gestión automática de la memoria que se utiliza para recuperar la memoria ocupada por cadenas que ya no se utilizan. Las cadenas cortas que se liberan pueden almacenarse en medio de otras cadenas, lo que evita que se utilice esa memoria cuando se necesita una cadena más larga.
En los primeros microordenadores, con su memoria limitada y procesadores lentos, la recolección de basura de BASIC podía causar a menudo pausas aparentemente aleatorias e inexplicables en medio de la operación del programa. Algunos intérpretes de BASIC, como Applesoft BASIC en la familia Apple II , escaneaban repetidamente los descriptores de cadena en busca de la cadena que tuviera la dirección más alta para compactarla hacia una memoria alta, lo que daba como resultado un rendimiento O(n 2 ) , que podía introducir pausas de minutos en la ejecución de programas con uso intensivo de cadenas. La recolección de basura era notoriamente lenta o incluso interrumpida en otras versiones de Microsoft BASIC. [125] Algunos sistemas operativos que admitían tareas en segundo plano impulsadas por interrupciones, como TRSDOS/LS-DOS 6.x en el TRS-80 Model 4 , explotaban los períodos de inactividad del usuario (como los períodos de milisegundos entre las pulsaciones de teclas y los períodos posteriores a la actualización de la pantalla de vídeo) para procesar la recolección de basura durante las ejecuciones de programas BASIC.
La mayoría de los intérpretes de BASIC diferían ampliamente en gráficos y sonido, que variaban drásticamente de un microordenador a otro. Altair BASIC carecía de comandos gráficos o de sonido, al igual que las implementaciones de Tiny BASIC, mientras que Integer BASIC ofrecía un conjunto muy completo.
El nivel I de BASIC para el TRS-80 tenía un conjunto lo más mínimo posible: CLS
, para CLear Screen; SET(X,Y)
, que iluminaba una ubicación en la pantalla; RESET(X,Y)
, que la apagaba; y POINT(X,Y)
, que devolvía 1 si una ubicación estaba iluminada, 0 si no lo estaba. Las coordenadas podían ser cualquier expresión y variaban de 0 a 127 para el eje X y de 0 a 47 para el eje Y. Solo se admitía la visualización en blanco y negro. [126]
En cambio, el BASIC entero admitía gráficos en color, sonido simple y controladores de juegos. El modo gráfico se activaba con la GR
instrucción y se desactivaba con TEXT
. [127] El dibujo era modal y normalmente comenzaba emitiendo un comando para cambiar el color, lo que se lograba estableciendo una pseudovariable; COLOR=12
fijaba el color del dibujo en 12, verde claro. Se podía entonces PLOT 10,10
producir un único punto de ese color, [128] HLIN 0,39 AT 20
dibujar una línea horizontal en la fila 20 que abarcara la pantalla, o VLIN 5,15 AT 7
dibujar una línea vertical más corta en la columna 7. [129] A=SCRN X,Y
devolvía el color de la pantalla en X,Y. [130] [b]
Los fabricantes de hardware a menudo incluían soporte propietario para semigráficos , formas simples e iconos tratados como caracteres especiales . Algunos ejemplos incluían los gráficos de bloques del ZX-81 y los símbolos de cartas ♠, ♣, ♥ y ♦ en el conjunto de caracteres PETSCII de Commodore International . BASIC podía generar estos símbolos utilizando .PRINT CHR$();
Microsoft agregó muchos comandos gráficos a IBM BASIC : LINE
, PSET
(Pixel SET), PRESET
(Pixel RESET), GET
(almacena un rectángulo de la pantalla en una matriz), PUT
(muestra un segmento rectangular almacenado), LOCATE
(para mover el cursor de texto) y DRAW
, que dibuja formas utilizando una sintaxis similar a LOGO . Bill Gates y Neil Konzen escribieron DONKEY.BAS , un juego incluido, para demostrar los gráficos en color y el sonido del intérprete . [131]
Otra área en la que las implementaciones divergieron fue en las palabras clave para tratar con medios (casetes y disquetes), entrada de teclado y controladores de juegos (si los hay).
Dado que los intérpretes BASIC basados en ROM a menudo funcionaban como shells para cargar en otras aplicaciones, las implementaciones agregaron comandos relacionados con cintas de casete (por ejemplo, CLOAD
y CSAVE
), archivos de disco binarios (por ejemplo, BLOAD
, BSAVE
y BRUN
) y programas BASIC en disco (por ejemplo, LOAD
, SAVE
y CATALOG
). Las implementaciones de BASIC empresarial agregaron comandos para archivos de acceso aleatorio. (Incluso los intérpretes BASIC basados en ROM no fueron diseñados ni pensados para usarse como sistemas operativos, y las microcomputadoras más pequeñas simplemente carecían de cualquier sistema operativo. [132] )
Dartmouth BASIC carecía de un comando para obtener información del teclado sin pausar el programa. Para dar soporte a los videojuegos , los BASIC añadieron comandos propietarios para hacerlo: INKEY$
era una función en Microsoft BASIC que devolvía una cadena vacía si no se presionaba ninguna tecla o, en caso contrario, un solo carácter; KP
(para KeyPress ) devolvía el valor ASCII de la entrada en Astro BASIC .
El Tiny BASIC de Palo Alto carecía de cadenas pero permitía a los usuarios ingresar expresiones matemáticas como respuesta a INPUT
afirmaciones; al establecer variables, como Y=1; N=0
, el usuario podía responder “Y” o “1” o incluso “3*2-5” ante una pregunta de sí/no.
Algunos sistemas admitían controladores de juegos. Astro BASIC admitía JX()
(posición horizontal del joystick especificado), JY()
(posición vertical del joystick), KN()
(estado de la perilla) y TR()
(estado del disparador). Integer BASIC admitía un controlador de juegos , un controlador de paleta , que tenía dos controladores en un solo conector. La posición del controlador se podía leer usando la PDL
función, pasando el número del controlador, 0 o 1, como A=PDL(0):PRINT A
, devolviendo un valor entre 0 y 255. [133] [c]
El BASIC de enteros carecía de comandos de entrada/salida personalizados y también carecía de la DATA
declaración y el asociado READ
. Para introducir y extraer datos de un programa, la funcionalidad de entrada/salida se redirigía a una ranura de tarjeta seleccionada con PR#x
y IN#x
, que redirigían la salida o la entrada (respectivamente) a la ranura numerada. A partir de entonces, los datos se podían enviar a la tarjeta mediante PRINT
comandos convencionales y leer desde ella mediante INPUT
. [130] La producción de sonidos se lograba mediante PEEK
ing en la ubicación asignada en memoria de un simple "beeper", −16336. [d]
Si bien Kemeny y Kurtz conocían la programación estructurada , a través de los ejemplos de ALGOL 58 y ALGOL 60WHILE...WEND
, cuando diseñaron BASIC, adaptaron solo el bucle for, ignorando la instrucción else, el bucle while, el bucle repeat, los procedimientos nombrados, el paso de parámetros y las variables locales. Como resultado, los dialectos posteriores a menudo diferían drásticamente en la redacción utilizada para las técnicas estructuradas. Por ejemplo, (en Microsoft BASIC ), WHILE...ENDWHILE
(en Turbo-Basic XL ) DO...LOOP WHILE
e incluso WHILE
las cláusulas (ambas en BASIC-PLUS ).
De las implementaciones de Tiny BASIC, sólo National Industrial Basic Language (NIBL) ofrecía un comando de bucle de cualquier tipo. DO/UNTIL
[ 135] Esto fue a pesar de que el inventor de Tiny BASIC, Dennis Allison, lamentaba públicamente el estado de BASIC. [136]
BBC BASIC fue uno de los primeros intérpretes de microcomputadoras en ofrecer programación BASIC estructurada, con procedimientos y funciones DEF PROC
/ nombrados, bucles y estructuras inspiradas en COMAL . Los BASIC de segunda generación (por ejemplo, SBASIC (1976), BBC BASIC (1981), True BASIC (1983), Beta BASIC (1983), QuickBASIC (1985) y AmigaBASIC (1986)) introdujeron una serie de características en el lenguaje, principalmente relacionadas con la programación estructurada y orientada a procedimientos. Por lo general, la numeración de líneas se omite del lenguaje y se reemplaza con etiquetas (para GOTO ) y procedimientos para fomentar un diseño más fácil y flexible. [137] Además, se introdujeron palabras clave y estructuras para admitir la repetición, la selección y los procedimientos con variables locales.DEF FN
REPEAT UNTIL
IF THEN ELSE
El siguiente ejemplo pertenece a Microsoft QBASIC, la tercera implementación de un BASIC estructurado de Microsoft (después de Macintosh BASIC en 1984 y Amiga BASIC en 1985). [138]
Ejemplo de REM QBASICDeclaración de avance REM: permite que el código principal llame a una subrutina REM que se define más adelante en el código fuente DECLARE SUB PrintSomeStars ( StarCount! ) REM El programa principal sigue DO INPUT "¿Cuántas estrellas quieres? (0 para salir) " , NumStars CALL PrintSomeStars ( NumStars ) LOOP WHILE NumStars > 0 END Definición de subrutina REM SUB PrintSomeStars ( StarCount ) REM Este procedimiento utiliza una variable local llamada Stars$ Stars$ = STRING$ ( StarCount , "*" ) PRINT Stars$ END SUB
El soporte inicial para la programación orientada a objetos solo proporcionaba la reutilización de objetos creados con otros lenguajes, como Visual Basic y PowerBASIC, que admitían el Modelo de objetos componentes de Windows . A medida que los intérpretes de BASIC continuaron evolucionando, agregaron soporte para características orientadas a objetos, como métodos , constructores , asignación dinámica de memoria , propiedades y asignación temporal.
Las ROMs de BASIC Integer también incluían un monitor de código de máquina , un "miniensamblador " y un desensamblador para crear y depurar programas en lenguaje ensamblador . [90] [139] [140]
Una de las características únicas de BBC BASIC era el ensamblador en línea , que permitía a los usuarios escribir programas en lenguaje ensamblador para el 6502 y, más tarde, para el Zilog Z80 , NS32016 y ARM . El ensamblador estaba totalmente integrado en el intérprete de BASIC y compartía variables con él, que podían incluirse entre los caracteres [ y ], guardarse mediante *SAVE y *LOAD, y llamarse mediante los comandos CALL o USR. Esto permitía a los desarrolladores escribir no solo código en lenguaje ensamblador, sino también código BASIC para emitir lenguaje ensamblador, lo que hacía posible utilizar técnicas de generación de código e incluso escribir compiladores simples en BASIC.
Como en la mayoría de los BASIC, los programas se iniciaban con el RUN
comando y, como era común, se podían dirigir a un número de línea particular como RUN 300
. [141] La ejecución se podía detener en cualquier momento usando + [142] (o BREAK como en el TRS-80) y luego reiniciar con inue ( en Integer BASIC). [143] Aprovechando las capacidades únicas de los programas interpretados (el código se procesa en tiempo real una declaración a la vez, en contraste con los compiladores ), el usuario en la consola podía examinar datos variables usando la declaración PRINT y cambiar dichos datos sobre la marcha, para luego reanudar la ejecución del programa. CtrlCCONT
CON
Para la ejecución paso a paso, la instrucción TRON
o TRACE
se podía utilizar en el símbolo del sistema o dentro del programa mismo. Cuando se activaba, se imprimían los números de línea para cada línea que el programa visitaba. La función se podía desactivar nuevamente con TROFF
o NOTRACE
. [144]
Algunas implementaciones, como los intérpretes de Microsoft para los distintos modelos TRS-80 , incluían el comando ON ERROR GOSUB
. Este redirigiría la ejecución del programa a un número de línea específico para un manejo especial de errores.
A diferencia de la mayoría de los BASIC, Atari BASIC escaneaba la línea de programa recién ingresada e informaba los errores de sintaxis de inmediato. Si se encontraba un error, el editor volvía a mostrar la línea, resaltando el texto cerca del error en video inverso .
En muchos intérpretes, incluido Atari BASIC, los errores se muestran como códigos numéricos, con las descripciones impresas en el manual. [145] Muchos MS-BASIC usaban abreviaturas de dos caracteres (por ejemplo, SN para SYNTAX ERROR). Palo Alto Tiny BASIC y Level I BASIC usaban tres palabras para los mensajes de error: "¿QUÉ?" para los errores de sintaxis, "¿CÓMO?" para los errores de tiempo de ejecución como GOTO a una línea que no existía o desbordamientos numéricos, y "SORRY" para problemas de falta de memoria.
Mientras que el lenguaje BASIC tiene una sintaxis simple, las expresiones matemáticas no la tienen, ya que admiten diferentes reglas de precedencia para paréntesis y diferentes operadores matemáticos. Para admitir dichas expresiones es necesario implementar un analizador descendente recursivo . [146]
Este analizador se puede implementar de varias maneras:
La variedad de decisiones de diseño que se tomaron al programar un intérprete BASIC a menudo se revelaron a través de diferencias de rendimiento.
Las implementaciones de gestión de línea a menudo afectaban el rendimiento y normalmente utilizaban la búsqueda lineal . Delimitar cada línea con un CR haría que un GOTO o GOSUB a una línea posterior tomara más tiempo, ya que el programa necesitaría iterar sobre todas las líneas para encontrar el número de línea de destino. En algunas implementaciones, como Atari BASIC, la longitud de cada línea se registraba y almacenaba después del número de línea, de modo que el programa no tuviera que escanear cada carácter de la línea para encontrar el siguiente retorno de carro. Muchas implementaciones siempre buscarían un número de línea al que ramificarse desde el inicio del programa; MS-BASIC buscaría desde la línea actual, si el número de línea de destino era mayor. Pittman agregó un parche a su 6800 Tiny BASIC para usar una búsqueda binaria. [148]
Trabajar únicamente con matemáticas de números enteros proporciona otro gran impulso en velocidad. Como muchos benchmarks de computadoras de la época eran pequeños y a menudo realizaban matemáticas simples que no requerían punto flotante, Integer BASIC superó a la mayoría de los otros BASIC. [e] En uno de los primeros benchmarks de microcomputadoras conocidos, los benchmarks Rugg/Feldman , Integer BASIC fue más del doble de rápido que Applesoft BASIC en la misma máquina. [150] En Byte Sieve , donde las matemáticas eran menos importantes pero el acceso a matrices y el rendimiento de bucles dominaban, Integer BASIC tomó 166 segundos mientras que Applesoft tomó 200. [151] No apareció en el Creative Computing Benchmark , que se publicó por primera vez en 1983, momento en el que Integer BASIC ya no se suministraba por defecto. [152] La siguiente serie de pruebas, tomada de ambos artículos originales de Rugg/Feldman, [150] [149] muestra el rendimiento de Integer en relación con el BASIC derivado de MS en la misma plataforma.
En teoría, el BASIC de Atari debería haber funcionado más rápido que los BASIC contemporáneos basados en el patrón de Microsoft. Debido a que el código fuente está completamente tokenizado cuando se ingresa, todos los pasos de tokenización y análisis ya están completos. Incluso las operaciones matemáticas complejas están listas para ejecutarse, con cualquier constante numérica ya convertida a su formato interno de 48 bits, y los valores de las variables se buscan por dirección en lugar de tener que buscarlos. A pesar de estas ventajas teóricas, en la práctica, el BASIC de Atari es más lento que otros BASIC de computadora doméstica , a menudo por una cantidad grande. [153] En la práctica, esto no se confirmó. En dos pruebas de referencia ampliamente utilizadas de la época, Sieve of Eratosthenes de la revista Byte y la prueba de referencia Creative Computing escrita por David H. Ahl , el Atari terminó cerca del final de la lista en términos de rendimiento, y fue mucho más lento que el Apple II contemporáneo o el Commodore PET , [154] a pesar de tener la misma CPU pero ejecutándola aproximadamente al doble de velocidad que cualquiera de ellos. Quedó detrás de máquinas relativamente lentas como la Sinclair ZX81 e incluso de algunas calculadoras programables. [155]
La mayor parte de la lentitud del lenguaje se debía a tres problemas. [153] El primero era que las rutinas matemáticas de punto flotante estaban mal optimizadas. En la prueba comparativa de Ahl, una operación de exponente único, que recorre internamente la función de multiplicación lenta, era responsable de gran parte del pobre desempeño de la máquina. [153] En segundo lugar, la conversión entre el formato de punto flotante interno y los enteros de 16 bits utilizados en ciertas partes del lenguaje era relativamente lenta. Internamente, estos enteros se utilizaban para números de línea e indexación de matrices, junto con algunas otras tareas, pero los números en el programa tokenizado siempre se almacenaban en formato decimal codificado en binario (BCD). [156] Siempre que se encuentra uno de estos, por ejemplo, en el número de línea en GOTO 100
, el valor BCD tokenizado tiene que convertirse a un entero, una operación que puede tardar hasta 3500 microsegundos. [157] Otros BASIC evitaron este retraso convirtiendo en mayúsculas y minúsculas especiales los números que solo podían ser enteros, como el número de línea que sigue a un GOTO
, cambiando a código ASCII a entero especial para mejorar el rendimiento. En tercer lugar, Atari BASIC implementó ramificaciones y FOR
bucles. Para realizar una ramificación en un GOTO
o GOSUB
, el intérprete busca en todo el programa el número de línea coincidente que necesita. [158] Una pequeña mejora encontrada en la mayoría de los BASIC derivados de Microsoft es comparar el número de línea de destino con el número de línea actual y buscar hacia adelante desde ese punto si es mayor, o comenzar desde arriba si es menor. Esta mejora faltaba en Atari BASIC. [153] A diferencia de casi todos los demás BASIC, que empujaban un puntero a la ubicación del FOR
en una pila, de modo que cuando llegaba al NEXT
podía regresar fácilmente al de FOR
nuevo en una sola operación de ramificación, Atari BASIC empujaba el número de línea en su lugar. Esto significaba que cada vez NEXT
que se encontraba a, el sistema tenía que buscar en todo el programa para encontrar la FOR
línea correspondiente. Como resultado, cualquier bucle en un programa BASIC de Atari causa una gran pérdida de rendimiento en relación con otros BASIC. [153]
A=SCRN(X,Y)
.de aspectos positivos: Visual Basic es fácil de aprender y está ampliamente disponible.
Debido a que TA es tan grande (19 703 bytes), descubrí que la ejecución se volvía insoportablemente lenta, simplemente debido al escaneo de memoria para GOTO, GOSUB y RETURN. Un parche simple para el intérprete lo convierte en un
algoritmo de búsqueda binaria
, para una aceleración de aproximadamente un orden de magnitud en el tiempo de ejecución. Los cambios necesarios se enumeran en el Apéndice.
Código fuente y documentos de diseño, en orden cronológico del lanzamiento de las implementaciones BASIC: