Articulo de referencia

SUPERBÁSICO

SUPER BASIC , a veces llamado SBASIC para abreviar, es un dialecto avanzado del lenguaje de programación BASIC que se ofrecía en los sistemas SDS 940 de Tymshare a partir de 196...

SUPER BASIC , a veces llamado SBASIC para abreviar, es un dialecto avanzado del lenguaje de programación BASIC que se ofrecía en los sistemas SDS 940 de Tymshare a partir de 1968 y que estuvo disponible hasta bien entrada la década de 1970.

Al igual que el Dartmouth BASIC en el que se basaba, SUPER BASIC era un lenguaje de compilación y ejecución , a diferencia de un intérprete . Además de ofrecer la mayoría de los comandos y funciones de Dartmouth BASIC Versión 4, incluidos los comandos de matemáticas matriciales, SUPER BASIC también incluía una serie de características del lenguaje JOSS fundamental desarrollado en Rand Corporation , [ 1 ] a través de la versión de Tymshare, CAL , y añadía una variedad de nuevas funciones, números complejos como tipo incorporado y soporte para doble precisión .

SUPER BASIC también mejoró notablemente el manejo de cadenas de caracteres con respecto al sistema rudimentario de Dartmouth, introduciendo las funciones de cadena LEFT`,` MIDy `,`, la concatenación simple de cadenas y otras características. Estas se utilizaron posteriormente en BASIC-PLUS de DEC , que a su vez sirvió de base para el Microsoft BASIC original , que tuvo un uso generalizado en la década de 1980.RIGHT

Historia

El Dartmouth BASIC original se lanzó en 1964, pero en aquel entonces era en gran medida experimental. Pasó por varias revisiones antes de volverse realmente útil con la Cuarta Edición, cuando se adaptó a la máquina GE 635 y se publicó en 1968. Dartmouth específicamente puso el diseño subyacente en el dominio público, para que cualquiera pudiera adaptarlo a sus plataformas y llamarlo BASIC. Su difusión se vio favorecida además por los incansables esfuerzos de sus autores para promocionarlo. Sin embargo, como el código fue diseñado para ejecutarse en el sistema operativo DTSS , se requirió cierta adaptación para ejecutarlo en sistemas de producción. Esto dio lugar a una proliferación de versiones con pequeñas diferencias. [ 2 ]

Tymshare se formó dentro de la Universidad de California, Berkeley , alquilando inicialmente tiempo en las computadoras de la Universidad fuera del horario lectivo. El BASIC original de Tymshare, simplemente Tymshare BASIC, se basaba en código fuente "de otra parte" de la Universidad, [ 3 ] que Dan Lewis comenzó a mejorar. Frank Bracher añadió las rutinas para la entrada/salida de archivos (E/S), lo que lo hizo mucho más práctico que el código original de Dartmouth, que dependía únicamente de DATAinstrucciones integradas en el programa. El flujo de trabajo de Dartmouth se basaba en cintas, por lo que cargar y guardar archivos individuales no era práctico y la E/S directa no se abordó hasta versiones posteriores. El código de E/S de Bracher se había desarrollado originalmente para la oferta SUPER FORTRAN de Tymshare . [ 2 ]

Una característica frecuentemente mencionada del sistema era la documentación, escrita por Caroline Diehl. Los manuales estaban escritos en un estilo conversacional. [ 3 ]

Tymshare mantuvo SUPER BASIC durante la década de 1970, pero a medida que el mercado de servicios de programación de tiempo compartido de alquiler disminuyó, el sistema entró en mantenimiento y Lewis y Bracher se marcharon para ofrecer servicios de consultoría de SUPER BASIC a las empresas que aún lo utilizaban. El mantenimiento dentro de Tymshare pasó principalmente a Walter Main. [ 3 ]

Tymshare solicitó el registro de la marca SUPER BASIC el 7 de enero de 1970 y lo renovó el 17 de octubre de 1977, convirtiéndose en propiedad de McDonnell Douglas en 1984 cuando la empresa adquirió Tymshare. [ 3 ]

Idioma

Modo directo e indirecto

Al igual que la mayoría de los sistemas BASIC de la época, SUPER BASIC tenía un único editor de línea de comandos que funcionaba tanto como lenguaje interactivo como editor de programas. Los comandos que se escribían sin número de línea se ejecutaban inmediatamente, lo que se denominaba " modo directo ". [ a ] Si la misma línea iba precedida de un número de línea, se copiaba en el área de almacenamiento del código del programa, lo que se conocía como "modo indirecto". Se añadían nuevas líneas al programa si el número de línea era único, se reemplazaban las líneas existentes con el mismo número o se eliminaban del programa si se escribía un número de línea existente sin ningún código que le siguiera. [ 4 ]

Declaraciones del programa

Los números de línea iban del 0 al 999999. [ 5 ] El DELETE(o forma abreviada DEL) se podía usar para eliminar un rango de líneas usando LISTla notación típica, por ejemplo, DELETE 5,10-50. [ 4 ] El ENTERcomando iniciaba un sistema automático de numeración de líneas. Tomaba dos parámetros opcionales, un número de línea inicial y un paso, separados por BY. Se asumía que el número inicial era cero si no se proporcionaba, y el paso era 10. Por ejemplo, ENTERproduciría 0,10,20,..., ENTER BY 5produciría 0,5,10,..., y ENTER 10 BY 10produciría 10,20,30... [ 6 ]RENUMBER tomaba tres parámetros, un nuevo número de línea inicial, un rango de líneas para renumerar (como 20-100) y el paso. [ 7 ]

Aunque el editor integrado solo cargaba y guardaba las líneas del programa, el usuario podía editar el archivo de texto resultante para añadir comandos adicionales que se ejecutarían en modo directo. Un ejemplo común era editar un programa y añadir una RUNlínea aparte al final del archivo. Al cargarse, el sistema detectaba la línea RUNy compilaba e iniciaba el programa inmediatamente. [ 8 ] Esto es inusual en los sistemas BASIC, aunque era de uso común en JOSS.

Declaraciones

En consonancia con el concepto general de Dartmouth BASIC , SUPER BASIC era un sistema de compilación y ejecución que compilaba el código fuente cuando se ejecutaba el programa. SUPER BASIC tenía dos comandos para esto, el típico RUNque se ve en la mayoría de los BASIC, así como STARTque hacía lo mismo. [ 9 ] Se podían colocar comentarios en cualquier lugar usando !. [ 10 ]

SUPER BASIC amplió la FORinstrucción de varias maneras. Un cambio menor fue permitir BYen lugar de STEP, y permitió que el paso se colocara al final como en la mayoría de los BASIC, o en el medio como en JOSS y otros lenguajes. Por lo tanto, y eran ambos válidos. [ 11 ] Además, SUPER BASIC proporcionó formas alternativas de la definición de rango usando y , mientras que la mayoría de los otros lenguajes usaban estructuras de bucle completamente separadas para estos. Por ejemplo, continuará mientras X<Y, mientras que se detiene cuando se cumple la condición. [ 12 ] Como en Microsoft BASIC , varios bucles podían terminar con un solo , [ 12 ] aunque no incluía la característica de versiones posteriores de MS donde la variable de índice podía omitirse por completo. Finalmente, al estilo de JOSS, se podía reemplazar el especificador de rango típico con una lista explícita de valores, . [ 13 ]FORI=1TO10BY2FORI=1BY2TO10WHILEUNTILFORX=1WHILEX<YFORX=1UNTILX<YNEXT I,J1 TO 10FORI=1,4,5,6,10

Un cambio más importante, siguiendo el modelo JOSS, fue el concepto de "modificadores de sentencia" que permitían colocar un IFor después de la sentencia que controlaban. Por ejemplo, es equivalente a . Esto puede hacer que algunos casos de uso comunes sean más fáciles de entender. [ 14 ] También incluía el azúcar sintáctico que era un con el sentido opuesto; por ejemplo, . También se podía usar un bucle en estos casos, lo que hacía que los bucles de una sola sentencia fueran fáciles de implementar, por ejemplo . [ 15 ] También se podía usar un "bare" o sin el for, . Los modificadores también se podían agrupar, . [ 16 ]FORPRINT"IT IS"IFX=5IFX=5THENPRINT"IT IS"UNLESSIFPRINT"IT IS NOT FIVE"UNLESSX=5PRINTXFORX=1TO10WHILEUNTILX=X+2UNTILX>10PRINT"YES"IFA=BUNLESSN=0

Expresiones

Variables

Los nombres de las variables podían constar de una o dos letras, o de una letra y un dígito. SUPER BASIC no requería que las variables tuvieran un tipo específico; una variable podía contener un número en un momento dado y una cadena de caracteres en otro, como consecuencia de su forma de almacenamiento. Esto obligaba al sistema a comprobar el tipo de variable en tiempo de ejecución, INPUTpor PRINTejemplo, lo que reducía el rendimiento. Esto podía solucionarse declarando explícitamente el tipo de variable mediante diversos comandos. [ 17 ]

En la mayoría de los dialectos de BASIC, las variables se crean sobre la marcha a medida que se encuentran en el código y, por lo general, se inicializan a cero (o a la cadena vacía) al crearse. Esto puede generar problemas cuando se supone que las variables se inicializan mediante código previo que no se llama correctamente, pero en tiempo de ejecución puede ser difícil saber si 0 es un valor no inicializado o uno con los valores 0 perfectamente válidos. SUPER BASIC solucionó esto con el VARcomando. Existían dos formas principales: una VAR=ZEROque hacía que todas las variables no definidas obtuvieran automáticamente el valor cero al acceder a ellas, que es el patrón normal de BASIC, y VAR=UNDEFotra que, en cambio, provocaba un error de "VARIABLE NO TIENE VALOR" cuando se intentaba acceder a su valor con una variable no vista previamente. Esta última es muy útil en escenarios de depuración , donde el comportamiento normal puede ocultar el hecho de que una variable utilizada en un cálculo no se ha inicializado correctamente. [ 18 ]

Numérico

Salvo que se especifique lo contrario, las variables se almacenaban en un formato de punto flotante de precisión simple de 48 bits con once dígitos de precisión. También se podía definir explícitamente una variable como , que era el formato de precisión simple. Esto no se tenía en cuenta en otros BASIC, donde algún tipo de sufijo, como , indicaba el tipo dondequiera que apareciera. [ 17 ]REAL A$

Cuando sea necesario, se puede usar un formato de doble precisión con diecisiete dígitos, almacenado en tres palabras de 24 bits en lugar de dos, declarando una variable con DOUBLE A. [ 19 ] Un valor o expresión de precisión simple existente se puede convertir a doble usando la DBL(X)función. Por ejemplo, se puede forzar a que una expresión se evalúe usando doble precisión usando DBL(10+20). [ 20 ]

Asimismo, se podría declarar INTEGER Ala producción de un valor entero de 24 bits de una sola palabra. [ 17 ]

Una adición más inusual fue el soporte directo para números complejos . Estos se configuraron de manera similar a otras variables, utilizando COMPLEX I,Jpara reservar dos espacios de precisión simple. Cuando se encontraban en programas, otras instrucciones como INPUTactivaban modos alternativos que solicitaban dos números en lugar de uno, con modificaciones similares a READ(utilizado con DATAinstrucciones) PRINTy otros. Se podía crear un único número complejo a partir de dos números simples utilizando la CMPLX(X,Y)función, mientras que REAL(I)y IMAG(I)extraían las partes real e imaginaria, respectivamente, en números simples. También se ofrecieron algunas funciones de utilidad adicionales. [ 21 ]

Operadores y funciones

Había siete operadores matemáticos básicos: [ 22 ]

  • Para los exponentes, el exponente se convierte a un entero de 12 bits.
  • *para la multiplicación
  • /para división
  • MODpara módulo, el resto de una división entera
  • DIVpara la división entera
  • +para añadir
  • -para resta

La lista de funciones matemáticas de SUPER BASIC era más larga que la de la mayoría de los BASIC, incluyendo una serie de funciones trigonométricas inversas y logaritmos para base 2 y 10. [ 22 ]

RND ( X ), devuelve un número aleatorio usando una secuencia fija , se puede inicializar con RND ( -1 ) ABS ( N ), valor absoluto SQR ( N ) o SQRT ( N ), raíz cuadrada SIN COS TAN ASIN ACOS ATN o ATAN ATN / ATAN con dos variables , ( y , x ) calcula y / x y devuelve el ATN de ese SINH COSTH TANH LOG LGT / LOG10 LOG2 EXP EXP2 INT , como en BASIC , siempre trunca hacia abajo FIX , similar a INT pero simplemente trunca el decimal ROUND , redondea el valor al más cercano , a diferencia de INT COMP ( X , Y ) COMPare , combina una resta y SGN , por lo que si X > Y = 1 , X = Y = 0 , X < y + -1 PDIF ( X , Y ) Positive DIFference , devuelve la diferencia ( X - Y ) si X > Y , 0 en caso contrario

SUPER BASIC también incluía varias funciones de JOSS: [ 23 ]

IP (), Parte entera , equivalente a INT FP (), Parte fraccionaria , igual que X - INT ( X ) MAX ( ... ) devuelve el valor máximo de una lista de entradas MIN ( ... ) devuelve el mínimo

Matrices y matemáticas matriciales

Además de las operaciones matemáticas básicas, SUPER BASIC incluía funcionalidad de matrices como muchas otras implementaciones de BASIC. Se podía DIM A(5,5)crear una matriz bidimensional y, como consecuencia de la forma en que se almacenaban, todas las variables que no estaban declaradas se declaraban con diez índices, por lo que se podía hacer LET B(5)=20sin declarar previamente B. [ 24 ]

A diferencia de otros BASIC, SUPER BASIC permitía definir el rango de una o ambas dimensiones, asumiendo 1 si no se definía. Así, en el ejemplo anterior, A tiene índices del 1 al 5, pero también se podría DIM A(-5:5,0:5)generar una matriz con 11 índices, desde -5 hasta +5 para X, y desde 0 hasta +5 para Y. También se podía usar el BASEcomando para cambiar el valor predeterminado; BASE 0por ejemplo, hace que todas las dimensiones comiencen en 0. [ 24 ]

Además de estos conceptos básicos tradicionales, SUPER BASIC también incluía la mayoría de las funciones de cálculo matricial presentes en versiones posteriores de Dartmouth BASIC. Estas se activaban añadiendo la palabra clave MATdelante de otros comandos. Por ejemplo, MAT A=B*Cmultiplica todos los elementos de la matriz B por su elemento correspondiente en C, mientras que MAT A=B*5multiplica todos los elementos de B por 5. Se incluyeron funciones para operaciones matriciales comunes como la inversión y la identidad. [ 25 ]

Matemáticas binarias y valores lógicos

Como en la mayoría de las versiones de BASIC, SUPER BASIC incluía el conjunto estándar de operadores de comparación, =, <>, >=, <=, >y <, así como los operadores booleanos OR, ANDy NOT. Además, #podía usarse como una forma alternativa de <>, una forma que se encontraba en varias implementaciones de BASIC en esa época. [ 14 ] SUPER BASIC también añadió XOR, EQVpara "equivalencia" (igual) y IMPpara "implicación". [ 26 ]

A este conjunto básico, SUPER BASIC también agregó tres nuevos comandos para comparar pequeñas diferencias entre números: >>, <<y =#. Los operadores mucho mayor que y mucho menor que comparaban los valores de los dos operandos, por ejemplo, A y B en la expresión A >> B. Si al sumar B a A A se obtiene A sin cambios después del redondeo inherente, >>devolvía verdadero. Internamente, esto se realizaba mediante . , el operador casi igual, simplemente comparaba ambos valores con una metavariable interna, , realizando . [ 14 ]IFA=A-B=#EPSABS(A/B-1)<EPS

La mayoría de los dialectos de BASIC permiten almacenar el resultado de dichas comparaciones lógicas en variables, utilizando algún formato interno para representar el valor lógico, a menudo 0 para falso y 1 o -1 para verdadero. SUPER BASIC también lo permitía, lo que resultaba en el comportamiento algo confuso de , que, siguiendo la precedencia de operadores, asigna 5 a B y luego devuelve verdadero o falso si A=B. SUPER BASIC también añadió variables lógicas verdaderas, declaradas de forma similar a las de tipo double o complex, utilizando , y otras variables podían transmitirse a valores lógicos utilizando . [ 27 ]LETA=B=5LOGICAL AL()

A diferencia de las comparaciones y operadores lógicos, SUPER BASIC también añadió varios operadores lógicos bit a bit. Estos aplicaban una operación lógica básica a los bits individuales de una palabra. Entre ellos se incluían BAN, BORy BEX, para AND, OR y OR exclusivo . Otras funciones incluyen LSH(X)y RSH(X)para el desplazamiento de bits a la izquierda y a la derecha, respectivamente. Para facilitar la introducción de valores binarios, las constantes podían introducirse en formato octal [ b ] anteponiendo una "O" al número, como . [ 28 ]LETA=O41

Instrumentos de cuerda

SUPER BASIC permitía encerrar las constantes de cadena (literales) entre comillas simples o dobles, por lo que se podía usar PRINT "HELLO, WORLD!"o PRINT 'HELLO, WORLD!'. [ 29 ]

A diferencia de los dialectos posteriores de BASIC, se podía asignar una cadena a cualquier variable y $no se utilizaba el significante, por lo que A="HELLO, WORLD!"era válida. Esto podía generar cierta confusión cuando un usuario proporcionaba un valor que combinaba dígitos y letras, y SUPER BASIC asumía que cualquier cosa que comenzara con un dígito era un número. Para guiar al sistema cuando esto pudiera resultar en una entrada confusa, se podían declarar explícitamente variables de cadena usando STRING A. Al igual que con todas las variables en SUPER BASIC, estas podían ser arreglos, STRING A(5). Además, SUPER BASIC agregó la instrucción adicional TEXTque tomaba un segundo parámetro para definir la longitud de los elementos de la cadena, por lo que TEXT A(12):10crea un arreglo con 12 elementos de 10 caracteres cada uno, mientras que TEXT B(5:10):15es un arreglo de seis elementos, 5..10, cada uno de 15 caracteres de longitud. [ 30 ]

Operadores y funciones de cadena

SUPER BASIC incluía operadores para =comparación y +concatenación. Incluía las siguientes funciones: [ 31 ]

ASC(S), devuelve el número ASCII del primer carácter de la cadena. CHAR(N), devuelve una cadena con un solo carácter ASCII, igual que MS CHR(). COMP(A,B), compara dos cadenas, devuelve -1, 0 o 1 dependiendo de cuál sea "mayor". INDEX(A,B), devuelve el índice de B dentro de A. El tercer parámetro opcional es un punto de inicio de desplazamiento. LONGITUD(A), longitud de la cuerda ESPACIO(X), devuelve una cadena que consta de X espacios. VAL(A), busca un número en la cadena y lo devuelve. STR(N), convierte un número en una cadena IZQUIERDA, como en MS BIEN SUBSTR, como MID de MS 

Funciones de utilidad

También se incluyen funciones de utilidad típicas: [ 32 ]

POS devuelve la columna del cabezal de impresión POS ( X ) devuelve la posición en un archivo TAB ( X ) mueve el cabezal de impresión a la columna X TAB ( X , N ) la misma en el archivo número N FECHA HORA

SUPER BASIC también incluyó pseudovariables para PIy DPI, siendo esta última de doble precisión, así como la ya mencionada EPSpara representar el valor más pequeño posible.

SUPER BASIC incluía dos formas de formato de impresión que podían usarse con la PRINTinstrucción. PRINT IN IMAGE X:utilizaba una cadena de formato, en este caso almacenada en X, de forma similar a como otros BASIC implementaban usando PRINT USINGo los ejemplos más comunes que se encuentran en C y sus derivados. El tipo de campo incluía enteros, [ 33 ] formatos decimales especificados y exponentes, así como cadenas y texto. %Los signos indicaban un solo dígito en un campo entero o real, e #indicaban un dígito en un campo E. [ 34 ]* y $podían usarse para anteponer cualquier valor. [ 35 ]

PRINT IN FORMATFuncionaba generalmente de la misma manera, con la diferencia de que los espacios debían definirse explícitamente usando B. Así, la cadena de formato imprimiría dos valores numéricos con tres espacios entre ellos, mientras que si se trataba de una imagen, se imprimiría con un espacio a cada lado. La versión admitía una mayor variedad de cadenas de formato e incluía elementos como retornos de carro en línea, pero los ejemplos que se dan en los manuales no aclaran por qué existen dos sistemas de este tipo cuando al final logran lo mismo. [ 36 ]"%% BBB %%.%%""BBB"FORMAT

Curiosamente, los mismos comandos de formato podrían usarse para INPUT, no solo para PRINT. En este caso, la entrada del usuario se formatearía correctamente según la cadena, por lo que 1.2345podría truncarse a 1.2si el formato es %.%. [ 37 ]

E/S de archivos

SUPER BASIC incluía un sistema de entrada/salida de archivos basado en INPUT ON Xy PRINT ON Xdonde Xes el identificador del archivo, un número. El número se asignaba usando . se proporcionaba como alternativa a , pero son idénticos internamente. Cuando se completa, el archivo se puede liberar con o . [ 38 ] Al trabajar con archivos, se podía leer la ubicación de la siguiente lectura usando y cambiarla usando . [ 39 ] devolvía la posición dentro de un formulario si se estaba usando. [ 40 ] devolvía el tamaño del archivo. [ 41 ] Se podía usar en bucles para comprobar si se había alcanzado el final del archivo durante las lecturas. [ 42 ]OPENfilenameFOR[INPUT|OUTPUT]ASFILEXWRITE ON XPRINT ON XCLOSE XCLOSE filenameLOC(X)LOCATE 100 ON 2POS(X)IN FORMSIZE(N)ENDFILE(X)

El sistema también incluía una función TELque devolvía si había o no entrada pendiente en la terminal. Los programas SUPER BASIC a menudo incluían código como

100 ESPERAR ( 1 ); SI NO DECIR ENTONCES 100

esperar la entrada del usuario y probarla cada segundo antes de continuar. [ 43 ] Además, incluía un pseudo-nombre de archivo "TEL"que podía abrirse para lectura y escritura usando y luego . [ 44 ] Además de , tanto como también hacían referencia al comando teletype. [ 45 ]OPEN"TEL"FOROUTPUTAS2WRITEON2"HELLO WORLD""TEL""T""TELETYPE"

Notas

  1. La terminología tiene su origen en JOSS; los BASIC derivados de MS generalmente se refieren a esto como "modo inmediato".
  2. El sistema hexadecimal no se popularizó hasta que la mayoría de las máquinas usaban palabras basadas en 8 bits; en la era de las bases de 6 bits como la SDS 940, el sistema octal era común.

Referencias

Citas

  1. Lampson, Butler, "Sistemas", Investigación , Microsoft
  2. 1 2 Gregory 2018 , pág. 132.
  3. 1 2 3 4 Gregory 2018 , pág. 133.
  4. 1 2 Manual 1978 , pág. 14.
  5. Manual 1978 , pág. 3.
  6. Manual 1978 , pág. 11.
  7. Manual 1978 , pág. 107.
  8. Manual 1978 , pág. 13.
  9. Manual 1978 , pág. 15.
  10. Manual 1978 , pág. 143.
  11. Manual 1978 , pág. 9.
  12. 1 2 Manual 1978 , pág. 43.
  13. Manual 1978 , pág. 140.
  14. 1 2 3 Manual 1978 , pág. 29.
  15. Manual 1978 , pág. 44.
  16. Manual 1978 , pág. 45.
  17. 1 2 3 Manual 1978 , pág. 47.
  18. Manual 1978 , págs. 6, 7.
  19. Manual 1978 , pág. 26.
  20. Manual 1978 , pág. 27.
  21. Manual 1978 , pág. 25.
  22. 1 2 Manual 1978 , págs. 7, 8.
  23. Manual 1978 , pág. 17.
  24. 1 2 Manual 1978 , pág. 21.
  25. Manual 1978 , pág. 24.
  26. Manual 1978 , pág. 30.
  27. Manual 1978 , págs. 30, 31.
  28. Manual 1978 , pág. 28.
  29. Manual 1978 , pág. 33.
  30. Manual 1978 , pág. 34.
  31. Manual 1978 , págs. 35–37.
  32. Manual 1978 , pág. 18.
  33. Manual 1978 , pág. 51.
  34. Manual 1978 , pág. 52.
  35. Manual 1978 , pág. 53.
  36. Manual 1978 , pág. 55.
  37. Manual 1978 , pág. 60.
  38. Manual 1978 , págs. 71–75.
  39. Manual 1978 , pág. 84.
  40. Manual 1978 , pág. 85.
  41. Manual 1978 , pág. 132.
  42. Manual 1978 , pág. 126.
  43. Manual 1978 , pág. 99.
  44. Manual 1978 , pág. 76.
  45. Manual 1978 , pág. 89.

Bibliografía

  • Manual de referencia SUPER BÁSICO . Tymshare. Febrero de 1978.
  • Gregory, Nathan (2018). El tiempo antes de... Lulu. ISBN 9781387304059.