lumen
Динамически типизированный скриптовый язык на Kotlin. Исходник сканируется, парсится в AST, компилируется в байткод и выполняется на стековой виртуальной машине.
Динамически типизированный скриптовый язык на Kotlin, который по-настоящему выполняет код: сканирование и разбор в AST, компиляция в байт-код и запуск на собственной стековой виртуальной машине.
Обзор
lumen - это динамически типизированный скриптовый язык, написанный на Kotlin, который по-настоящему выполняет код. Исходник сканируется, разбирается в AST, компилируется в байт-код, а в конце запускается на собственной стековой виртуальной машине. Выглядит как обычный скриптовый язык, но под низом каждая строка проходит полный путь от текста до инструкций машины.
Разница между lumen и типичным упражнением по написанию языка кроется в одном слове: байт-код. Легко построить интерпретатор, который ходит по дереву и вычисляет его на ходу. lumen идёт на шаг дальше и компилирует, что одновременно труднее и куда интереснее.
Интерпретатор, ходящий по синтаксическому дереву, прост в написании, но быстро упирается в потолок производительности. Каждый прогон одного и того же цикла означает повторный обход тех же узлов дерева, со всеми накладными расходами, которые это несёт. Для маленького скрипта это незаметно, для чего угодно крупнее - ощутимо.
lumen выбирает более трудный, но лучший путь: вместо того чтобы выполнять дерево, он компилирует его в байт-код, то есть плоский список простых инструкций. Эти инструкции затем работают на виртуальной машине, которой уже не нужно ничего понимать в синтаксисе - она получает готовые команды и просто их выполняет.
От текста до байт-кода
Весь путь раскладывается на четыре этапа. Сканер режет текст на токены, парсер складывает их в дерево, компилятор превращает дерево в байт-код, а виртуальная машина выполняет этот байт-код инструкция за инструкцией. Выглядит как обычный код, но каждая строка проходит тот же полный путь.
исходный текст становится токенами.
токены складываются в синтаксическое дерево (AST).
дерево превращается в байт-код.
байт-код выполняется на стеке, инструкция за инструкцией.
Стековая машина изнутри
У стековой машины нет регистров, как у настоящего процессора - операнды она кладёт на стек и снимает с него. Сложение сводится к трём движениям: положить два числа, снять их и сложить, положить результат. Та же модель под капотом движет, среди прочего, Python и Java, поэтому написать её самому - это заглянуть в то, как работают языки, которыми вы пользуетесь каждый день.
Сложение на стековой машине
| Шаг | Инструкция | Стек после |
|---|---|---|
| 1 | положить 2 | 2 |
| 2 | положить 3 | 2, 3 |
| 3 | сложить | 5 |
Стековая машина работает без регистров, и всё же умеет выполнить любую программу. Вся арифметика и передача значений происходят через один стек - это удивительно просто и одновременно ровно та идея, что движет большими производственными языками.
Эффект: слово "скомпилировано" перестаёт быть абстракцией
На выходе - язык, который по-настоящему выполняет код - он не интерпретирует дерево на ходу, а компилирует его и запускает на собственной машине. Это проект, после которого слово "скомпилировано" перестаёт быть абстракцией, потому что сам прошёл весь путь от символа в файле до инструкции, которая что-то делает. Маленький язык, но полный вплоть до самого выполнения.
Больше проектов
Другие работы из той же категории - посмотрите, как мы решаем похожие задачи.
Есть похожий проект?
Напишите нам - смета бесплатна и приходит в течение часа.



