J'ai créé plusieurs compilateurs écrits à la main pour des langages très simples mais maintenant je veux m'essayer au développement d'un langage dynamique, similaire à un Python ou Ruby simplifié. Cependant, il m'a été facile de comprendre comment fonctionnent les compilateurs. Les compilateurs primitifs ne font que traduire. Mais je ne peux pas faire ça si la langue est dynamique. Je dois écrire un interprète ou une machine virtuelle qui garde la trace des informations au moment de l'exécution et me met beaucoup plus de travail.
En bref, y a-t-il des ressources que je devrais vérifier étant donné que je sais comment fonctionnent les compilateurs mais que je souhaite migrer vers la création d'un interprète? Il existe quelques machines virtuelles pour les langages dynamiques, mais je n'ai aucun problème avec le mien. C'est juste pour mon expérience personnelle.
Je cherche des informations sur la façon de passer d'un compilateur à un interprète. Si j'ai déjà fait un compilateur pour la langue X mais maintenant quoi écrire un interprète, que faut-il faire et y a-t-il des ressources qui vont au cours du processus?
Je ne veux pas de ressources étendues ou abstraites sur le fonctionnement des compilateurs ou des machines virtuelles. J'ai plein de manuels sur le sujet. Toutes les ressources que j'ai trouvées en ligne supposent que vous avez 0 expérience et vous commencent donc par une analyse lexicale ou syntaxique ou elles sont extrêmement abstraites. J'ai un compilateur qui fonctionne, mais je veux maintenant le transformer en interprète et ajouter des fonctionnalités dynamiques au langage.
Je n'ai pas pu trouver de ressources sur ce processus, il peut être de portée trop limitée, ou de ressources sur le "back end" d'un interprète sans être trop théorique c'est pourquoi j'ai posté ici.
la source
Réponses:
Apprenez d'abord à implémenter des interprètes. Je recommande PLAI (langages de programmation: application et interprétation) . Il arrive rapidement à la chair d'interprétation sans s'attarder trop sur la syntaxe.
Pour votre langage, vous pourrez réutiliser la bibliothèque frontale du compilateur (analyseur, principalement) et la bibliothèque d'exécution (GC, structures de données, opérations primitives, etc.).
Bien sûr, vous pouvez également implémenter un langage dynamique avec un compilateur qui produit du code qui manipule (certaines) les mêmes structures de données que vous utiliseriez dans un interpréteur. Par exemple, dans un interpréteur, vous pouvez implémenter des variables globales sous forme de table de hachage indexée sur des chaînes. Dans un compilateur, vous compileriez des références de variables globales dans le code qui effectue la recherche en utilisant la même table. En revanche, vous pourriez compiler des variables lexicales dans une représentation plus efficace (arguments "natifs" et références de structure de fermeture).
la source
Si vous voulez apprendre les bases de l'implémentation d'un interpréteur pour un langage dynamique, je ne peux pas imaginer un meilleur endroit pour commencer que les origines du tout premier langage de programmation interprété dynamique: Lisp.
Dans son article original de 1960 , John McCarthy a défini 5 fonctions primitives nécessaires à un Lisp. Bien sûr, McCarthy ne voulait que son article sur Lisp comme un exercice académique; c'est un étudiant diplômé qui a implémenté l'
eval
assemblage et créé le premier interprète Lisp. Paul Graham identifie sept primitives : quote, atom, eq, cons, car, cdr et cond.Le fait est que vous pouvez vraiment implémenter Lisp dans n'importe quelle langue; une fois que vous avez implémenté
eval
, il est facile de configurer un REPL et vous disposez d'un interprète interactif . Les gens se sont ennuyés ou ont été assez curieux pour implémenter Lisps en C, Java, Ruby, Python et bien d'autres langages. Et pas toujours exprès; il est important de se rappeler la dixième règle de Greenspun :Je ne dis pas que votre objectif final devrait être une implémentation Lisp; mais l'homoiconicité a ses avantages lorsqu'on apprend à mettre en œuvre un langage dynamique; pourquoi faire face à des problèmes de syntaxe quand vous pouvez apprendre sur une langue dans laquelle la syntaxe idiomatique est identique à l'AST d'une langue qui utilise un lexer / analyseur?
Quoi qu'il en soit ... juste une suggestion. Mais c'est à juste titre que la plupart des grands langages de programmation depuis C ont au moins un peu de nature Lisp.
la source
J'ai mis cela (~ 600 lignes de C #) dans le domaine public, qui prend en charge quote / list / apply / eval / test / etc, et permet de personnaliser facilement une syntaxe de type Lisp et / ou les constructions sémantiques:
https://repl.it/CdjV/3
Par exemple:
«HTH,
la source
En supposant que vous connaissiez un peu Scheme (par exemple avoir lu SICP ) ou Lisp, je recommande le livre Lisp In Small Pieces de Queinnec . Il explique plusieurs variantes d'interprètes et de compilateurs de type Lisp (y compris le bytecode ou le C).
Lisez également la programmation du langage de programmation de Scott , le dernier Dragon Book , le manuel du GC , les types et les langages de programmation de Pierce .
Ensuite, une évaluation partielle (et projections Futamura) et un style de passage de continuation pourraient être pertinents.
la source