Escribimos nuestro lenguaje de programación, parte 4: Representación de estructuras y clases, generación de asignadores.

imagen

Buen día a quienes decidieron leer mi próximo artículo.

En primer lugar, publico enlaces a las partes anteriores:
Parte 1: escribir un lenguaje VM
Parte 2: presentación intermedia de programas
Parte 3: Arquitectura del traductor. Análisis de estructuras del lenguaje y expresiones matemáticas.

También vale la pena publicar enlaces al repositorio y a un pequeño artículo de revisión en el que describí brevemente el trabajo realizado en su totalidad.

Entonces, en el último artículo describí la creación de un traductor de un lenguaje de programación más o menos de alto nivel en una representación intermedia y un mayor ensamblaje de la aplicación.

Ahora nos enfrentamos a la tarea de agregar estructuras y clases al lenguaje para que tenga la funcionalidad de los análogos modernos. Este artículo no proporcionará el código descrito
funcionalidad desde es mucho, es bastante aburrido y no todos estarán interesados ​​en profundizar en ello. Solo teoria. Y algunas fotos.

Comencemos a crear ...


Vista de clase


Vale la pena comenzar con el hecho de que cualquier estructura se puede representar como una matriz. El índice de un elemento de matriz se puede asociar con una variable de clase particular o su método.

Considere un ejemplo de código simple (naturalmente en Mash):
imagen

Aquí hay un ejemplo simple de una clase que almacena copias de los valores de a y b, que se le pasan en el constructor. También tiene un destructor y una función summ que devolverá la suma de a y b.
Pero en la representación intermedia no hay OOP, y aún más en el nivel de VM.
Si miramos un poco más profundo para ver qué es realmente MyClass, veremos la siguiente imagen:
imagen

Genial El traductor, a través de simples manipulaciones y hechizos, convierte nuestra estructura en una simple matriz.

Typing dinámico para clases


También vale la pena pensar en la configuración de tipo dinámico rápido para las clases y el trabajo correspondiente con ellas, porque en los idiomas con escritura dinámica este es un punto muy importante.

La solución más simple y efectiva es una tabla virtual de componentes de clase. Es decir en el traductor, puede implementar el procesamiento de todas las definiciones de clase y hacer una lista de nombres y métodos de variables de clase. En consecuencia, desde nuestras clases están representadas en forma de matrices: cada nombre de la lista es comparable a un índice. A medida que completa la lista de nombres, puede especificar el tamaño de la matriz para cada clase, para una asignación de memoria más económica.

Asignadores de clase básica


Para poder utilizar una clase con una tabla de método virtual, además de simplemente asignar memoria, debe completar esta tabla con punteros a los puntos de entrada a los métodos de clase.

Una forma simple y funcional es generar un asignador para cada clase. Este es un método simple que asigna memoria para una matriz de la estructura de la clase, la llena parcialmente y devuelve un puntero a la clase.

Los asignadores se llaman cuando se crea una instancia de la clase, es decir en el ejemplo anterior, la llamada se realizará en la línea 24: "nueva MyClass (10, 20)". Después del asignador, puede llamar al constructor de la clase. En Mash, se llama a un constructor si hay paréntesis (...) después del nombre de la clase en la nueva construcción.

Introspección


Es posible que no todos estén familiarizados con esta definición, pero muchos se han encontrado.
Introspección: la definición del tipo de objeto con el que se realiza el trabajo durante la ejecución del código. Un ejemplo es typeof () en el mismo JavaScript.


Mash tiene una introspección completa, es decir para tipos de datos simples y para clases.
Sin más preámbulos, aquí hay algunos ejemplos de código:
imagen

Y para la clase:
imagen

La introspección para las clases se implementa agregando un tipo al campo de cada clase: un puntero a su tipo.

Finalización


Traté de explicar en un lenguaje simple cómo se organiza el trabajo con las clases en mi traductor de Mash. Una tecnología similar también es inherente a muchos otros idiomas con escritura dinámica.

Espero que encuentres este artículo interesante. Gracias por leerlo hasta el final si lo hiciste. Por el momento, este fue quizás mi último artículo sobre la creación del lenguaje Mash (siempre y cuando no domine la compilación JIT). Mis artículos posteriores considerarán otros aspectos del proyecto o se relacionarán con otros temas.

Source: https://habr.com/ru/post/es436224/


All Articles