Пишем свой язык программирования, часть 4: Представление структур и классов, генерация аллокаторов

image

Доброго времени суток тем, кто решил ознакомиться с моей очередной статьёй.

Первым делом выкладываю ссылки на предыдущие части:
Часть 1: пишем языковую ВМ
Часть 2: промежуточное представление программ
Часть 3: Архитектура транслятора. Разбор языковых структур и математических выражений

Также стоит выложить ссылки на репозиторий и на небольшую обзорную статью, в которой я вкратце описал проделанную работу целиком.

Итак, в прошлой статье я описывал создание транслятора с более-менее высокоуровневого языка программирования в промежуточное представление и дальнейшую сборку приложения.

Сейчас перед нами стоит задача добавления в язык структур и классов, для того чтобы он имел функциональность современных аналогов. В данной статье не будет приведен код описываемой
функциональности, т.к. его много, он довольно скучный и далеко не всем будет интересно в нем копаться. Только теория. И немного картинок.

Начнем творить…

Представление класса


Стоит начать с того, что любая структура может быть представлена в виде массива. Индекс элемента массива может быть ассоциирован с определенной переменной класса или с его методом.

Рассмотрим простой пример кода (естественно на Mash):
image

Перед нами простой пример класса, который хранит копии значений a и b, которые передают ему в конструктор. Он также имеет деструктор и функцию summ, которая вернет сумму a и b.
Но в промежуточном представлении отсутствует какое-либо ООП, а уж на уровне ВМ тем более.
Если мы заглянем чуть глубже, чтобы посмотреть, что на самом деле представляет из себя MyClass, то мы увидим примерно следующую картину:
image

Отлично. Транслятор, путем несложных манипуляций и заклинаний превращает нашу структуру в простой массив.

Динамическая типизация для классов


Стоит также подумать о быстром динамическом установлении типов для классов и соответствующей работы с ними, ведь в языках с динамической типизацией это очень важный момент.

Самое простое и эффективное решение — виртуальная таблица классовых составляющих. Т.е. в трансляторе можно реализовать обработку всех определений классов и составить список из имен классовых переменных и методов. Соответственно, т.к. классы у нас представляются в виде массивов — каждое имя из списка сопоставимо с индексом. По мере заполнения списка имен — можно указывать размер массива для каждого класса, для более экономичного выделения памяти.

Базовые аллокаторы для классов


Для того, чтобы можно было использовать класс с виртуальной таблицей методов, помимо простого выделения памяти, нужно эту таблицу заполнить указателями на точки входа в методы класса.

Простой и рабочий способ — генерировать для каждого класса аллокатор. Это простой метод, который выделяет память под массив структуры класса, частично заполняет её и возвращает указатель на класс.

Аллокаторы вызываются при создании экземпляра класса, т.е. в примере выше вызов будет произведен на 24-й строке — «new MyClass (10, 20)». После аллокатора можно вызвать конструктор класса. В Mash вызов конструктора осуществляется в том случае, если в конструкции new присутствуют скобки (…) после имени класса.

Интроспекция


Возможно, что с этим определением знакомы не все, но многие сталкивались.

Интроспекция — определение типа объекта, с которым ведется работа во время выполнения кода. Пример — typeof () в том же JavaScript.

В Mash присутствует полная интроспекция, т.е. для простых типов данных и для классов.
Без лишних слов, приведу примеры кода:
image

И для класса:
image

Интроспекция для классов реализована путем добавления в поле каждого класса type — указатель на его тип.

Завершение


Я постарался простым языком рассказать, как организована работа с классами в моём трансляторе языка Mash. Подобная технология также присуща многим другим языкам с динамической типизацией.

Надеюсь, что эта статья была вам интересна. Спасибо, что дочитали её до конца, если вы это сделали. На данный момент это была пожалуй последняя моя статья посвященная созданию языка Mash (До тех пор, как не осилю JIT компиляцию). Последующие мои статьи будут рассматривать другие аспекты проекта, либо и вовсе будут относиться к другим темам.

© Habrahabr.ru