¿Qué tipos de patrones puedo aplicar en el código para facilitar la traducción a otro lenguaje de progtwigción?

Me estoy proponiendo hacer un proyecto paralelo que tiene el objective de traducir el código de un lenguaje de progtwigción a otro. Los idiomas con los que estoy empezando son PHP y Python (Python to PHP debería ser más fácil de usar), pero lo ideal sería poder agregar otros idiomas con una facilidad (relativa). El plan es:

Entonces creo que puedo empezar a generar código. No necesito una traducción perfecta . Todavía tendré que revisar el código generado y solucionar problemas. Idealmente, el traductor debe marcar las traducciones problemáticas.

Antes de preguntar “¿Qué demonios es el punto de esto?” La respuesta es … Será una experiencia de aprendizaje interesante. Si tiene alguna idea sobre cómo hacer esto menos desalentador, hágamelo saber.


EDITAR:

Estoy más interesado en saber qué tipos de patrones podría aplicar en el código para facilitar la traducción (es decir, ¿IoC, SOA?) Que cómo hacer la traducción.

He estado creando herramientas (DMS Software Reengineering Toolkit) para realizar la manipulación de progtwigs de propósito general (con la traducción de idiomas como un caso especial) desde 1995, con el apoyo de un equipo de científicos informáticos. DMS proporciona análisis generics, creación de AST, tablas de símbolos, análisis de flujo de datos y control, aplicación de reglas de traducción, regeneración de texto de origen con comentarios, etc., todo parametrizado por definiciones explícitas de lenguajes de computadora.

La cantidad de maquinaria que necesita para hacer esto bien es enorme (especialmente si desea poder hacerlo en múltiples idiomas de una manera general), y luego necesita analizadores fiables para idiomas con definiciones poco confiables (PHP es el ejemplo perfecto de esto). ).

No hay nada de malo en que pienses en construir un traductor de idioma a idioma o intentarlo, pero creo que encontrarás una tarea mucho más grande para los idiomas reales de lo que esperas. Tenemos unos 100 años hombre invertidos solo en DMS, y otros 6 a 12 meses en cada definición de lenguaje “confiable” (incluida la que construimos dolorosamente para PHP), mucho más para lenguajes desagradables como C ++. Será un “infierno de una experiencia de aprendizaje”; Ha sido para nosotros. (Es posible que encuentre interesante la sección de documentos técnicos en el sitio web anterior para comenzar ese aprendizaje).

Las personas a menudo intentan construir algún tipo de maquinaria generalizada comenzando con una pieza de tecnología con la que están familiarizados, que hace parte del trabajo. (Los ASTs de Python son un gran ejemplo). La buena noticia, es que parte del trabajo está hecho. La mala noticia es que la maquinaria tiene un montón de suposiciones incorporadas, la mayoría de las cuales no descubrirás hasta que intentes luchar para que haga otra cosa. En ese momento, descubre que la maquinaria está cableada para hacer lo que originalmente hace, y realmente se resistirá a su bash de hacer que haga algo más. (Sospecho que intentar obtener el AST de Python para modelar PHP va a ser muy divertido).

La razón por la que comencé a crear DMS originalmente fue para construir bases que tenían muy pocas suposiciones de este tipo incorporadas. Algunas de ellas nos dan dolores de cabeza. Hasta ahora, no hay agujeros negros. (La parte más difícil de mi trabajo en los últimos 15 años es tratar de evitar que esas suposiciones se introduzcan).

Mucha gente también comete el error de suponer que si pueden analizar (y quizás obtener un AST), están en el buen camino para hacer algo complicado. Una de las lecciones difíciles es que necesita tablas de símbolos y análisis de flujo para realizar un buen análisis o transformación de progtwigs. Los AST son necesarios pero no suficientes. Esta es la razón por la que el comstackdor de Aho y Ullman no se detiene en el capítulo 2. (El OP tiene este derecho en el sentido de que planea construir maquinaria adicional más allá del AST). Para más información sobre este tema, vea Vida después de analizar .

El comentario sobre “No necesito una traducción perfecta” es problemático. Lo que hacen los traductores débiles es convertir el 80% “fácil” del código, dejando el 20% difícil de hacerlo a mano. Si la aplicación que pretende convertir es bastante pequeña y solo desea convertirla una vez, entonces ese 20% está bien. Si desea convertir muchas aplicaciones (o incluso la misma con cambios menores en el tiempo), esto no es bueno. Si intenta convertir 100K SLOC, el 20% es 20,000 líneas originales de código que son difíciles de traducir, entender y modificar en el contexto de otras 80,000 líneas de progtwigs traducidos que ya no comprende. Eso requiere mucho esfuerzo. A nivel de un millón de líneas, esto es simplemente imposible en la práctica. (Sorprendentemente, hay personas que desconfían de las herramientas automatizadas e insisten en traducir millones de sistemas de línea a mano; eso es aún más difícil y normalmente lo descubren dolorosamente con largos retrasos, altos costos y, a menudo, fallas directas).

Lo que debe buscar para traducir sistemas a gran escala es un alto porcentaje de conversión en porcentajes de los noventa, o es probable que no pueda completar la parte manual de la actividad de traducción.

Otra consideración clave es el tamaño del código a traducir. Se necesita mucha energía para construir un traductor robusto que funcione, incluso con buenas herramientas. Si bien parece atractivo y atractivo construir un traductor en lugar de simplemente hacer una conversión manual, para bases de código pequeñas (por ejemplo, hasta aproximadamente 100K SLOC en nuestra experiencia), la economía simplemente no lo justifica. A nadie le gusta esta respuesta, pero si realmente tiene que traducir solo 10K de código SLOC, probablemente esté mejor mordiendo la bala y haciéndolo. Y sí, eso es doloroso.

Considero que nuestras herramientas son extremadamente buenas (pero, entonces, estoy bastante sesgada). Y todavía es muy difícil construir un buen traductor; Nos lleva alrededor de 1.5-2 años-hombre y sabemos cómo usar nuestras herramientas. La diferencia es que con esta cantidad de maquinaria, tenemos mucho más éxito de lo que fracasamos.

Mi respuesta abordará la tarea específica de analizar Python para traducirlo a otro idioma, y ​​no los aspectos de nivel superior que Ira abordó bien en su respuesta.

En resumen: no utilice el módulo analizador, hay una forma más fácil.

El módulo ast , disponible desde Python 2.6, es mucho más adecuado para sus necesidades, ya que le brinda un AST ya preparado para trabajar. He escrito un artículo sobre este último año, pero en resumen, use el método parse de ast para analizar el código fuente de Python en un AST. El módulo de parser le dará un árbol de análisis, no un AST. Ten cuidado con la diferencia .

Ahora, dado que los AST de Python son bastante detallados, dado un AST, el trabajo de front-end no es terriblemente difícil. Supongo que puede tener listo un prototipo simple para algunas partes de la funcionalidad con bastante rapidez. Sin embargo, llegar a una solución completa llevará más tiempo, principalmente porque la semántica de los idiomas es diferente. Un subconjunto simple del lenguaje (funciones, tipos básicos, etc.) se puede traducir fácilmente, pero una vez que llegue a las capas más complejas, necesitará maquinaria pesada para emular el núcleo de un idioma en otro. Por ejemplo, considere los generadores de Python y listas de comprensión que no existen en PHP (que yo sepa, que es bastante pobre cuando se trata de PHP).

Para darte un consejo final, considera la herramienta 2to3 creada por los desarrolladores de Python para traducir el código de Python 2 al código de Python 3. De cara al extremo, tiene la mayoría de los elementos que necesita para traducir Python a algo . Sin embargo, dado que los núcleos de Python 2 y 3 son similares, no se requiere maquinaria de emulación allí.

Escribir un traductor no es imposible, especialmente considerando que Joel Intern lo hizo durante un verano.

Si quieres hacer un idioma, es fácil. Si quieres hacer más, es un poco más difícil, pero no demasiado. La parte más difícil es que, mientras que cualquier lenguaje completo puede hacer lo que hace otro idioma completo, los tipos de datos incorporados pueden cambiar lo que un idioma hace fenomenalmente.

Por ejemplo:

 word = 'This is not a word' print word[::-2] 

se necesita mucho código C ++ para duplicar (está bien, puede hacerlo bastante corto con algunas construcciones de bucle, pero aún así).

Eso es un poco aparte, supongo.

¿Alguna vez has escrito un tokenizer / parser basado en una gramática de lenguaje? Probablemente querrá aprender cómo hacerlo si no lo ha hecho, porque esa es la parte principal de este proyecto. Lo que haría sería crear una syntax completa de Turing básica, algo bastante similar al código de bytes de Python. Luego creas un lexer / parser que toma una gramática del lenguaje (tal vez usando BNF ), y en base a la gramática, comstack el idioma en tu idioma intermedio. Entonces, lo que querrá hacer es hacer lo contrario: cree un analizador de su idioma en los idiomas de destino según la gramática.

El problema más obvio que veo es que al principio probablemente crearás un código horriblemente ineficiente, especialmente en lenguajes más poderosos * como Python.

Pero si lo hace de esta manera, entonces probablemente podrá descubrir formas de optimizar la salida a medida que avanza. Para resumir:

  • leer gramática proporcionada
  • comstackr el progtwig en syntax intermedia (pero también Turing completa)
  • comstackr el progtwig intermedio en el idioma final (basado en la gramática proporcionada)
  • …?
  • ¡Lucro!(?)

* por poderoso quiero decir que esto toma 4 líneas:

 myinput = raw_input("Enter something: ") print myinput.replace('a', 'A') print sum(ord(c) for c in myinput) print myinput[::-1] 

Muéstrame otro idioma que pueda hacer algo así en 4 líneas, y te mostraré un idioma tan poderoso como Python.

Hay un par de respuestas que te dicen que no te molestes. Bueno, ¿qué tan útil es eso? ¿Tu quieres aprender? Puedes aprender. Esto es comstackción. Da la casualidad de que su idioma de destino no es un código de máquina, sino otro lenguaje de alto nivel. Esto se hace todo el tiempo.

Hay una manera relativamente fácil de empezar. Primero, vaya a http://sourceforge.net/projects/lime-php/ (si desea trabajar en PHP) o algo similar y revise el código de ejemplo. A continuación, puede escribir un analizador léxico utilizando una secuencia de expresiones regulares y alimentar tokens al analizador que genere. Sus acciones semánticas pueden generar un código directamente en otro idioma o crear una estructura de datos (piense en los objetos, hombre) que puede aplicar y atravesar para generar un código de salida.

Tienes suerte con PHP y Python porque, en muchos aspectos, son el mismo lenguaje entre sí, pero con una syntax diferente. La parte difícil es superar las diferencias semánticas entre las formas gtwigticales y las estructuras de datos. Por ejemplo, Python tiene listas y diccionarios, mientras que PHP solo tiene matrices Assoc.

El enfoque de “aprendiz” es construir algo que funcione bien para un subconjunto restringido del lenguaje (como solo imprimir declaraciones, matemáticas simples y asignación de variables) y luego eliminar las limitaciones progresivamente. Eso es básicamente lo que hicieron los “grandes” muchachos en el campo.

Ah, y como no tiene tipos estáticos en Python, podría ser mejor escribir y confiar en funciones de PHP como “python_add” que agrega números, cadenas u objetos de acuerdo con la forma en que Python lo hace.

Obviamente, esto puede ser mucho más grande si lo dejas.

Respaldaré el punto de vista de @EliBendersky con respecto al uso de ast.parse en lugar del analizador (que no conocía antes). También te recomiendo encarecidamente que revises su blog. Utilicé ast.parse para hacer Python-> traductor de JavaScript (@ https://bitbucket.org/amirouche/pythonium ). He creado el diseño de Pythonium revisando un poco otras implementaciones y probándolas por mi cuenta. Bifurqué Pythonium desde https://github.com/PythonJS/PythonJS, que también empecé, en realidad es una reescritura completa. El diseño general está inspirado en PyPy y http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-89-1.pdf .

Todo lo que probé, desde el principio hasta la mejor solución, incluso si parece que el marketing de Pythonium realmente no lo es (no dude en decirme si algo no parece correcto para la netiqueta):

  • Implemente la semántica de Python en el JavaScript antiguo simple utilizando la herencia de prototipo: AFAIK es imposible implementar la herencia múltiple de Python utilizando el sistema de objetos prototipo JS. Intenté hacerlo usando otros trucos más adelante (cf. getattribute). Por lo que sé, no existe una implementación de la herencia múltiple de Python en JavaScript, lo mejor que existe es la herencia única + mixins y no estoy seguro de que manejen la herencia de diamante. Algo similar a Skulpt pero sin google clojure.

  • Probé con Google clojure, al igual que Skulpt (comstackdor) en lugar de leer el código de Skulpt #fail. De todos modos debido al sistema de objetos basado en prototipos JS sigue siendo imposible. Crear un enlace fue muy difícil, necesitas escribir JavaScript y un montón de código repetitivo (ver https://github.com/skulpt/skulpt/issues/50 donde soy el fantasma). En ese momento no había una forma clara de integrar el enlace en el sistema de comstackción. Creo que Skulpt es una biblioteca y solo tienes que incluir tus archivos .py en el html para ejecutar, no es necesario que el desarrollador realice una fase de comstackción.

  • Probé pyjaco (comstackdor) pero crear enlaces (llamar código Javascript desde código Python) fue muy difícil, había mucho código repetitivo para crear cada vez. Ahora creo que Pyjaco es el que más cerca de Pythonium. pyjaco está escrito en Python (ast.parse también) pero mucho está escrito en JavaScript y usa la herencia de prototipo.

Nunca tuve éxito en ejecutar Pajamas #fail y nunca intenté leer el código #fail de nuevo. Pero en mi mente, pijamas estaba haciendo la traducción API-> API (o marco a marco) y no Python a la traducción de JavaScript. El marco de JavaScript consume datos que ya están en la página o datos del servidor. El código de Python es sólo “fontanería”. Después de eso descubrí que el pijama era en realidad un verdadero traductor de python-> js.

Aún así, creo que es posible hacer la traducción API-> API (o framework-> framework) y eso es básicamente lo que hago en Pythonium pero a un nivel inferior. Probablemente los pijamas usan el mismo algoritmo que Pythonium …

Luego descubrí que brython estaba completamente escrito en Javascript como Skulpt, sin necesidad de comstackción y mucha pelusa … pero escrito en JavaScript.

Desde la línea inicial escrita en el curso de este proyecto, conocía PyPy, incluso el backend de JavaScript para PyPy. Sí, puede, si lo encuentra, generar directamente un intérprete de Python en JavaScript desde PyPy. La gente dice, fue un desastre. No leo donde por que Pero creo que la razón es que el lenguaje intermedio que usan para implementar el intérprete, RPython, es un subconjunto de Python diseñado para ser traducido a C (y tal vez asm). Ira Baxter dice que siempre haces suposiciones cuando construyes algo y probablemente lo afinas para ser el mejor en lo que se supone que debe hacer en el caso de la traducción de PyPy: Python-> C. Es posible que esas suposiciones no sean relevantes en otro contexto, peor que pueden sobrepasar los gastos generales, de lo contrario, la traducción directa probablemente siempre será mejor.

Tener el intérprete escrito en Python sonaba como una idea (muy) buena. Pero estaba más interesado en un comstackdor por razones de rendimiento y en realidad es más fácil comstackr Python para JavaScript que interpretarlo.

Comencé con PythonJS con la idea de armar un subconjunto de Python que pudiera traducir fácilmente a JavaScript. Al principio ni siquiera me molesté en implementar el sistema OO debido a la experiencia pasada. El subconjunto de Python que logré traducir a JavaScript es:

  • Funciona con parámetros semánticos completos tanto en definición como en vocación. Esta es la parte de la que estoy más orgulloso.
  • while / if / elif / else
  • Los tipos de Python se convirtieron a tipos de JavaScript (no hay tipos de python de ningún tipo)
  • para iterar sobre matrices de Javascript solamente (para una matriz en)
  • Acceso transparente a JavaScript: si escribe Array en el código de Python, se traducirá a Array en javascript. Este es el mayor logro en términos de usabilidad sobre sus competidores.
  • Puede pasar la función definida en la fuente de Python a las funciones de javascript. Los argumentos por defecto serán tomados en cuenta.
  • Add tiene una función especial llamada new que se traduce a JavaScript new p. Ej .: new (Python) (1, 2, spam, “egg”) se traduce a “new Python (1, 2, spam,” egg “).
  • “var” son manejados automáticamente por el traductor. (muy buen descubrimiento de Brett (contribuyente de PythonJS).
  • palabra clave global
  • cierres
  • lambdas
  • lista de comprensiones
  • las importaciones son compatibles a través de requirejs
  • herencia de una sola clase + mixin via classyjs

Esto parece mucho, pero en realidad es muy estrecho en comparación con la semántica completa de Python. Es realmente JavaScript con una syntax de Python.

El JS generado es perfecto, es decir. no hay sobrecarga, no se puede mejorar en términos de rendimiento al editarlo. Si puede mejorar el código generado, también puede hacerlo desde el archivo fuente de Python. Además, el comstackdor no se basó en ningún truco de JS que pueda encontrar en .js escrito por http://superherojs.com/ , por lo que es muy legible.

El descendiente directo de esta parte de PythonJS es el modo de Pythonium Veloce. La implementación completa se puede encontrar en https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/veloce/veloce.py?at=master 793 SLOC + alrededor de 100 SLOC de código compartido con el otro traductor.

Una versión adaptada de pystones.py se puede traducir en modo Veloce cf. https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pystone/?at=master

Después de haber configurado la traducción básica de Python-> JavaScript, elegí otra ruta para traducir Python completo a JavaScript. La forma de hacer glib haciendo código orientado a clase orientado a objetos, excepto el idioma de destino, es JS, por lo que tiene acceso a matrices, objetos tipo mapa y muchos otros trucos y toda esa parte se escribió en Python. IIRC no hay código javascript escrito en el traductor de Pythonium. Obtener una sola herencia no es difícil, aquí están las partes difíciles que hacen que Pythonium sea completamente compatible con Python:

  • spam.egg en Python siempre se traduce a getattribute(spam, "egg") No hice un perfil de esto en particular, pero creo que getattribute(spam, "egg") mucho tiempo y no estoy seguro de poder mejorarlo con asm.js O algo más.
  • orden de resolución del método: incluso con el algoritmo escrito en Python, traducirlo al código compatible con Python Veloce fue un gran esfuerzo.
  • getattributre : el algoritmo de resolución real de getattribute es un poco complicado y aún no admite descriptores de datos
  • basado en la clase de metaclase: sé dónde conectar el código, pero aún así …
  • último bu no menos importante: some_callable (…) siempre se traduce a “call (some_callable)”. AFAIK el traductor no usa inferencia en absoluto, por lo que cada vez que hace una llamada necesita verificar qué tipo de objeto es para llamarlo de la forma en que debe llamarse.

Esta parte se incluye en https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/runtime.py?at=master. Está escrito en Python compatible con Python Veloce.

El traductor compatible real https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/compliant.py?at=master no genera código JavaScript directamente y lo más importante no hace la transformación ast-> ast . Probé lo de ast-> ast y ast incluso si no es agradable trabajar con ast.st, incluso con ast.NodeTransformer y, lo que es más importante, no necesito hacer ast-> ast.

Hacer python ast to python ast en mi caso al menos podría ser una mejora de rendimiento, ya que a veces inspecciono el contenido de un bloque antes de generar el código asociado con él, por ejemplo:

  • var / global: para poder var algo debo saber lo que necesito y no var. En lugar de generar un seguimiento de bloque, qué variable se crea en un bloque dado e insertarlo en la parte superior del bloque de función generado, solo busco una asignación de variable revelant cuando entro en el bloque antes de visitar el nodo secundario para generar el código asociado.
  • el rendimiento, los generadores tienen, hasta el momento, una syntax especial en JS, así que necesito saber qué función de Python es un generador cuando quiero escribir la “var my_generator = function”

Así que realmente no visito cada nodo una vez para cada fase de la traducción.

El proceso general se puede describir como:

 Python source code -> Python ast -> Python source code compatible with Veloce mode -> Python ast -> JavaScript source code 

Las incorporaciones de Python están escritas en código Python (!), IIRC hay algunas restricciones relacionadas con los tipos de arranque, pero tiene acceso a todo lo que puede traducir Pythonium en modo compatible. Echa un vistazo a https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/builtins/?at=master

Se puede entender la lectura del código JS generado por Pythonium, pero los mapas de origen serán de gran ayuda.

Los valiosos consejos que puedo darles a la luz de esta experiencia son viejos tipos:

  • Revisar ampliamente el tema tanto en literatura como en proyectos existentes de código cerrado o gratuito. Cuando revisé los diferentes proyectos existentes, debería haberle dado más tiempo y motivación.
  • ¡hacer preguntas! Si supiera de antemano que el backend de PyPy era inútil debido a la sobrecarga debido al desajuste semántico de C / Javascript. Tal vez hubiera tenido una idea de Pythonium antes de 6 meses, tal vez hace 3 años.
  • saber lo que quieres hacer, tener un objective. Para este proyecto tenía diferentes objectives: practicar un poco javascript, aprender más de Python y poder escribir código de Python que se ejecutaría en el navegador (más y más abajo).
  • el fracaso es la experiencia
  • un pequeño paso es un paso
  • empieza pequeño
  • Sueño grande
  • hacer demos
  • iterar

¡Solo con el modo Python Veloce, estoy muy feliz! Pero en el camino descubrí que lo que realmente buscaba era liberarme a mí ya otros de Javascript, pero lo más importante es poder crear de una manera cómoda. Esto me llevó a Esquema, DSL, Modelos y, finalmente, modelos específicos de dominio (consulte http://dsmforum.org/ ).

Sobre lo que responde Ira Baxter:

Las estimaciones no son útiles en absoluto. Me tomé más o menos 6 meses de tiempo libre para PythonJS y Pythonium. Así que puedo esperar más de 6 meses a tiempo completo. Creo que todos sabemos lo que 100 años-hombre en un contexto empresarial pueden significar y no significar en absoluto …

Cuando alguien dice que algo es difícil o más a menudo imposible, respondo que “solo se necesita tiempo para encontrar una solución para un problema que es imposible” de lo contrario, no se puede hacer nada, excepto si se demuestra que es imposible en este caso …

Si no se demuestra que es imposible, entonces deja espacio para la imaginación:

  • encontrar una prueba que demuestre que es imposible

y

  • Si es imposible, puede haber un problema “inferior” que puede tener una solución.

o

  • Si no es imposible, encontrar una solución.

No es solo un pensamiento optimista. Cuando empecé con Python-> Javascript todos decían que era imposible. PyPy imposible. Metaclases demasiado duras. etc … Creo que la única revolución que trae PyPy sobre Scheme-> C paper (que tiene 25 años) es una generación automática de JIT (sugerencias basadas en el intérprete de RPython, creo).

La mayoría de las personas que dicen que una cosa es “dura” o “imposible” no proporcionan las razones. C ++ es difícil de analizar? Sé que, todavía son analizadores (gratuitos) de C ++. ¿El mal está en el detalle? Yo sé eso. Decir que es imposible por sí solo no es útil, es incluso peor que “no es útil”, es desalentador y algunas personas pretenden desalentar a otros. Me enteré de esta pregunta a través de https://stackoverflow.com/questions/22621164/how-to-automatically-generate-a-parser-code-to-code-translator-from-a-corpus .

¿Qué sería la perfección para ti ? Así es como define el próximo objective y tal vez scope el objective general.

Estoy más interesado en saber qué tipos de patrones podría aplicar en el código para facilitar la traducción (es decir, ¿IoC, SOA?) Que cómo hacer la traducción.

No veo patrones que no puedan ser traducidos de un idioma a otro, al menos de una manera menos que perfecta. Ya que la traducción de un idioma a otro es posible, es mejor que apuntes primero. Desde entonces, creo que según http://en.wikipedia.org/wiki/Graph_isomorphism_problem , la traducción entre dos lenguajes de computadora es un árbol o isomorfismo DAG. Incluso si ya sabemos que ambos están completos, así que …

Marco-> Marco que mejor visualizo como API-> la traducción de API podría ser algo que debería tener en cuenta como una forma de mejorar el código generado. Por ejemplo: Prolog como una syntax muy específica, pero aún así puede hacer el cálculo Prolog como describiendo el mismo gráfico en Python … Si tuviera que implementar un traductor de Prolog a Python no implementaría la unificación en Python sino en una biblioteca de C y vendría con una “syntax de Python” que es muy legible para un Pythonist. Al final, la syntax es solo “pintura” por lo que le damos un significado (por eso empecé el esquema). El mal está en el detalle del lenguaje y no estoy hablando de la syntax. Los conceptos que se usan en el lenguaje getattribute hook (puede vivir sin él) pero las funciones de VM requeridas, como la optimización de recursión de cola, pueden ser difíciles de tratar. No importa si el progtwig inicial no usa la recursión de la cola e incluso si no hay una recursión de la cola en el idioma de destino, puede emularlo utilizando los bucles de sucesos de Greenlets.

Para los idiomas de destino y de origen, busque:

  • Ideas grandes y especificas.
  • Pequeñas y comunes ideas compartidas.

De esto surgirá:

  • Cosas que son fáciles de traducir.
  • Cosas que son difíciles de traducir.

Probablemente, también podrá saber qué se traducirá a código rápido y lento.

También está la cuestión de la biblioteca estándar o de cualquier biblioteca, pero no hay una respuesta clara, depende de sus objectives.

El código idiomático o el código generado legible también tienen soluciones …

Dirigirse a una plataforma como PHP es mucho más fácil que apuntar a los navegadores, ya que puede proporcionar una implementación en C de una ruta lenta y / o crítica.

Dado que el primer proyecto es traducir Python a PHP, al menos para el subconjunto de PHP3 que conozco, personalizar a veloce.py es su mejor opción. Si puede implementar veloce.py para PHP, entonces probablemente podrá ejecutar el modo compatible … Además, si puede traducir PHP al subconjunto de PHP, puede generar con php_veloce.py, esto significa que puede traducir PHP al un subconjunto de Python que veloce.py puede consumir, lo que significa que puedes traducir PHP a Javascript. Solo digo…

También puedes echar un vistazo a esas bibliotecas:

También puede interesarle esta publicación de blog (y comentarios): https://www.rfk.id.au/blog/entry/pypy-js-poc-jit/

Puede echar un vistazo al comstackdor Vala , que traduce Vala (un lenguaje similar a C #) a C.