ALGOL 68-R fue la primera implementación del lenguaje algorítmico ALGOL 68 .
En diciembre de 1968 se publicó el informe sobre el lenguaje algorítmico ALGOL 68. Del 20 al 24 de julio de 1970, la Federación Internacional para el Procesamiento de la Información (IFIP) organizó una conferencia de trabajo para discutir los problemas de implementación del lenguaje, [1] un pequeño equipo del Royal Radar Establishment (RRE) asistió para presentar su compilador . escrito por IF Currie, Susan G. Bond , [2] y JD Morrison. Ante las estimaciones de hasta 100 años-hombre para implementar el lenguaje, utilizando compiladores de múltiples pasos con hasta siete pasos, describieron cómo ya habían implementado un compilador de un solo paso que estaba en producción para usos científicos y de ingeniería.
El compilador ALGOL 68-R se escribió inicialmente en un dialecto local de ALGOL 60 con extensiones para manipulación de direcciones y procesamiento de listas. El analizador se escribió utilizando el generador de analizadores Syntax Improving Device (SID) de JM Foster .
Aproximadamente 20.000 de esto son programas, que consideramos demasiado grandes.
– Currie [3]
La primera versión del compilador ocupaba 34.000 palabras. Posteriormente fue reescrito en ALGOL 68-R, [4] tomando alrededor de 36 K palabras para compilar la mayoría de los programas. [5]
ALGOL 68-R se implementó bajo el sistema operativo George 3 en una ICL 1907F . El compilador fue distribuido sin costo alguno por International Computers Limited (ICL) en nombre de Royal Radar Establishment (RRE).
Es una cuestión de moralidad. ¡Tenemos una Biblia y estás pecando!
– Mailloux [6]
Para permitir la compilación de una pasada, ALGOL 68-R implementó un subconjunto del lenguaje definido en el informe original: [7]
Muchas de estas restricciones fueron adoptadas por el informe revisado sobre ALGOL 68.
Para permitir la compilación en una sola pasada, ALGOL 68-R insistió en que todos los identificadores se especificaran (declararan) antes de su uso.
El programa estándar:
PROC par = ( número INT ) BOOL : (número = 0 | VERDADERO | impar ( ABS (número - 1))); PROC impar = ( número INT ) BOOL : (número = 0 | FALSO | par ( ABS (número - 1)));
habría que reescribirlo como:
PROC ( INT ) BOOL impar; PROC par = ( número INT ) BOOL : (número = 0 | VERDADERO | impar ( ABS (número - 1)));impar := ( número INT ) BOOL : ( número = 0 | FALSO | par ( ABS (número - 1)));
Para permitir declaraciones recursivas de modos (tipos), se utilizó una declaración de modo stub especial para informar al compilador que un símbolo próximo era un modo en lugar de un operador:
MODO B ; MODO A = ESTRUCTURA ( REF B b); MODO B = [1:10] REF A ;
En el lenguaje estándar, la coerción procesal podría, en un contexto fuerte , convertir una expresión de algún tipo en un procedimiento que devuelva ese tipo. Esto podría usarse para implementar la llamada por nombre .
Otro caso donde se utilizó la procesalidad fue la declaración de procedimientos, en la declaración:
PROC x más 1 = INT : x + 1;
el lado derecho era una conversión de x + 1 a un número entero, que luego se convertía en un procedimiento que devolvía un número entero .
El equipo de ALGOL 68-R encontró esto demasiado difícil de manejar e hizo dos cambios en el idioma. Se eliminó la coerción de procedimiento y el modo de forma: expresión se redefinió como una denotación de procedimiento , y las conversiones se indican mediante un símbolo VAL explícito:
REAL : x CO un elenco a REAL en ALGOL 68 COREAL VAL x CO un elenco a REAL en ALGOL 68-R CO
El código que tenía un uso válido para llamar por nombre (por ejemplo, el dispositivo de Jensen ) podría simplemente pasar una denotación de procedimiento:
PROC suma = ( INT bajo, alto, PROC ( INT ) REAL término) REAL : COMENZAR REAL temp := 0; PARA i DE lo A hola DO temperatura +:= término (i); temperatura FIN ; imprimir (suma (1, 100, ( INT i) REAL : 1/i))
En la versión del lenguaje definido en el informe revisado se aceptaron estos cambios, aunque la forma del elenco se cambió ligeramente a modo (expresión) .
REAL (x) CO una conversión a REAL en ALGOL 68 CO revisado
En el idioma original, el modo VOID estaba representado por un modo vacío:
: x := 3,14; Lanzamiento de CO (x: = 3,14) para anular el COPROC finalizar = GOTO finalizar; CO un procedimiento que devuelve CO nulo
El equipo de ALGOL 68-R decidió utilizar un símbolo VOID explícito para simplificar el análisis (y aumentar la legibilidad):
VALOR ANULADO x := 3,14; Lanzamiento de CO (x: = 3,14) para anular el COPROC final = VOID : GOTO final; CO un procedimiento que devuelve CO nulo
Esta modificación del lenguaje fue adoptada por el informe revisado ALGOL 68.
Los declarantes formales son los modos del lado izquierdo de una declaración de identidad, o los modos especificados en una declaración de procedimiento. En el idioma original, podían incluir límites de matriz y especificar si el declarante real coincidente era fijo, FLEX o CUALQUIERA :
[ 15 ] INT a; CO un declarante real, límites 1:15 CO REF [ 3 : ] INT b = a; CO Esto es un error COPROC x = ( REF [ 1 : CUALQUIER ] INT a ) : ...
Creo que fue algo razonable omitir los límites de los declarantes formales, pero creo que fue un crimen terrible omitir CUALQUIERA o FLEX –
Lindsey [ 8]
El equipo de ALGOL 68-R redefinió a los declarantes formales para que sean iguales a los declarantes virtuales que no incluyen información vinculada. Descubrieron que esto reducía las ambigüedades al analizar el lenguaje y sintieron que no era una característica que se usaría en programas de trabajo.
Si un procedimiento necesitara ciertos límites para sus argumentos, podría comprobarlos él mismo con los operadores UPB (límite superior) y LWB (límite inferior).
En ALGOL 68-R, el ejemplo anterior podría recodificarse así: (los límites de a en el procedimiento dependerían de la persona que llama).
[ 15 ] INT a; CO un declarante real, límites 1:15 CO REF [] INT b = a [ AT 3]; CO usa rebanada para que b tenga límites 3:17 COPROC x = ( REF [] INT a) VOID : ... límites de CO dados por la persona que llama CO
En el informe revisado sobre ALGOL 68 también se eliminaron los límites formales, pero la indicación FLEX se movió a su posición para que pudiera incluirse en los declarantes formales:
[ 1: FLEXIBLE ] INT a; CO original ALGOL 68, o ALGOL 68-R CO FLEX [ 1: ] INT a; CO revisado ALGOL 68, CO
PROC x = ( REF [ 1: FLEX ] INT a ): ... CO ALGOL 68 original CO PROC x = ( REF [ ] INT a ) VOID : ... CO ALGOL 68-R CO PROC x = ( REF FLEX [ ] INT a) NULO : ... CO Revisado ALGOL 68 CO
En ALGOL 68, el código se puede ejecutar en paralelo escribiendo PAR seguido de una cláusula colateral , por ejemplo en:
PAR INICIO productor, consumidorFIN
Los procedimientos productor y consumidor se ejecutarán en paralelo. Se proporciona un tipo de semáforo ( SEMA ) con los operadores tradicionales P ( DOWN ) y V ( UP ) para sincronizar entre las partes de la cláusula paralela.
Esta característica no se implementó en ALGOL 68-R.
Se escribió una extensión llamada ALGOL 68-RT que utilizaba la función de subprogramación del ICL 1900 para proporcionar funciones de subprocesos múltiples a los programas ALGOL 68-R con una semántica similar a las bibliotecas de subprocesos modernas . [9] No se realizaron cambios en el compilador, solo en la biblioteca de ejecución y el vinculador.
En ALGOL 68 el símbolo GOTO podría omitirse en un salto:
Parada PROC = : ...;...COMIENZAR SI x > 3 ENTONCES detener FI ; CO un salto, no una llamada CO ...detener: SALTAR FINAL
Como ALGOL 68-R era un compilador de una sola pasada, esto era demasiado difícil, por lo que el símbolo GOTO se hizo obligatorio.
La misma restricción se hizo en el sublenguaje oficial, ALGOL 68S . [10]
En ALGOL 68 unión es la coerción que produce una UNIÓN a partir de un modo constituyente, por ejemplo:
MODO IBOOL = UNIÓN ( INT , BOOL ); CO un IBOOL es un INT o un BOOL CO IBOOL a = TRUE ; CO el valor BOOL TRUE se une a un IBOOL CO
En el estándar ALGOL 68, la unión era posible en contextos firmes o fuertes , por lo que, por ejemplo, podría aplicarse a los operandos de fórmulas :
OP ISTRUE = ( IBOOL a) BOOL : ...; SI ISTRUE 1 CO es legal porque 1 ( INT ) se puede unir a IBOOL CO ENTONCES ...
Los implementadores de ALGOL 68-R encontraron que esto generaba demasiadas situaciones ambiguas, por lo que restringieron la coerción unificadora a contextos fuertes .
Los efectos de esta restricción rara vez eran importantes y, si era necesario, se podían solucionar utilizando un reparto para proporcionar un contexto sólido en el punto requerido del programa.
El compilador ALGOL 68-R inicializó la memoria no utilizada con el valor -6815700. [11] [12]
Se eligió este valor porque:
F00L
Se utilizó el mismo valor para representar NIL .
Observo, en algunos de sus programas de muestra, que no está subrayando ni acentuando nada.
– Mailloux [13]
En las lenguas de la familia ALGOL , es necesario distinguir entre identificadores y símbolos básicos de la lengua. En los textos impresos, esto generalmente se lograba imprimiendo símbolos básicos en negrita o subrayados ( BEGIN o comenzar , por ejemplo).
En los programas de código fuente , se debía utilizar alguna técnica de ajuste . En muchos lenguajes similares a ALGOL, antes de ALGOL 68-R, esto se lograba encerrando símbolos básicos entre comillas simples ('comienzo', por ejemplo). En 68-R, los símbolos básicos se podían distinguir escribiéndolos en mayúsculas, utilizándose minúsculas para los identificadores.
Como ALGOL 68-R se implementó en una máquina con bytes de 6 bits (y por lo tanto un juego de 64 caracteres), esto era bastante complejo y, al menos inicialmente, los programas debían componerse en cinta perforada de papel usando un Friden Flexowriter .
Basado en parte en la experiencia de ALGOL 68-R, el informe revisado sobre ALGOL 68 especificó representaciones de hardware para el lenguaje, incluido el ajuste SUPERIOR.
ALGOL 68-R incluía extensiones para compilación separada y acceso de bajo nivel a la máquina.
Dado que ALGOL 68 es un lenguaje fuertemente tipado , las sencillas funciones de biblioteca utilizadas por otros lenguajes en el sistema ICL 1900 eran insuficientes. ALGOL 68-R se entregó con su propio formato de biblioteca y utilidades que permitían compartir modos, funciones, variables y operadores entre segmentos de código compilados por separado que podían almacenarse en álbumes . [14]
Un segmento que se pondría a disposición de otros segmentos terminaría con una lista de declaraciones que se pondrían a disposición:
graphlib CO el nombre del segmento CO BEGIN MODE GRAPHDATA = STRUCT (...); GRÁFICO DE MODO = DATOS DEL GRÁFICO DE REF ; PROC nuevo gráfico = (...) GRÁFICO : ...; PROC dibujar gráfico = ( GRAPH g) VOID : ...; ...FINALIZAR MANTENER GRÁFICO , nuevo gráfico, dibujar gráfico FINALIZAR
Y luego las funciones gráficas podrían ser utilizadas por otro segmento:
myprog CON graphlib DESDE graphalbum COMENZAR GRÁFICO g = nuevo gráfico (...); ... dibujar el gráfico (g); ...ACABADO FINAL
Como lenguaje de alto nivel fuertemente tipado, ALGOL 68 evita que los programas accedan directamente al hardware de bajo nivel. Por ejemplo, no existen operadores para la aritmética de direcciones.
Dado que ALGOL 68-R no se compilaba en el formato semicompilado (listo para enlace) ICL estándar, era necesario ampliar el lenguaje para proporcionar funciones en ALGOL 68-R para escribir código que normalmente se escribiría en lenguaje ensamblador . Las instrucciones de la máquina se podían escribir en línea , dentro de las secciones CÓDIGO ... EDOC y se agregaron los operadores de manipulación de direcciones INC , DEC , DIF , AS . [15]
Un ejemplo, utilizando una operación George peri para emitir un comando:
[1: 120] Mejora de CARBÓN ; número de unidad INT ; STRUCT ( modo de tipo BITS , respuesta, recuento INT , dirección REF CHAR ) área de control := (8r47400014,0,120,buff[1]);...;CÓDIGO 0,6/número de unidad; 157,6/tipomodo DEL área de control EDOC
Una copia del compilador ALGOL 68-R, ejecutable bajo el emulador del sistema operativo George 3 , de David Holdsworth ( Universidad de Leeds ), está disponible, con código fuente, bajo una Licencia Pública General GNU (GPL). [dieciséis]
El compilador Algol 68-R solía inicializar su almacenamiento en la cadena de caracteres "F00LF00LF00LF00L..." porque como puntero o como número de coma flotante causaba un bloqueo, y como entero o cadena de caracteres era muy reconocible en un vertedero.