BASIC-PLUS es un dialecto extendido del lenguaje de programación BASIC que fue desarrollado por Digital Equipment Corporation (DEC) para su uso en su sistema operativo de tiempo compartido RSTS/E para la serie PDP-11 de minicomputadoras de 16 bits a principios de la década de 1970 y hasta la de 1980.
BASIC-PLUS se basó en BASIC-8 para el TSS/8 , [1] a su vez basado en gran medida en el BASIC Dartmouth original . BASIC-PLUS agregó una serie de nuevas estructuras, así como características de JOSS relacionadas con las sentencias condicionales y el formato. A su vez, BASIC-PLUS fue la versión en la que se basó el BASIC original de Microsoft . [2]
Entre las novedades que se hicieron en BASIC-PLUS, cabe destacar la introducción de funciones de cadena como MID$ y LEFT$ , además del comando CHANGE original de Dartmouth, que servía para todo tipo de operaciones . En versiones posteriores del lenguaje, en particular en Microsoft, se eliminó CHANGE y las funciones de cadena de BASIC-PLUS se convirtieron en las únicas formas de realizar este tipo de operaciones. La mayoría de los BASIC actuales siguen esta convención.
El lenguaje fue reescrito posteriormente como un compilador verdadero como BASIC-Plus-2 y fue portado a la plataforma VAX-11 como la implementación BASIC nativa de esa máquina. Esta versión sobrevivió a varios cambios de plataforma y hoy se conoce como VSI BASIC para OpenVMS .
Los usuarios se sentaban frente a una terminal y escribían instrucciones en lenguaje de programación. Las instrucciones podían ingresarse directamente en el intérprete de comandos del sistema o ingresarse en un editor de texto , guardarse en un archivo y cargarse en el intérprete de comandos desde el archivo. Los errores en el código fuente se informaban al usuario inmediatamente después de que se escribía la línea.
Como no se podía garantizar la existencia de un terminal inteligente con control del cursor, BASIC-PLUS utilizó el sistema común de anteponer a todo el código fuente un número de línea. El código se editaba escribiendo el número y luego modificando el contenido del código siguiente. Se podía eliminar una línea de código escribiendo su número de línea y nada más, con lo que se convertía en una línea vacía.
El espacio de direcciones virtuales de un usuario de RSTS/E estaba limitado a un poco menos de 64 KB de espacio. Con BASIC-PLUS, aproximadamente la mitad de este espacio de direcciones virtuales era utilizado por el intérprete de comandos y la biblioteca de tiempo de ejecución combinados (denominados Run Time System en RSTS/E). Esto limitaba los programas de usuario a unos 32 KB de memoria.
Los programas grandes se dividían en partes ejecutables independientes mediante el uso de la CHAIN
instrucción, y los programas podían encadenarse a números de línea específicos en un programa secundario para indicar que un programa debía comenzar su ejecución en un punto diferente de su primera línea. Esta característica de encadenamiento a un cierto número de línea permitía que los programas se indicaran entre sí que estaban siendo llamados desde otro programa. El uso de una sección de memoria compartida llamada núcleo común también permitía que los programas se pasaran datos entre sí según fuera necesario. También se podían utilizar archivos de disco , pero eran más lentos.
Para conservar la memoria, el sistema incluyó un administrador de memoria recolector de basura, utilizado tanto para datos de cadena como para código de bytes.
Un programa en ejecución podría interrumpirse, examinar y modificar variables y luego reanudarse.
BASIC-PLUS se basa en versiones posteriores de Dartmouth BASIC , incluidos sus potentes MAT
comandos. Además, DEC agregó una serie de estructuras de control de flujo únicas.
Los números de línea eran números enteros positivos de 1 a 32767. [3] Las líneas lógicas de código podían continuar en múltiples líneas físicas utilizando un avance de línea al final de una línea en lugar del carácter normal de retorno de carro . [4] Para facilitar la edición externa del archivo fuente, las versiones posteriores de BASIC-PLUS también permitían el &
carácter como un carácter de continuación de línea.
Se podían colocar varias declaraciones en una sola línea usando :
como separador de declaraciones. [4] El sistema permitía usar tabulaciones como espacios en blanco en línea y se usaba para hacer que los bucles fueran más claros, como en los lenguajes modernos. [5] Los comentarios usaban la REM
palabra clave o el !
carácter, [6] a diferencia de MS BASIC, que usaba REM
y '
.
El PRINT
comando dividía la pantalla en regiones de 14 espacios de ancho, y se usaba la coma para moverse entre estas ubicaciones; PRINT 1,2,3
generaba 1, 2 y 3 de manera espaciada, [7] mientras que PRINT 1;2;3
dejaba un solo espacio y producía "1 2 3". [8] [a] INPUT
permitía especificar una cadena de solicitud, pero usaba el punto y coma para separarla en lugar de la coma; . [9]INPUT "WHAT IS THE VALUE";A
Las cadenas se podían delimitar con comillas simples o dobles. [10] Además de las funciones CHR
y ASCII
que convertían caracteres individuales a y desde formato de cadena, [11] BASIC-PLUS también admitía el comando de Dartmouth CHANGE
. CHANGE
iteraba la cadena y devolvía el valor ASCII de cada carácter como una ranura en una matriz numérica. Por ejemplo, CHANGE 'HELLO' TO X
devolvería una matriz con los cinco códigos ASCII, 110, 105, 114, 114, 105, en los elementos 1 a 5, y el número 5, la longitud de la cadena, en el elemento 0. [12] También se podría invertir la operación, CHANGE X TO A$
leer los números individuales en la matriz X y convertirlos en una cadena. [13]
BASIC-PLUS agregó el concepto de "modificadores de sentencia", condiciones similares a JOSS que se podían aplicar a cualquier sentencia. Por ejemplo, es el equivalente de [14] También se proporcionó lo opuesto, era el equivalente de . [15]PRINT I IF I <> 10
IF I <> 10 THEN PRINT I
PRINT I UNLESS I = 10
IF I <> 10 THEN PRINT I
FOR
Los bucles funcionaban como en otras versiones de BASIC y NEXT
no se podía usar el comando en una expresión para salir antes de tiempo. [16] En cambio, se podían usar las palabras clave UNTIL
and WHILE
para controlar las salidas antes de tiempo. Por ejemplo, continuar el bucle hasta que I=10, con la suposición de que el código siguiente establecería el valor de I, [17] lo que significa que podría no salir después de 10 iteraciones, sino tan pronto como el código estableciera I en 10. [18] También se podían usar modificadores para construir bucles compactos de una línea, por ejemplo, se realizaría un bucle hasta que X fuera 100. [19]FOR I=1 UNTIL I=10
X=X+1 WHILE X<100
Los nombres de las variables en las primeras versiones de BASIC-PLUS podían ser de una sola letra o de una sola letra seguida de un solo dígito. [5] Con la inclusión del "modo Extend" en versiones posteriores, los nombres de las variables podían tener hasta 29 caracteres de longitud, y se añadió el punto (.) como carácter permitido. Todos los nombres de variables todavía tenían que empezar con una letra. [b] Como en la mayoría de las versiones de BASIC, la LET
palabra clave, para la asignación de variables, era opcional. Podía asignar un único valor a varias variables, como . [20]LET A,B,C=10
El lenguaje admitía tres tipos de datos: números de punto flotante, números enteros y cadenas. Las variables sin sufijo eran de punto flotante (8 bytes, rango 0,29 × 10−38 a 1,7 × 1038 , hasta 16 dígitos de precisión). Las variables enteras (16 bits, rango −32768 a +32767) se indicaron con un%
sufijo, [21] las variables de cadena (longitud variable) se indicaron con un$
sufijo. [10]
La lista de operadores matemáticos y lógicos era típica de la mayoría de los BASIC, con algunas extensiones. Para matemáticas, se admitían , , , y , junto con +
como -
forma *
alternativa /
de para terminales de computadora que podrían no tener ese carácter. Las comparaciones lógicas estándar eran , , , , y . Una adición interesante fue el operador, para "aproximadamente igual". Este devolvería verdadero si los dos números se imprimieran de la misma manera, es decir, sus seis dígitos más significativos fueran los mismos. [22] Los operadores lógicos incluían los típicos , y , junto con , que devuelve verdadero si tanto A como B son verdaderos o ambos son falsos, y que es falso si A es verdadero y B es falso y, en caso contrario, siempre verdadero. [23]^
**
^
=
<
>
<=
>=
<>
==
NOT A
A AND B
A OR B
A XOR B
A EQV B
A IMP B
La DIM
instrucción podía asignar matrices unidimensionales y bidimensionales de cualquiera de los tres tipos de datos. El rango de subíndices siempre comenzaba con 0 (pero MAT
las instrucciones no establecían elementos en la fila 0 o la columna 0). [24] [25]
El lenguaje también incluía una serie de MAT
comandos para trabajar con la matriz completa (o MATrix). El MAT READ
comando llenaría la matriz con valores en una DATA
declaración, [26] MAT INPUT
llenaría la matriz con valores escritos por el usuario e MAT PRINT
imprimiría los elementos en un formato unidimensional o bidimensional. [27] MAT
también se podía utilizar para establecer valores predeterminados en una matriz utilizando palabras clave asociadas, por ejemplo, MAT A=ZER
llenaría la matriz A con ceros. [28] TRN
transpondría una matriz completa y INV
la invertiría. [29] Además, +
, -
, y *
se podían utilizar en matrices, realizando la operación matricial asociada. [30]
La DIM#
sentencia "virtual DIM" podía asignar "arreglos de datos virtuales" o "arreglos virtuales" a un archivo de disco, lo que permitía arreglos más grandes que la memoria disponible de la computadora (o incluso su espacio de direcciones), y permitía el uso de elementos de arreglo para leer, escribir y extender archivos de disco (almacenamiento persistente). Llamaron a esta disposición "almacenamiento de datos virtuales" y "núcleo virtual", pero no utilizaba el enfoque moderno de asignar los arreglos y un archivo asignado a la memoria . En su lugar, se utilizaba un único búfer para almacenar 512 bytes de datos a la vez, y cuando se accedía a una entrada en el arreglo virtual, se leían los datos correspondientes y se escribían los datos antiguos, según fuera necesario. La CLOSE
sentencia hacía que se volviera a escribir el búfer (si era necesario) antes de cerrar el archivo. Debido a que no se almacenaban en caché sectores adicionales, acceder a los datos en el orden "incorrecto" podía multiplicar la cantidad de accesos al disco. Se impusieron reglas adicionales a los arreglos virtuales, de modo que un dato nunca podía abarcar un límite de registro: cada tipo de datos se alineaba a un múltiplo de su tamaño. Las cadenas virtuales se almacenaron como datos ASCIIZ de longitud fija, con tamaños restringidos a 2, 4, 8, 16, 32, 64, 128, 256 o 512 bytes, y se accedió a ellas utilizando LSET
y RSET
. [31]
BASIC-PLUS no era un intérprete sino un sistema de compilación y ejecución : cada línea de BASIC se traducía a "PPCODE" (Push-Pop Code) a medida que se ingresaba, para su posterior ejecución rápida en su máquina virtual. Estas traducciones no tokenizaban las líneas de BASIC sino que las reescribían para su uso en una máquina de pila; no se podían traducir estas representaciones de nuevo a instrucciones BASIC. Esto evitaba la necesidad de decodificar repetidamente las palabras clave como cadenas: una vez convertidas a PPCODE, las palabras clave eran números que apuntaban a rutinas para ejecutar esa función. BASIC-PLUS incluía un COMPILE
comando, pero no era un compilador verdadero; simplemente guardaba la representación PPCODE del programa para que no tuviera que volver a compilarse la próxima vez que se cargara el programa BASIC en la memoria. El sistema almacenaba el programa de un usuario en dos formatos. Uno era el código fuente editable en formato de texto, creado utilizando el SAVE
comando y normalmente colocado en un archivo .BAS. El otro era la versión PPCODE del programa creado por el COMPILE
comando y guardado en un archivo .BAC; Los archivos .BAC eran más pequeños y se cargaban y ejecutaban más rápido, pero no se podían editar. [32]
Posteriormente, DEC desarrolló un producto relacionado llamado Basic Plus 2 ("BP2" o BASIC-Plus-2 ) para añadir funciones adicionales y aumentar el rendimiento.
Utilizaba una compilación real en código enhebrado y escribía su salida en archivos de objetos compatibles con los archivos de objetos de código de máquina producidos por el ensamblador y otros sistemas de lenguaje. Estos archivos de objetos se podían guardar en bibliotecas. Un enlazador (el TKB, también conocido como el constructor de tareas) creaba entonces archivos ejecutables a partir de los archivos de objetos y las bibliotecas. El TKB también admitía superposiciones; esto permitía intercambiar rutinas individuales en el espacio de direcciones virtuales según fuera necesario, superponiendo rutinas que no se estaban utilizando en ese momento.
Además, los programas BP2 se ejecutaban bajo el sistema de tiempo de ejecución RSX; este RTS sólo ocupaba 8 KB del espacio de dirección virtual del usuario, dejando 56 KB para el programa del usuario. [33] (La versión 9 de RSTS/E introdujo un espacio separado para instrucciones y datos, y el "desaparecido" sistema de tiempo de ejecución RSX, que permitía hasta 64 KB de código de instrucción y datos). Estos dos factores permitieron que los programas BP2 individuales fueran mucho más grandes que los programas BASIC-PLUS, reduciendo a menudo la necesidad de encadenar varios programas.
A diferencia de BASIC-PLUS (que sólo estaba disponible en RSTS/E), BP2 también estaba disponible para el sistema operativo RSX-11 . Los programas BP2 también eran más compatibles con el posterior VAX BASIC .
Microsoft BASIC se basó en BASIC-PLUS. [2] Las versiones anteriores de MS BASIC, la serie 1.x, carecían de variables enteras, pero estas se agregaron en la serie 2.x que se encontró en muchas máquinas, incluidos los modelos posteriores de Commodore PET y Commodore 64. La capacidad de colocar comandos lógicos y de bucle en línea, como I = I + 1 UNTIL I = 10
no fue copiada y no aparece en ninguna versión común de BASIC para microcomputadoras. MS BASIC también carecía de los comandos matriciales.
FOR I=STOP
se interpretarían como .FOR I = S TO P