Написание простого DSL компилятора на Delphi (0. Введение)

Перевод поста Writing a Simple DSL Compiler with Delphi (0. Introduction)

Некоторое время назад я слушал подкаст Hanselminutes (YOU should write an interpreter with Thorsten Ball) где парень описал как он написал простой интерпретатор на языке Go. В действительности, меня не очень интересовало написание интерпретатора — я уже делал это однажды — но мысль закралась мне в голову. Я спросил себя смогу ли я сделать что-то лучше — написать компилятор (или что-то похожее на компилятор, как вы увидите дальше).

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

Скажем, у меня есть простоя программа написанная на моём языке которая складывает два числе вместе

Простой, С-подобный синтаксис. Не сложно угадать, что функция складывает два числа и возвращает результат.

Я хочу чтобы мой код конвертировал это в что-то похожее на это (и я здесь сильно упрощаю, в действительности код будет более сложный):

Для запуска программы, я могу вызывать prog([1,2]) и я получу 3 в результате.

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

Теперь более понятно, почему я назвал мой компилятор "что-то вроде компилятора". Он не компилирует программу в CPU-исполняемый формат, а использует очень специфичную среду времени выполнения — набор функций скомпилированных в Delphi программу и он не может быть сохранен как отдельно запускаемое приложение. За исключением всех ограничений, это мощная техника, запускаемый код быстрее чем простой интерпретатор того же языка. Но я захожу вперёд.

Эта статья просто введение в серию в которой я буду медленно презентовать мой проект. На данный момент запланированы следующие статьи:

  1. Язык
  2. Абстрактное синтаксическое дерево (AST)
  3. Токинизатор
  4. Парсер
  5. Фреймворк
  6. AST Dumper
  7. Компилятор AST
  8. Интерпретатор AST
  9. Ускорение исполнения и расширение языка
  10. Ускорение интерпретатора

Нетерпеливые могут найти весь код и демонстрационный проект на GitHub.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *