En primer lugar, sé que esta es una pregunta hecha por MUCHOS otros programadores antes que yo. Pero no pude encontrar ningún recurso utilizable que pudiera ayudarme.
Bueno, estoy creando un lenguaje de programación llamado "Light", la sintaxis es comparable a Python pero tiene un concepto estricto orientado a objetos.
He hecho un intérprete (en C ++) para este lenguaje todavía, mi problema es cómo convertir esto en un ejecutable. (O simplemente: ¿cómo hago un compilador?)
Gracias por tu atención
PD: He encontrado algunos enlaces a un tutorial muy antiguo, pero está en Pascal ...
EDITAR: Bueno, bueno. Ahora he encontrado un tutorial adecuado para C ++. Sobre el proyecto: Ha habido algunos cambios. Ahora el idioma se llama "Q". (Punto kju).
Respuestas:
El primer par de pasos lexing / parsing (y análisis, dependiendo de cómo esté estructurado) puede ser el mismo. Pero necesitará convertir su representación en una representación generadora de código. Normalmente, LLVM se usa para aficionados, ya que es prácticamente la única biblioteca de generación de código gratuita remotamente decente.
fuente
ghc
por ejemplo, es perfectamente capaz de producir ejecutables a través de C. Además de cientos de otros compiladores basados en C. ¿Tu religión te prohíbe usarpopen(...)
en un compilador? Entonces tienes que tirar a la basuragcc
. En cuanto a .NET, a diferencia de JVM, es capaz de satisfacer una gran variedad de semánticas, debido a sus características inseguras.Si todo lo que realmente desea es un ejecutable, puede agregar el script al final de un ejecutable de intérprete y hacer que lo ejecute.
Ver: /programming/5795446/appending-data-to-an-exe
Alternativamente, puede hacer que el intérprete cargue el código de un archivo en el mismo directorio que el intérprete y obtenga en gran medida el mismo resultado, solo con varios archivos.
Un verdadero compilador convertiría el código a otro idioma y usaría el compilador para ese idioma. Pero si solo desea distribuir ejecutables, no hay necesidad de hacerlo.
fuente
También puede considerar usar System.Reflection.Emit desde el tiempo de ejecución .NET para generar un ejecutable .NET. Esto le dará acceso a un entorno orientado a objetos existente que ya le ha resuelto algunos problemas, y el exe resultante puede ser independiente de la plataforma. El tiempo de ejecución compilará el código intermedio en el .exe al código de la máquina según sea necesario, por lo que el rendimiento debe ser comparable al que obtendría compilando directamente al código nativo.
fuente
Está preguntando acerca de la técnica conocida como "compilador de rastreo": el intérprete recopila información sobre la ejecución del código y construye de manera incremental el código de bajo nivel utilizando los datos recopilados.
https://en.wikipedia.org/wiki/Tracing_just-in-time_compilation
https://stefan-marr.de/papers/oopsla-marr-ducasse-meta-tracing-vs-partial-evaluation/
La diferencia con el JIT clásico es el hecho de que los datos de rastreo recopilados y el código compilado se conservan de cada ejecución de un programa, lo que le brinda no solo el código de máquina ejecutable sino también la optimización de datos reales (o de capacitación). El primer paso es un conjunto de pruebas, que deben pasar todas las ramas del programa, para crear código para cada parte de su programa. Los siguientes son programas que se ejecutan en datos reales (uso de producción), que recopila y aplica optimizaciones (cosas como el orden de sucursales a los casos más utilizados).
Este método es mucho más complejo de implementar que un esquema de construcción de compilador clásico, por lo que no se usa con frecuencia y es complejo encontrar un buen conjunto de tutoriales sobre cómo hacer un compilador similar.
fuente