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 de Procesamiento de la Información (IFIP) organizó una conferencia de trabajo para discutir los problemas de implementación del lenguaje, [1] a la que asistió un pequeño equipo del Royal Radar Establishment (RRE) 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 pasadas con hasta siete pasadas, describieron cómo ya habían implementado un compilador de una sola pasada 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 la manipulación de direcciones y el procesamiento de listas. El analizador se escribió utilizando el generador de analizadores sintácticos Syntax Improving Device (SID) de JM Foster .
Aproximadamente 20 000 de este programa, lo cual consideramos demasiado grande.
– Currie [3]
La primera versión del compilador ocupaba 34 K palabras. Posteriormente fue reescrita en ALGOL 68-R [4] , y se necesitaban alrededor de 36 K palabras para compilar la mayoría de los programas. [5]
ALGOL 68-R se implementó en el sistema operativo George 3 en un ICL 1907F . El compilador fue distribuido sin cargo por International Computers Limited (ICL) en nombre del Royal Radar Establishment (RRE).
Es una cuestión de moralidad. ¡Tenemos una Biblia y vosotros pecáis!
– Mailloux [6]
Para permitir la compilación en una sola pasada, ALGOL 68-R implementó un subconjunto del lenguaje definido en el informe original: [7]
Muchas de estas restricciones fueron adoptadas en 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 = ( INT número) BOOL : ( número = 0 | VERDADERO | impar ( ABS (número - 1))); PROC impar = ( INT número) BOOL : ( número = 0 | FALSO | par ( ABS (número - 1)));
Debería reescribirse como:
PROC ( INT ) BOOL impar; PROC par = ( INT número) BOOL : ( número = 0 | VERDADERO | impar ( ABS (número - 1)));impar := ( INT número) BOOL : ( número = 0 | FALSO | par ( ABS (número - 1)));
Para permitir declaraciones recursivas de modos (tipos), se utilizó una declaración de modo especial para informar al compilador que un símbolo siguiente 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 de procedimiento 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 en el que se utilizó el procedimiento fue la declaración de procedimientos, en la declaración:
PROC x más 1 = INT : x + 1;
El lado derecho fue una conversión de x + 1 a un entero, que luego se convirtió en un procedimiento que devolvía un entero .
El equipo ALGOL 68-R consideró que esto era demasiado difícil de manejar e hizo dos cambios en el lenguaje. Se eliminó la coerción de procedimiento y se redefinió el formato mode : expression como una denotación de procedimiento , y las conversiones se indicaban mediante un símbolo VAL explícito :
REAL : x CO se convierte en REAL en ALGOL 68 COREAL VAL x CO se convierte en 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 lo, hi, PROC ( INT ) término REAL ) REAL : INICIO REAL temp:= 0; PARA i DESDE lo HASTA hi HACER temp +:= término (i); temperatura FIN ; imprimir (suma (1, 100, ( INT i) REAL : 1/i))
En la versión del lenguaje definida en el informe revisado se aceptaron estos cambios, aunque la forma del molde se modificó ligeramente a modo (expresión) .
REAL (x) CO se convirtió en REAL en ALGOL 68 CO revisado
En el idioma original el modo VOID estaba representado por un modo vacío:
: x := 3.14; CO convierte (x := 3.14) en anulador de COPROC endit = GOTO end; CO un procedimiento que devuelve un CO vacío
El equipo de ALGOL 68-R decidió utilizar un símbolo VOID explícito para simplificar el análisis (y aumentar la legibilidad):
VOID VAL x := 3.14; conversión de CO (x := 3.14) a void COPROC endit = VOID : GOTO end; CO un procedimiento que devuelve un CO vacío
Esta modificación del lenguaje fue adoptada por el informe revisado de ALGOL 68.
Los declarantes formales son los modos que se encuentran en el lado izquierdo de una declaración de identidad o los modos especificados en una declaración de procedimiento. En el lenguaje original, podían incluir límites de matriz y especificar si el declarante real correspondiente era fijo, FLEX o EITHER :
[ 15 ] INT a; CO un declarante real, límites 1:15 CO REF [ 3 : ] INT b = a; CO Este es un error COPROC x = ( REF [ 1 : O ] INT a) : ...
Creo que fue razonable omitir los límites de los declarantes formales, pero creo que fue un crimen terrible omitir el EYTER o el FLEX
– Lindsey [8]
El equipo ALGOL 68-R redefinió los declarantes formales para que sean iguales a los declarantes virtuales que no incluyen información limitada. Descubrieron que esto reducía las ambigüedades en el análisis del lenguaje y consideraron que no era una característica que se utilizaría en programas en funcionamiento.
Si un procedimiento necesita ciertos límites para sus argumentos, podría comprobarlos por sí mismo con los operadores UPB (límite superior) y LWB (límite inferior).
En ALGOL 68-R el ejemplo anterior podría recodificarse de la siguiente manera: (los límites de a en el procedimiento dependerían del llamador).
[ 15 ] INT a; CO un declarante real, límites 1:15 CO REF [] INT b = a [ AT 3]; CO usa una porción para que b tenga límites 3:17 COPROC x = ( REF [] INT a) VOID : ... límites de CO dados por el llamador CO
En el informe revisado sobre ALGOL 68 también se eliminaron los límites formales, pero la indicación FLEX se movió de posición para que pudiera incluirse en los declarantes formales:
[ 1: FLEX ] 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 CO original PROC x = ( REF [ ] INT a) VOID : ... CO ALGOL 68-R CO PROC x = ( REF FLEX [ ] INT a) VOID : ... CO ALGOL 68 CO revisado
En ALGOL 68 el código se puede ejecutar en paralelo escribiendo PAR seguido de una cláusula colateral , por ejemplo en:
PAR COMIENZA 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 la sincronización entre las partes de la cláusula paralela.
Esta función no se implementó en ALGOL 68-R.
Se escribió una extensión llamada ALGOL 68-RT que utilizaba la característica de subprogramación del ICL 1900 para proporcionar facilidades de subprocesamiento múltiple 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 tiempo de ejecución y el enlazador.
En ALGOL 68 el símbolo GOTO podría omitirse en un salto:
PROC parada = : ...;...COMIENZA SI x > 3 ENTONCES para 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 unir es la coerción que produce una UNIÓN a partir de un modo constituyente, por ejemplo:
MODO IBOOL = UNION ( 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 unificación era posible en contextos firmes o fuertes , por lo que, por ejemplo, se podía aplicar a los operandos de fórmulas :
OP ISTRUE = ( IBOOL a) BOOL : ...; SI ISTRUE 1 CO legal porque 1 ( INT ) se puede unir a IBOOL CO ENTONCES ...
Los implementadores de ALGOL 68-R descubrieron que esto generaba demasiadas situaciones ambiguas, por lo que restringían la coerción unificadora a contextos fuertes .
Los efectos de esta restricción rara vez eran importantes y, de ser necesario, se podían solucionar utilizando un elenco para proporcionar un contexto fuerte 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 .
He observado que en algunos de sus programas de muestra no subraya ni resalta nada.
– Mailloux [13]
En los idiomas de la familia ALGOL es necesario distinguir entre identificadores y símbolos básicos del idioma. En los textos impresos esto se hacía generalmente imprimiendo los símbolos básicos en negrita o subrayados ( BEGIN o begin por ejemplo).
En los programas de código fuente , se debía utilizar alguna técnica de stropping . En muchos lenguajes similares a ALGOL, antes de ALGOL 68-R, esto se lograba encerrando los símbolos básicos entre comillas simples (por ejemplo, 'begin'). En 68-R, los símbolos básicos se podían distinguir escribiéndolos en mayúsculas, y los identificadores se servían en minúsculas.
Como ALGOL 68-R se implementó en una máquina con bytes de 6 bits (y por lo tanto, un conjunto de 64 caracteres), esto era bastante complejo y, al menos inicialmente, los programas debían componerse en cinta perforada de papel utilizando una 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 UPPER.
ALGOL 68-R incluía extensiones para compilación separada y acceso de bajo nivel a la máquina.
Como ALGOL 68 es un lenguaje fuertemente tipado , las sencillas bibliotecas 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 disposición de otros segmentos finalizará con una lista de declaraciones que se pondrán a disposición:
graphlib CO el nombre del segmento CO BEGIN MODE GRAPHDATA = STRUCT (...); MODE GRAPH = REF GRAPHDATA ; PROC nuevo gráfico = (...) GRAPH : ...; PROC dibujar gráfico = ( GRAPH g) VOID : ...; ...FIN 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 COMIENZO GRÁFICO g = nuevo gráfico (...); ... dibujar la gráfica (g); ...FINALIZACIÓN
Como lenguaje de alto nivel fuertemente tipado, ALGOL 68 impide que los programas accedan directamente al hardware de bajo nivel. No existen operadores para la aritmética de direcciones, por ejemplo.
Como ALGOL 68-R no se compilaba en el formato estándar ICL semicompilado (listo para enlace), era necesario ampliar el lenguaje para proporcionar características en ALGOL 68-R para escribir código que normalmente se escribiría en lenguaje ensamblador . Las instrucciones de máquina se podían escribir en línea , dentro de las secciones CODE ... EDOC y se añadieron los operadores de manipulación de direcciones INC , DEC , DIF y AS . [15]
Un ejemplo, utilizando una operación de George peri para emitir un comando:
[1 : 120] CHAR buff; INT número de unidad; STRUCT ( BITS tipo modo, respuesta, INT conteo, REF CHAR dirección) área de control := (8r47400014,0,120,buff[1]);...;CÓDIGO 0,6/número de unidad; 157,6/tipo modo OF á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 el código fuente, bajo una Licencia Pública General GNU (GPL). [16]
fallo, y como entero o cadena de caracteres era muy reconocible en un volcado.