Добавлен prog,
опубликован
Цель данного поста на данный момент прежде всего в том чтобы собрать фидбэк и интересные идеи, если таковые появятся в комментариях.
Готового к публикации компилятора пока нет, только прототип, загляните сюда позже, если вас интересует именно готовый продукт.
Немного Теории
Для начала немного теоретических рассуждений. Прежде всего, что же из себя представляет "компилятор" в реалиях варкрафта? Можно было бы обратиться к формальному определению компилятора и долго ломать копья об уместности этого слова в текущем контексте, но об этом в другой раз - сейчас важно определиться со смыслом который я вкладываю в это слово здесь и сейчас.
Компилятор - в текущем контексте это утилита, которая берет исходный код карты и преобразует его к виду пригодному для запуска в игре.
Именно так, ни больше ни меньше - только обработка исходного кода. Все остальные действия над картой - задача других утилит.
Поскольку компилятор только трансформирует исходный код, но не трогает карту руками, значит нам нужна еще одна утилита, которая затолкает переработанный код в карту и подготовит её к запуску. Назовем эту утилиту "билдер" или "сборщик".
Билдер/Сборщик - в текущем контексте это утилита, которая перепаковывает карту после обработки кода компилятором, а также запускает другие утилиты, если таковые предусмотрены процессом сборки.
И финальный недостающий для комфортной работы элемент - интеграция с внешней средой разработки. На данный момент для работы с Lua я пользуюсь VSCode, поэтому интеграция будет в виде плагина к VSCode.
Требования
Компилятор: общие требования
- Должен уметь собирать исходный код из файлов вне архива карты
- Должен уметь получать код карты, сгенерированный редактором карт и объединять его с кодом из внешних файлов
- Должен уметь кешировать скомпилированный код для ускорения повторной компиляции
- Не должен своевольно добавлять что-то в код карты, все действия с кодом должны иметь видимую причину
- Не должен слепо имитировать работу require
Билдер: общие требования
- Должен уметь запускать компилятор, передавая ему пути к исходному коду
- Должен уметь собирать пригодную к запуску карту из папки и исходного кода
- Должен уметь запускать дополнительные утилиты при условии их наличия
- Должен уметь игнорировать файлы "только для редактора" при сборке релизной версии карты
Интеграция: общие требования
- Простота настройки и начала работы
- Все входящие в базовый комплект утилиты должны скачиваться автоматически, без необходимости ручной установки и тем более компиляции
- Обязательные настройки перед началом работы должны сводиться к указанию путей к игре и редактору, все остальные настройки должны быть опциональными и иметь приемлемые значения по умолчанию
- Наличие пресета пустого проекта со стандартными настройками и готовой к работе файловой структурой
- Возможность работать в редакторе карт параллельно с редактированием кода в VSCode
Проект: общие требования
- Представлен в виде папки
- Одна карта - один проект
- Содержит воркспейс VSCode
- Содержит файлы конфигурации для конкретного проекта
- Содержит фиксированную структуру папок, диктующую расположение элементов проекта
- Содержит карту представленную в виде папки
- Содержит файлы с исходным кодом
- Содержит папку, в которую складываются промежуточные результаты и временные файлы
- Содержит папку, в которую складывается карта после сборки
- Все файлы находящиеся вне фиксированной структуры не влияют напрямую на происходящие в проекте процессы и формально не являются его частью
Предполагаемые фичи
Интеграция
- Возможность отдельного запуска компилятора из VSCode
- Возможность запуска процесса сборки карты из VSCode
- Возможность запуска карты на тестирование из VSCode
- Возможность открытия карты в редакторе карт по команде из VSCode
- Возможность хранить настройки самой интеграции и всех утилит в конфигурационных файлах конкретного проекта
- Возможность выбирать пресет по которому работают билдер и компилятор
- Возможность применять набор твиков к исходной карте, например исправленый abilitydata.slk для отображения скрытых способностей
Компилятор
- Преобразование равкодов в числа на этапе компиляции. Предварительно реализовано макросом RAW('A000')
- Инлайн переменных и функций. Предварительно частично реализовано макросом --#INLINE для переменных
- Генерация отладочной информации, позволяющей найти строку в файлах исходного кода по номеру строки в итоговом коде
- Режим компиляции release. Из кода исключаются фрагменты не нужные в релизной версии карты, а также код карты подвергается минификации
- Режим компиляции dev. Предназначен для быстрого запуска карты в близком к релизному виде, но с сохранением структуры кода.
- Режим компиляции debug, в код карты добавляются дополнительные отладочные элементы. Предназначен для поиска причин возникновения ошибок ценой потенциальной потери производительности.
- Макросы, позволяющие отмечать фрагменты кода соответствующие различным режимам компиляции
Биллдер
- Несколько режимов работы, отличающихся передаваемыми другим утилитам настройками
- Режим release - карта максимально очищается от лишних и не обязательных файлов, код компилируется в релизном режиме,возможен запуск внешних оптимизаторов.
- Режим dev - карта собирается в близком к релизному виде, но с применением только минимального набора оптимизаций.
- Режим debug - в карту инжектится отладочный модуль, позволяющий выводить сообщения об ошибках в отдельный фрейм.
Запланированные макросы
- --#INLINE для маркировки функций подлежащих инлайну в пределах текущего файла
- --#INLINE GLOBAL для маркировки функций и переменных подлежащих инлайну во всех файлах
- --#IF для начала блока условной компиляции, предварительно без серьезных вычислений, только на основе сравнения констант
- --#ELSE для начала блока else при условной компиляции
- --#END для завершения блоков у любых блочных макросов
Реализованные макросы
- RAW('A000') для конвертации равкодов в число при компиляции.
- --#INLINE для маркировки переменных подлежащих инлайну в пределах текущего файла. Локальные переменные инлайнятся с удалением объявления/присвоения переменной из кода, а для глобальных объявление/присвоение переменной сохраняется.
- --#ALIAS для назначения метки файлу. Взаимозаменяем с макросом #NAME.
- --#AFTER для указания списка меток, которые должны быть включены в код карты прежде чем можно будет включить туда текущий файл. При отсутствии этого макроса файлы включаются в порядке обхода папок и только после кода сгенерированного WE.
На рассмотрении
- Управление порядком включения файлов кода в итоговый код карты через макрос --#IMPORT вставляющий код из указанного файла в место расположения макроса. При такой реализации импортированный файл включается в код как есть, столько раз, сколько использован макрос, защита от конфликтов имен полностью на совести разработчика.
- Управление порядком включения файлов кода в итоговый код карты через макрос --#REQUIRE вставляющий код из указанного файла в место расположения макроса. При такой реализации импортированный файл включается в код путем оборачивания в функцию и возврата объекта из этой функции. Также возможно наличие проверки, позволяющей избежать повторного включения одного и того же модуля. В целом, предполагается что этот макрос будет работать аналогично стандартному require, за исключением невозможности динамически формировать пути к включаемым файлам.
- Фреймворк, который будет поставляться вместе с плагином и который можно будет подключить для получения каких-то дополнительных возможностей в рантайме. Например, система модулей или библиотек, каст-система, различные универсальные утилиты и так далее.
- Расширенная отладочная система, позволяющая по клику в отладочном фрейме внутри игры получить переход на место в коде, в котором возникла показанная в отладочном фрейме ошибка, если это место возможно обнаружить. Причем переход не к финальному монолитному коду карты, а конкретно в тот файл, из которого эта строка попала в итоговый код. Возможно будет работать в два этапа для упрощения реализации, сперва клик в отладочном фрейме экспортирует данные об ошибке в файл, а потом клик в VSCode читает информацию из файла и выполняет переход.
- Режим сборки карты, при котором код из внешних файлов переносится в триггеры в таком виде чтобы его мог исправно сохранять редактор. Предназначен для выкладывания карты на сайт, чтобы люди без настроенной среды разработки тоже могли воспользоваться. Поскольку редактор не сможет обработать макросы - их необходимо обработать до импорта в триггеры.
- Встроенный slk-оптимизатор, конвертирующий данные РО в slk таблицы при запаковке карты.
- Подсказки и автокомплит для макросов.
- Доступ к данным карты из среды разработки, в частности подсказки и автокомплит для равкодов.
- Поддержка линукса, а также других IDE кроме VSCode. Несомненно нужно, но очень затратно по времени.
Разработка
Стартовое состояние
Имеется плагин warcraft-vscode, выполняющий большую часть функций интеграции и билдера. К сожалению, автором этого плагина было принято несколько сомнительных решений, в частности код оборачивается в громоздкую систему имитирующую работу require и это поведение невозможно отключить. Требует серьезной доработки. В составе содержит кастомный сборщик карты, умеющий собрать mpq архив по списку файлов в конфиге.
Для подсветки синтаксиса и поиска синтаксических ошибок используется плагин sumneko.lua, включащий в себя языковой сервер Lua, обработку аннотаций EmmyLua и другие полезные фичи. Не содержит из коробки списка нативок, поэтому их приходится подавать ему из внешних файлов. Мог бы работать лучше, но самостоятельная доработка того не стоит, тем более плагин находится в активной разработке автором и постепенно становится только лучше.
Первая итерация
- Скачаны исходники warcraft-vscode, проведена настройка окружения для компиляции
- Безжалостно удалены лишние фичи из кода плагина, такие как обработка кода шаблонами, имитация require и нерабочие макросы условной компиляции, загрузка библиотек с гитхаба и так далее
- В тестовых целях временно добавлена обработка простых и рабочих макросов условной компиляции
- Начат процесс приведения плагина к виду, в котором его можно было бы опубликовать не опасаясь проблем с авторским правом, фактически он переписывается с нуля с минимальным использованием оригинального кода
Вторая итерация
- Начата разработка внешнего компилятора
- Реализован парсинг кода из файла путем токенизации
- Реализованы макросы #INLINE и RAW
- Реализован вывод кода в файл путем обратной конвертации токенов
- На текущем этапе обрабатывается только один файл - нет ни поиска других внешних файлов ни указания пути по которому должны сохраняться результирующие файлы
Третья итерация
- В этой итерации планируется допилить компилятор до состояния когда он будет способен самостоятельно найти все внешние файлы с кодом по указанному пути, скомпилировать их и вывести результирующий файл в указанное место. (DONE)
- Поскольку способ подключения внешних файлов пока под вопросом - принятие этого решения тоже входит в эту итерацию. (DONE, для начала реализованы макросы #NAME/#ALIAS и #AFTER, сойдет пока)
- Также на эту итерацию запланирована интеграция компилятора с плагином к VSCode, чтобы в плагине остались только функции билдера и интеграции, а вся компиляция выполнялась внешним компилятором.(DONE, в предварительной версии)
Четвертая итерация
- Мы сейчас здесь
- Нужно запилить игнор-лист для сборщика карты, чтобы можно было вручную указать какие файлы не надо паковать (DONE)
- На эту итерацию запланирован первый релиз, пока тестовый, с ручной установкой онли
- До релиза еще необходимо дочистить код от всего лишнего, завести репозиторий на гитхабе и всякое такое
FAQ
Q: Зачем козе баян? Что не так с Lua без дополнительного компилятора?
A: Прежде всего, ради поддержки импорта кода из внешних файлов и возможности работать с кодом карты вне редактора.
A: Прежде всего, ради поддержки импорта кода из внешних файлов и возможности работать с кодом карты вне редактора.
Q: Поддержка JASS?
A: Нет и не планируется. Но вместе с релизом будут выложены исходники - все желающие смогут попробовать самостоятельно адаптировать тулсет под JASS.
A: Нет и не планируется. Но вместе с релизом будут выложены исходники - все желающие смогут попробовать самостоятельно адаптировать тулсет под JASS.
Q: Когда релиз? Где скачать?
A: Как только так сразу. Скачать можно будет сразу после релиза, из маркетплейса плагинов к VSCode или с XGM.
A: Как только так сразу. Скачать можно будет сразу после релиза, из маркетплейса плагинов к VSCode или с XGM.
Вместо послесловия
Разработка ведется по мере наличия свободного времени, с периодической фиксацией результатов.
Когда плагин и компилятор будут пригодны к использованию - они появятся в маркетплейсе VSCode и здесь.
Идеи и предложения приветствуются.
Когда плагин и компилятор будут пригодны к использованию - они появятся в маркетплейсе VSCode и здесь.
Идеи и предложения приветствуются.
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован prog
Отредактирован PT153
PT153:
Отредактирован prog
Например у меня есть такой файл, main.lua
Единственный недостаток - если нужно полностью заменить main или config, а не дополнить их, то старый код этих функций останется в коде карты мертвым грузом.
Отредактирован PT153
Отредактирован prog
Поэтому куда более вероятен вариант макроса --#REPLACE или INJECT, который заставит компилятор найти оригинал функции и стереть его, но пока парсер не готов к таким макросам т.к. индивидуально проходит все файлы по очереди, только один раз и в алфавитном порядке продиктованном системой.