GScript
GScript — это мой скриптовый язык и виртуальная машина к нему. Язык напоминает JavaScript с отдельными идеями из Python — это язык с фигурными скобками, динамической типизацией, поддержкой модулей и прототипной объектной системой. Актуальной версией языка является GScript3. В данный момент VM и компилятор GScript3 практически готовы, но еще не написана стандартная библиотека. В перспективе GScript3 может стать языком общего назначения — я планирую сделать его расширяемым, добавив поддержку DLL-библиотек.
Я начал этот проект из-за недовольства существующими решениями для скриптинга в D. Привязки к мейнстримным языкам (типа Lua и Python) в D выглядят крайне чужеродно, пользоваться ими неудобно. Нативные скриптовые движки, написанные на самом D, по большей части устаревшие и неподдерживаемые. Кроме того, в GScript я реализовал некоторые концепции, которые в интерпретируемых языках практически не встречаются.
Особенности
- Компиляция в байт-код, который можно сохранить в файл для последующего запуска. Можно соединить байт-код с интерпретатором в один самостоятельный исполняемый файл. Также один байт-код может вызывать функции из другого путем встроенного в VM механизма динамического связывания
- Производительность виртуальной машины — более 140 млн. инструкций байт-кода в секунду. Фактически это верхний предел возможностей стекового интерпретатора без JIT
- Динамическая типизация. GScript поддерживает числа двойной точности, строки, массивы, объекты, функции и null-значения, а также специальный тип
Errorдля обработки ошибок - Все функции — вариативные. Список именованных аргументов необязателен
- Объектная модель — прототипная. При наследовании от прототипа данные в новый объект не копируются, а просто вставляется «секретная» ссылка на прототип, которая используется для доступа к свойствам. Если свойством объекта является функция, то такая функция считается методом, и при ее вызове неявно передается ссылка на объект первым аргументом, как в Python
- Поддерживаются модули и импорт. Модули не экспонируют свои глобальные символы, а записывают все, что нужно экспонировать, в специальный объект
global. Фактически модули просто конструируют глобальные прототипы объектов, которые затем можно использовать откуда угодно (похожая идея, только с классами, реализована в Haxe) - Зеленые потоки, которые также являются сопрограммами (корутинами). Можно создавать сотни потоков без вычислительного оверхеда. В VM встроен пул потоков — потоки не уничтожаются, а переиспользуются
- Изоляция памяти потоков. Каждый поток по умолчанию конструирует данные в собственной арене, которая очищается после завершения его работы, благодаря чему в языке не нужен сборщик мусора. Встроенный в VM escape checker проверяет операции копирования и не допускает утечки данных, чтобы в памяти не создавались висячие ссылки. Потоки также могут конструировать общие персистентные данные в глобальной арене
- Простая система обработки ошибок без исключений. Поток может преждевременно завершить работу оператором raise, сохранив значение ошибки в специальный слот. Вызывающий поток отлавливает это состояние и реагирует на него. Отличие от исключений в том, что мой подход не имеет специального синтаксиса обработки ошибок — она делается в рамках обычной синхронизации через await
- AST-макросы.