He creado un compilador en C (usando lex & bison) para un lenguaje de programación de tipo dinámico que admite bucles, declaraciones de funciones dentro de funciones, llamadas recursivas, etc. También creé una máquina virtual que ejecuta el código intermedio creado por el compilador.
Ahora estaba pensando en lugar de compilar en mi propio código intermedio, compilarlo en código de bytes de Java.
Vi que la pregunta sobre la creación de un lenguaje JVM ya se ha hecho, pero no encuentro la respuesta muy informativa.
Asi que aqui están mis preguntas:
- Supongo que para crear un lenguaje para JVM es imprescindible leer el libro de especificaciones de JVM , ¿qué otros libros puedes sugerir (excepto Dragon Book, por supuesto)? Lo que más me preocupa son los libros o tutoriales sobre cómo crear un lenguaje JVM, no un compilador en general.
- Hay muchas bibliotecas de Java para leer, escribir y cambiar archivos .class como jclasslib , bcel , gnu bytecode , etc. ¿Cuál sugeriría? Además, ¿conoce las bibliotecas C que hacen el mismo trabajo?
- Estaba pensando en echar un vistazo a quizás otro lenguaje que se dirija a la JVM como Clojure, Jython o JRuby. Pero todos estos lenguajes son de muy alto nivel y complicados (para crear un compilador para ellos). Estaba buscando un lenguaje de programación más simple (no me importa si es desconocido o no se usa) que se dirija a la JVM y su compilador sea de código abierto. ¿Algunas ideas?
El semestre pasado asistí a un curso de "Construcción de compiladores". Nuestro proyecto fue exactamente lo que quieres hacer.
El idioma que usé para escribir mi idioma fue Scala . Se ejecuta en una JVM pero admite muchas funciones avanzadas que Java no (sigue siendo totalmente compatible con una JVM pura de Java).
Para generar el código de bytes de Java, he usado la biblioteca Scala CAFEBABE . Bien documentado y no es necesario profundizar en las clases de Java para comprender qué hacer.
Además del libro, creo que puede encontrar mucha información revisando los laboratorios que hemos hecho durante el curso.
fuente
ASM puede ser una solución para generar códigos de bytes. Para comenzar, consulte los temas sobre la generación de elementos del manual .
fuente
Sugerencia: podría echar un vistazo al lenguaje de programación Lua , hay implementaciones de JVM como LuaJ .
(No confundir con LuaJava que usa bibliotecas nativas con enfoque JNI).
fuente
El fin de semana pasado, me hice la misma pregunta para trasladar mi lenguaje de juguetes a la JVM.
Solo paso unas pocas horas buscando información, así que tome estas referencias con un grano de sal.
Patrones de implementación del lenguaje . Odio las antlr pero este libro se ve muy bien. Si tampoco te gusta antlr, hay una gran ventaja en analizar "Técnicas de análisis. Una guía práctica".
El capítulo 10 cubre en 30 páginas (a la OMI rápida) estos temas. Pero hay otro capítulo que probablemente te interese.
La implementación de Lua 5.0 Este es un gran artículo sobre máquinas de códigos de bytes basadas en registros. Ve y léelo incluso por el simple hecho de hacerlo.
Lisp en pedazos pequeños. Este libro enseña cómo escribir comparadores de 2 schme que compilen en C. Se pueden aprender muchas lecciones de este libro. Soy dueño de una copia de este libro y es realmente bueno para cualquier persona interesante que cecea, pero tal vez no sea su taza de té.
http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521562473
Compruebe la máquina virtual Dalvik7, una máquina virtual basada en registros. El DVM funciona con códigos de bytes que se transforman a partir de los archivos Java Class compilados por un compilador Java.
Hay una lista de correo sobre el tema, jvm-languages.
¿Está planeando cargar el código en algún lugar? Me gustaría echarle un vistazo.
fuente
Are you planning to upload the code to anyplace?
No estoy orgulloso de ese código :( ... Quizás lo reescribiera todo. De todos modos, si lo hago, se lo haré saber. Muchas gracias por sus sugerencias.Le recomendaría que primero aprenda cómo funciona el ensamblaje de JVM, si aún no lo sabe.
Muchas instrucciones tienen la forma
?name
, donde?
esi
si la instrucción funciona con un tipo entero ya
si funciona con un tipo de referencia.Básicamente, JVM es una máquina de pila sin registros, por lo que todas las instrucciones funcionan con datos directamente en la pila. Puede enviar / extraer datos con
?push/?pop
y mover datos entre las variables locales (ubicaciones de pila referenciadas por compensaciones) y la parte superior de la pila usando?store/?load
. Algunas otras instrucciones importantes soninvoke???
yif_???
.por el curso de compilación de mi universidad usamos Jasmin para ensamblar los programas. No sé si esta es la mejor manera, pero al menos es un lugar fácil para comenzar.
Aquí hay una referencia de instrucciones para una versión anterior de la JVM, que puede contener menos instrucciones que una nueva.
fuente
Primero retrocedería, modificaría mi compilador para generar Java real en lugar de códigos de bytes de Java (lo que significa crear más un traductor que un compilador) y compilaría la salida de Java con cualquier entorno de Java que sea conveniente (lo que probablemente generaría un mejor código de objeto que mi propio compilador).
Puede usar la misma técnica (por ejemplo, compilar en C #) para generar códigos de bytes CLI, o compilar en Pascal para generar código P, etc.
No está claro por qué está considerando los códigos Java en lugar de usar su propia máquina virtual, pero si es por rendimiento, por supuesto, también debería considerar la compilación en código de máquina real.
fuente
Por supuesto, una vez podría usar Java para escribir un nuevo lenguaje. Con la API de reflexión de Java, puede obtener un llot. Si la velocidad no importa demasiado, le daría preferencia a Java en lugar de ASM. La programación es más fácil y menos propensa a errores en Java (en mi humilde opinión) . Eche un vistazo al séptimo idioma de RPN . Está completamente escrito en Java.
fuente