
Bonjour à ceux qui ont décidé de lire mon prochain article.
Tout d'abord, je poste des liens vers les parties précédentes:
Partie 1: écrire une machine virtuelle de languePartie 2: présentation intermédiaire des programmesPartie 3: Architecture du traducteur. Analyse des structures du langage et des expressions mathématiquesIl vaut également la peine de publier des liens vers le
référentiel et vers un
petit article de synthèse dans lequel j'ai brièvement décrit le travail effectué dans son intégralité.
Ainsi, dans le dernier article, j'ai décrit la création d'un traducteur à partir d'un langage de programmation plus ou moins avancé dans une représentation intermédiaire et un assemblage ultérieur de l'application.
Nous sommes maintenant confrontés à la tâche d'ajouter des structures et des classes au langage afin qu'il ait la fonctionnalité d'analogues modernes. Cet article ne fournira pas le code décrit
fonctionnalité depuis c'est beaucoup, c'est assez ennuyeux et tout le monde ne sera pas intéressé à s'y plonger. Seule théorie. Et quelques photos.
Commençons à créer ...
Vue de classe
Il convient de commencer par le fait que toute structure peut être représentée sous forme de tableau. L'index d'un élément de tableau peut être associé à une variable de classe particulière ou à sa méthode.
Prenons un exemple de code simple (naturellement sur Mash):

Voici un exemple simple d'une classe qui stocke des copies des valeurs de a et b, qui lui sont passées dans le constructeur. Il possède également un destructeur et une fonction somm qui renverra la somme de a et b.
Mais dans la représentation intermédiaire, il n'y a pas de POO, et encore plus au niveau VM.
Si nous regardons un peu plus en profondeur pour voir ce qu'est réellement MyClass, alors nous verrons l'image suivante:

Super. Le traducteur, à travers de simples manipulations et sorts, transforme notre structure en un simple tableau.
Typage dynamique pour les classes
Il convient également de réfléchir au paramètre de type dynamique rapide pour les classes et au travail correspondant avec elles, car dans les langues avec typage dynamique, c'est un point très important.
La solution la plus simple et la plus efficace est une table virtuelle de composants de classe. C'est-à-dire dans le traducteur, vous pouvez implémenter le traitement de toutes les définitions de classe et faire une liste des noms et méthodes des variables de classe. En conséquence, nos classes sont représentées sous forme de tableaux - chaque nom de la liste est comparable à un index. Lorsque vous remplissez la liste des noms, vous pouvez spécifier la taille du tableau pour chaque classe, pour une allocation de mémoire plus économique.
Allocateurs de classe de base
Pour pouvoir utiliser une classe avec une table de méthode virtuelle, en plus d'allouer simplement de la mémoire, vous devez remplir cette table de pointeurs vers les points d'entrée des méthodes de classe.
Un moyen simple et efficace consiste à générer un allocateur pour chaque classe. Il s'agit d'une méthode simple qui alloue de la mémoire à un tableau de la structure de classe, la remplit partiellement et renvoie un pointeur sur la classe.
Les allocateurs sont appelés lorsqu'une instance de la classe est créée, c'est-à-dire dans l'exemple ci-dessus, l'appel sera effectué sur la 24e ligne - «new MyClass (10, 20)». Après l'allocateur, vous pouvez appeler le constructeur de la classe. Dans Mash, le constructeur est appelé si la nouvelle construction contient des crochets (...) après le nom de la classe.
Introspection
Il est possible que tout le monde ne connaisse pas cette définition, mais beaucoup sont tombés sur.
Introspection - la définition du type d'objet avec lequel le travail est effectué pendant l'exécution du code. Un exemple est typeof () dans le même JavaScript.
La purée a une introspection complète, c'est-à-dire pour les types de données simples et pour les classes.
Sans plus tarder, voici quelques exemples de code:

Et pour la classe:

L'introspection pour les classes est implémentée en ajoutant un type au champ de chaque classe - un pointeur sur son type.
Achèvement
J'ai essayé d'expliquer dans un langage simple comment le travail avec les classes est organisé dans mon traducteur Mash. Une technologie similaire est également inhérente à de nombreuses autres langues avec typage dynamique.
J'espère que cet article vous intéresse. Merci de l'avoir lu jusqu'au bout si vous l'avez fait. Pour le moment, c'était peut-être mon dernier article sur la création du langage Mash (tant que je ne maîtrise pas la compilation JIT). Mes articles suivants examineront d'autres aspects du projet, ou se rapporteront à d'autres sujets.