C-- (pronunciado C minus minus ) es un lenguaje de programación similar a C , diseñado para ser generado principalmente por compiladores para lenguajes de alto nivel en lugar de ser escrito por programadores humanos. Fue creado por los investigadores de programación funcional Simon Peyton Jones y Norman Ramsey. A diferencia de muchos otros lenguajes intermedios, se representa en texto ASCII simple, no en código de bytes u otro formato binario . [1] [2]
Hay dos ramas principales:
- C--, la rama original, con la versión final 2.0 lanzada en mayo de 2005 [3]
- Cmm, la bifurcación se utiliza activamente como representación intermedia (IR) en el compilador Glasgow Haskell (GHC) [4] [5]
Diseño
C-- es un " lenguaje ensamblador portátil ", [6] diseñado para facilitar la implementación de compiladores que producen código de máquina de alta calidad . [7] Esto se hace delegando la generación de código de bajo nivel y la optimización del programa a un compilador de C--. La sintaxis del lenguaje toma prestado en gran medida de C mientras que omite o cambia las características estándar de C como funciones variádicas , sintaxis de puntero y aspectos del sistema de tipos de C, porque obstaculizan las características esenciales de C-- y la facilidad de generación de código.
El nombre del lenguaje es una broma interna que indica que C-- es una forma reducida de C, de la misma manera que se eligió " C++-- " para connotar una versión mejorada de C. (En C, y ++significan "decremento" e "incremento", respectivamente). [8]
El trabajo en C-- comenzó a fines de la década de 1990. Dado que escribir un generador de código personalizado es un desafío en sí mismo, y los backends de compilador disponibles para los investigadores en ese momento eran complejos y estaban mal documentados, varios proyectos habían escrito compiladores que generaban código C (por ejemplo, el compilador Modula-3 original ). Sin embargo, C es una mala opción para lenguajes funcionales: no garantiza la optimización de llamadas finales , ni admite una recolección de basura precisa o un manejo eficiente de excepciones . C-- es una alternativa más simple a C, definida estrictamente, que admite todas estas funciones. Su característica más innovadora es una interfaz de tiempo de ejecución que permite escribir recolectores de basura portátiles, sistemas de manejo de excepciones y otras funciones de tiempo de ejecución que funcionan con cualquier compilador de C--.
La primera versión de C-- se publicó en abril de 1998 como un documento MSRA, [1] acompañado por un documento de enero de 1999 sobre recolección de basura. [2] Un manual revisado se publicó en formato HTML en mayo de 1999. [9] Dos conjuntos de cambios importantes propuestos en 2000 por Norman Ramsey ("Cambios propuestos") y Christian Lindig ("Una nueva gramática") condujeron a la versión 2 de C--, que se finalizó alrededor de 2004 y se publicó oficialmente en 2005. [3]
Sistema de tipos
El sistema de tipos C-- está diseñado para reflejar las restricciones impuestas por el hardware en lugar de las convenciones impuestas por los lenguajes de nivel superior. Un valor almacenado en un registro o memoria puede tener solo un tipo: bit-vector . Sin embargo, bit-vector es un tipo polimórfico que viene en varios anchos, p. ej. bits8 , bits32 o bits64 . Se admite una familia separada de tipos de punto flotante de 32 o 64 bits. Además del tipo bit-vector, C-- proporciona un tipo booleano bool , que puede calcularse mediante expresiones y usarse para el flujo de control, pero no puede almacenarse en un registro o memoria. Al igual que en un lenguaje ensamblador, cualquier disciplina de tipos superior, como las distinciones entre signed, unsigned, float y pointer, se impone mediante los operadores C-- u otras construcciones sintácticas. C-- no se verifica por tipos, ni aplica ni verifica la convención de llamada. [3] : 28
La versión 2 de C-- elimina la distinción entre tipos de vector de bits y de punto flotante. Estos tipos se pueden anotar con una etiqueta de cadena "kind" para distinguir, entre otras cosas, el tipo entero de una variable frente al tipo flotante y su comportamiento de almacenamiento (global o local). El primero es útil en destinos que tienen registros separados para valores enteros y de punto flotante. Se introdujeron tipos especiales para punteros y la palabra nativa, aunque se asignan a un vector de bits con una longitud que depende del destino. [3] : 10
Código de ejemplo
El siguiente código C calcula la suma y el producto de los números enteros del 1 al n [10] (se recibe n como argumento). Demuestra dos características del lenguaje:
- Los procedimientos pueden devolver múltiples resultados.
- La recursión de cola se solicita explícitamente con la palabra clave "jump".
/* Recursión de cola */
export sp ; sp ( bits32 n ) { jump sp_help ( n , 1 , 1 ); }
sp_help ( bits32n , bits32s , bits32p ) { si n == 1 { devolver ( s , p ); } de lo contrario { saltar sp_help ( n - 1 , s + n , p * n ) ; } }
Implementaciones
La página de especificaciones de C-- enumera algunas implementaciones de C--. El compilador "más activamente desarrollado", Quick C--, fue abandonado en 2013. [11]
Haskell
Algunos desarrolladores de C--, incluidos Simon Peyton Jones, João Dias y Norman Ramsey, trabajan o han trabajado en GHC, cuyo desarrollo ha llevado a extensiones en el lenguaje C--, formando el dialecto Cmm que utiliza el preprocesador C para ergonomía. [4] [12]
Los backends de GHC son responsables de transformar aún más C-- en código ejecutable, a través de LLVM IR, C lento o directamente a través del backend nativo integrado. [13] [14] [15] A pesar de la intención original, GHC realiza muchas de sus optimizaciones genéricas en C--. Al igual que con otros IR de compilador, la representación de C-- se puede volcar para depuración. [16] Las optimizaciones específicas del objetivo las realiza más tarde el backend.
Sistemas de procesamiento
A partir de 2018, la mayoría de los sistemas de procesamiento no reciben mantenimiento ni se publica su código fuente.
- Quick C-- es un compilador desarrollado por el equipo de Quick C--. Compila la versión 2 del código C-- en código de máquina Intel x86 Linux. La compilación en código de máquina para otras plataformas está disponible como una función experimental. Anteriormente, Quick C-- se desarrolló en paralelo con la evolución de la especificación del lenguaje C--, pero el proyecto se archivó en 2019 en GitHub y el desarrollo ha cesado, aunque el código fuente está disponible allí.
- cmmc es un compilador de C implementado en el lenguaje de programación ML por Fermin Reig. Genera código máquina para arquitecturas Alpha, Sparc y x86. [17]
- Trampoline C-- Compiler es un transpilador de C-- a C desarrollado por Sergei Egorov en mayo de 1999. Traduce código C-- en código C, lo que permite compilarlo utilizando compiladores C estándar.
- El compilador C del Oregon Graduate Institute (OGI C-Compiler) es el primer prototipo de compilador C-Compiler, desarrollado en 1997 utilizando el lenguaje de programación ML. El mantenimiento del compilador C-Compiler OGI se interrumpió una vez que comenzó el desarrollo de Quick C-Compiler.
Véase también
Referencias
- ^ ab Nordin, Thomas; Jones, Simon Peyton; Iglesias, Pablo Nogueira; Oliva, Dino (23 de abril de 1998). "El manual de referencia del lenguaje C".
{{cite journal}}: Requiere citar revista|journal=( ayuda ) - ^ ab Reig, Fermin; Ramsey, Norman; Jones, Simon Peyton (1999-01-01). "C–: un lenguaje ensamblador portátil que soporta la recolección de basura": 1– 28.
{{cite journal}}: Requiere citar revista|journal=( ayuda ) - ^ abcd Ramsey, Norman; Jones, Simon Peyton. "La especificación del lenguaje C, versión 2.0" (PDF) . Consultado el 11 de diciembre de 2019 .
- ^ ab Comentario de GHC: ¿Qué diablos es un archivo .cmm?
- ^ "Un backend LLVM mejorado". Abril de 2019.
- ^ Oliva, Dino; Nordin, T.; Peyton Jones, Simon (1 de enero de 1997). "C-: Un lenguaje ensamblador portátil". Actas del taller de 1997 sobre implementación de lenguajes funcionales , a través de Microsoft.
- ^ Jones, Simon Peyton; Nordin, Thomas; Oliva, Dino (1998). Clack, Chris; Hammond, Kevin; Davie, Tony (eds.). "C--: Un lenguaje ensamblador portátil". Implementación de lenguajes funcionales . Berlín, Heidelberg: Springer: 1– 19. doi :10.1007/BFb0055421. ISBN 978-3-540-68528-9.
- ^ "Operadores de incremento y decremento en C con precedencia". unstop.com . Consultado el 20 de junio de 2024 .
- ^ Nordin, Thomas; Jones, Simon Peyton; Iglesias, Pablo Nogueira; Oliva, Dino (23 de mayo de 1999). "El manual de referencia del lenguaje C".
- ^ Ramsey, Norman; Jones, Simon Peyton; Lindig, Christian (23 de febrero de 2005), The C-- Language Specification, versión 2.0 (CVS Revision 1.128) (PDF) , pág. 7 , consultado el 22 de junio de 2023
- ^ "C-- Descargas". www.cs.tufts.edu . Consultado el 11 de diciembre de 2019 .
- ^ "5.10. Backends de GHC: Guía del usuario del compilador Glasgow Haskell 9.8.1". downloads.haskell.org . Consultado el 20 de junio de 2024 .
- ^ Backends de GHC
- ^ "Artículo de opinión sobre los backends de GHC". andreaspk.github.io . 25 de agosto de 2019 . Consultado el 20 de junio de 2024 .
- ^ "Uso del compilador Glasgow Haskell (GHC)". ProgDoer . Consultado el 20 de junio de 2024 .
- ^ Depuración de compiladores con combustible de optimización
- ^ "C-- Descargas". www.cs.tufts.edu . Consultado el 20 de junio de 2024 .
Enlaces externos
- Archivo del antiguo sitio web oficial (cminusminus.org)
- Archivo de código C rápido (implementación de referencia)