Créer un langage de programmation JVM

91

J'ai créé un compilateur en C (en utilisant lex & bison) pour un langage de programmation typé dynamique qui prend en charge les boucles, les déclarations de fonctions à l'intérieur des fonctions, les appels récursifs, etc. J'ai également créé une machine virtuelle qui exécute le code intermédiaire créé par le compilateur.

Je pensais maintenant au lieu de compiler vers mon propre code intermédiaire, compilez-le en java byte code.

J'ai vu que la question sur la création d'un langage JVM a déjà été posée mais je ne trouve pas la réponse très informative.

Donc, voici mes questions:

  1. Je suppose que pour créer un langage pour JVM, un must est de lire le livre de spécifications JVM , quels autres livres pouvez-vous suggérer (sauf Dragon Book bien sûr)? Je suis surtout préoccupé par les livres ou les tutoriels sur la façon de créer un langage JVM, pas un compilateur en général.
  2. Il existe de nombreuses bibliothèques Java pour lire, écrire et modifier des fichiers .class comme jclasslib , bcel , gnu bytecode , etc. Laquelle suggérez-vous? Connaissez-vous également les bibliothèques C qui font le même travail?
  3. Je pensais jeter un œil à peut-être un autre langage qui cible la JVM comme Clojure, Jython ou JRuby. Mais tous ces langages sont de très haut niveau et compliqués (pour créer un compilateur pour eux). Je cherchais un langage de programmation plus simple (cela ne me dérange pas s'il est inconnu ou inutilisé) qui cible la JVM et son compilateur est open source. Des idées?
fonctionnel
la source

Réponses:

61

Je recommanderais aussi ASM, mais jetez un œil à Jasmin , je l'ai utilisé (ou: je devais l'utiliser) pour un projet universitaire, et cela fonctionne assez bien, j'ai écrit une combinaison lexer / parse / analyseur / optimiseur / générateur pour un langage de programmation utilisant java et jasmin, générant ainsi du code JVM. J'ai téléchargé le code ici , la partie intéressante devrait être le code source lui-même . Dans le dossier "bytecode / InsanelyFastByteCodeCreator.java", vous trouvez un morceau de code qui transforme un arbre AST au format d'entrée de l'assembleur jasmin. Est assez simple.

Le langage source (qui a été transformé en AST par Lexer + Parser + Analyzer) est un sous-ensemble de Java appelé MiniJava. Il manque certaines fonctionnalités "compliquées" comme l'héritage, les constructeurs, les méthodes statiques, les champs / méthodes privés. Aucune de ces fonctionnalités n'est difficile à implémenter, mais il y avait une autre tâche pour écrire un backend X86 (donc pour générer un assembleur de machine), et ces choses ont tendance à devenir difficiles si vous n'avez pas de JVM qui gère certaines choses.

Au cas où vous vous interrogeriez sur l'étrange nom de la classe: La tâche du projet universitaire était de transformer l'AST en un graphique SSA (donc un graphique représentant le code d'entrée), puis d'optimiser le graphique et de le transformer en code octet java. Cela représentait environ 3/4 du travail du projet et InsanlyFastByteCodeCreator n'était qu'un raccourci pour tout tester.

Jetez un œil au livre "Java Virtual Machine" de Jon Meyer et Troy Downing. Ce livre fait fortement référence au Jasmin-Assembler, il est très utile pour comprendre les composants internes de la JVM.

theomega
la source
Merci pour votre réponse, je vais jeter un oeil à Jasmin. Et aussi je serais heureux si vous pouviez télécharger la source pour que je puisse y jeter un coup d'œil. À propos du livre que vous avez suggéré, il semble intéressant mais il est épuisé et assez vieux :(.
Le livre est cependant d'occasion très bon marché. J'en ai trouvé une copie pour quelques dollars.
namin
Jetez un œil à ma modification ci-dessus, si vous avez des questions, je serai heureux de vous aider.
theomega
Le lien vers le "code source lui-même" est rompu. Bien que je suppose que c'est à prévoir après 8 ans.
Llew Vallis
@LlewVallis, si j'interprète toutes les informations correctement, le code semble être ici: github.com/replimoc/compiler .
U880D
14

Le semestre dernier, j'ai suivi un cours "Compiler Construction". Notre projet était exactement ce que vous vouliez faire.

La langue que j'ai utilisée pour écrire ma langue était le Scala . Il fonctionne sur une JVM mais prend en charge de nombreuses fonctionnalités avancées que Java ne fait pas (toujours entièrement compatible avec une JVM pure java).

Pour générer le bytecode java, j'ai utilisé la bibliothèque Scala CAFEBABE . Bien documenté et vous n'avez pas besoin d'aller au fond des classes Java pour comprendre ce qu'il faut faire.

À côté du livre, je pense que vous pouvez trouver beaucoup d'informations en parcourant les laboratoires que nous avons faits pendant le cours.

Kami
la source
Cela ressemble à un excellent cours. Pourriez-vous partager vos notes ou votre code?
Pedro
1
Pas de problème, je vais vérifier où se trouvent mes sauvegardes et poster un lien ici pour que vous puissiez les télécharger dès que possible.
Kami
1
Bien, je cherchais un cours de compilation pratique qui cible la JVM avec tout le matériel en ligne pour l'auto-apprentissage.
namin
5

ASM peut être une solution pour générer du bytecode. Pour commencer, consultez les rubriques sur la génération d' éléments dans le manuel .

h3xStream
la source
4

Je pensais jeter un œil à peut-être un autre langage qui cible la JVM comme Clojure, Jython ou JRuby. Mais tous ces langages sont de très haut niveau et compliqués (pour créer un compilateur pour eux).

Suggestion: Vous pouvez jeter un œil au langage de programmation Lua , il existe des implémentations JVM comme LuaJ .

Interpréteur Lua léger , rapide et centré sur Java écrit pour J2ME et J2SE, avec des bibliothèques pour les packages de base, string, table, package, math, io, os, debug et coroutine, un compilateur , des liaisons luajava et un moteur de script enfichable JSR-233 fixations.

(À ne pas confondre avec LuaJava qui utilise une bibliothèque native avec une approche JNI.)

Bakkal
la source
Je vous remercie. Je vais jeter un oeil
3

Le week-end dernier, je me posais la même question pour porter mon langage jouet sur la JVM.

Je ne passe que quelques heures à chercher des informations, alors prenez ces références avec un grain de sel.

  • Modèles d'implémentation du langage . Je déteste antlr mais ce livre a l'air très bien. Si vous n'aimez pas non plus antlr, il y a une très bonne analyse "Techniques d'analyse. Un guide pratique."

    Apprenez à créer des lecteurs de fichiers de configuration, des lecteurs de données, des générateurs de code basés sur des modèles, des traducteurs source-source, des analyseurs de source et des interpréteurs. Vous n'avez pas besoin d'une formation en informatique - le créateur d'ANTLR Terence Parr démystifie l'implémentation du langage en la décomposant en modèles de conception les plus courants. Modèle par modèle, vous apprendrez les compétences clés dont vous avez besoin pour implémenter vos propres langages informatiques.

    Le chapitre 10 couvre en 30 pages (à IMO rapide) ces sujets. Mais il y a un autre chapitre qui vous intéressera probablement.

    • 10 Construire des interpréteurs de bytecode
      • 10.1 Programmation des interpréteurs de bytecode. .
      • 10.2 Définition d'une syntaxe de langage d'assemblage
      • 10.3 Architecture de la machine Bytecode. . . . .
      • 10.4 Où aller à partir d'ici. . . . . . . . . .
      • P.26. Assembleur de bytecode. . . . . . . . . . .
      • P.27. Interpréteur de bytecode basé sur la pile. . .
      • P.28. Interpréteur de bytecode basé sur le registre
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • L'implémentation de Lua 5.0 Ceci est un excellent article sur les machines à bytecode basées sur des registres. Allez le lire même pour le plaisir.

    • Lisp en petits morceaux. Ce livre enseigne comment écrire 2 compilateurs schme qui se compilent en C. Tant de leçons peuvent être tirées de ce livre. Je possède un exemplaire de ce livre et il est vraiment bon pour tous ceux qui sont intéressants, mais peut-être pas votre tasse de thé.

      Ceci est un compte rendu complet de la sémantique et de l'implémentation de toute la famille de langages Lisp, à savoir Lisp, Scheme et les dialectes associés. Il décrit 11 interprètes et 2 compilateurs ...

    http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521562473

Vérifiez la VM Dalvik7, une VM basée sur des registres. Le DVM fonctionne sur des bytecodes qui sont transformés à partir des fichiers de classe Java compilés par un compilateur Java.

Il existe une liste de diffusion sur le sujet, jvm-languages.

Envisagez-vous de télécharger le code n'importe où? Je voudrais jeter un oeil.

Pedro
la source
Are you planning to upload the code to anyplace?Je ne suis pas fier de ce code: (... Je réécrirais peut-être tout. De toute façon, si je le fais, je vous le ferai savoir. Merci beaucoup pour vos suggestions.
2

Je vous recommande d'apprendre d'abord comment fonctionne l'assemblage JVM, si vous ne le connaissez pas déjà.

De nombreuses instructions ont la forme ?name, où ?est isi l'instruction fonctionne avec un type entier et asi elle fonctionne avec un type référence.

Fondamentalement, JVM est une machine de pile sans registre, donc toutes les instructions fonctionnent avec des données directement sur la pile. Vous pouvez pousser / pop des données avec ?push/?popet déplacer des données entre des variables locales (emplacements de pile référencés par des décalages) et le haut de la pile en utilisant ?store/?load. Certaines autres instructions importantes sont invoke???et if_???.

Pour le cours de compilation de mon université, nous avons utilisé Jasmin pour assembler les programmes. Je ne sais pas si c'est la meilleure façon, mais au moins c'est un point de départ facile.

Voici une référence d'instructions pour une ancienne version de la JVM, qui peut contenir moins d'instructions qu'une nouvelle.

Jørgen Fogh
la source
0

Tout d'abord, je reculerais, modifierais mon compilateur pour générer Java réel au lieu de codes d'octets Java (ce qui signifie créer plus d'un traducteur que d'un compilateur), et compiler la sortie Java avec n'importe quel environnement Java pratique (ce qui générerait probablement un meilleur code objet que mon propre compilateur).

Vous pouvez utiliser la même technique (par exemple, compiler en C #) pour générer des codes d'octet CLI, ou compiler en Pascal pour générer du code P, etc.

On ne sait pas pourquoi vous envisagez d'utiliser des codes Java au lieu d'utiliser votre propre machine virtuelle, mais si c'est pour les performances, vous devriez bien sûr également envisager de compiler le code machine réel.

Joe Snyder
la source
La compilation pour la JVM permettra à son code d'être exécuté plus largement que si l'on compile en code natif. De plus, la compilation en bytecode permettra au code de faire certaines choses qui ne sont pas possibles dans le langage Java lui-même.
supercat
0

Bien sûr, une fois pourrait utiliser Java pour écrire un nouveau langage. Avec l'API de réflexion Java, vous pouvez obtenir un llot. Si la vitesse n'a pas trop d'importance, je donnerais la préférence à Java au lieu d'ASM. La programmation est plus facile et moins sujette aux erreurs en Java (IMHO) . Jetez un œil à la 7e langue RPN . Il est entièrement écrit en Java.

Kaplan
la source