Question

J'ai été la programmation en Ruby pendant un certain temps maintenant avec juste l'implémentation standard IRM de Ruby, mais je suis toujours curieux de savoir les autres implémentations que j'entends tant.

Je lisais Rubinius l'autre jour, un interpréteur Ruby écrit en Ruby. J'ai essayé de regarder vers le haut en divers endroits, mais j'avais du mal à comprendre exactement comment quelque chose comme cela fonctionne. Je ne l'ai jamais eu beaucoup d'expérience dans les compilateurs ou l'écriture de la langue, mais je suis vraiment intéressé à comprendre.

Comment exactement une langue peut être interprétée par lui-même? Y at-il une étape fondamentale dans la compilation que je ne comprends pas où cela a du sens? Quelqu'un peut-il expliquer cela à moi comme je suis un idiot (parce que ce ne serait pas trop loin hors de la base de toute façon)

Était-ce utile?

La solution

Il est plus simple que vous le pensez.

Rubinius est pas 100% écrit en Ruby, juste la plupart du temps.

De http://rubini.us/

  

Un grand aspect des langues populaires tels que C et Java est que la majorité des fonctionnalités disponibles pour le programmeur est écrit dans la langue elle-même. Rubinius a pour but d'ajouter à cette liste Ruby. Rubyistes pourrait ajouter plus facilement des fonctionnalités à la langue, les bugs fixes, et apprendre comment la langue fonctionne. Dans la mesure du possible Rubinius est écrit en Ruby. Où pas possible (encore), il est C ++.

Autres conseils

Le concept que vous recherchez est compilateur bootstrapping .

bootstrapping Fondamentalement, des moyens d'écriture d'un compilateur (ou un interprète) pour la langue x dans la langue x . Cela se fait soit en écrivant un compilateur de base à un niveau inférieur à la main (à savoir l'écriture d'un compilateur C à l'Assemblée), ou en utilisant un autre langage de haut niveau.

En savoir plus sur bootstrapping sur wikipedia . La réponse de Greg concernant les évaluateurs de méta-circulaire est également fortement recommandé, y compris le chapitre correspondant SICP.

En cas de Rubinius, la machine virtuelle est écrit en C ++ et traite tous les lowlevel (système d'exploitation liés) opérations de substance et base. La machine virtuelle a son propre format bytecode (comme la machine virtuelle Java a son propre bien) et quand Rubinius est démarré il commence la machine virtuelle qui exécute le bytecode. La plupart de la bibliothèque standard de Rubinius (qui fait partie de Ruby la langue) est mis en œuvre en Ruby cependant, par rapport à C (IRM) ou Java (JRuby). En outre, le compilateur bytecode Rubinius est également écrit en Ruby. Alors oui, à un moment donné très tôt au début, ils devaient utiliser l'interpréteur Ruby standard (IRM) pour l'amorçage Rubinius. Mais cela ne devrait pas être le cas plus (bien que je ne sais pas si vous pourriez encore avoir besoin depuis son utilisation accumulation système râteau).

Supposons que la langue que vous travaillez avec une certaine langue, dire Lisp, mais il n'a pas d'importance. (Peut-être C ++, Java, Ruby, rien.)

Eh bien vous avez une implémentation de Lisp. Appelez cette mise en œuvre Imp (quelques-uns composé nom court pour la mise en œuvre). Depuis Imp est un programme en lui-même, votre ordinateur peut exécuter. Maintenant, vous écrivez votre propre implémentation pour Lisp écrit en Lisp et vous l'appelez Circ. Circ est juste un programme compilé (ou interprété si vous voulez) à partir du code Lisp. Votre code est écrit de sorte qu'il lit dans un fichier, il parse (processus en données significatives), et fait quelque chose avec les données. Quel est ce quelque chose? Dans le cas de Circ, il exécute les données.

Mais comment fait-elle donc?

Et bien supposons que pour un cas simple, que le code Circ lit et Parsis est quelque chose de simple comme faire un peu de mathématiques et sortir le résultat. Circ traite le code dans les données facile à utiliser (bien pour une langue comme Lisp il est facile de commencer, mais qui est au-delà du point) et le stocke. Eh bien en Lisp, vous pouvez écrire du code pour les numéros de crunch, de sorte que le code écrit pour Circ peut le faire aussi parce qu'il est écrit en Lisp. Ainsi, les données traitées est branché à un code de traitement d'addition ... et le tour est joué! Vous avez le résultat numérique! Ensuite, votre programme Circ affiche le résultat.

La même chose peut être fait avec des choses plus complexes que les mathématiques simples. En fait, vous pouvez compiler / interpréter d'autres aspects de la langue. assez d'écriture de ces « autres aspects » et les coller ensemble, vous obtenez un compilateur pour un Lisp écrit en Lisp.

Étant donné que le compilateur est compilé par Imp, il peut être exécuté par la machine, et presto! Vous avez terminé.

Cette technique est appelée généralement un évaluateur metacircular et a été introduit il y a plusieurs décennies dans le contexte de Lisp.

Une bonne description de la technique peut être trouvée dans Structure et interprétation des programmes de l'ordinateur, chapitre 4.

scroll top