Вопрос или проблема
Я хочу скомпилировать код, написанный на языке программирования со статической семантикой, в уникальный эквивалент кода Lua, оптимизированный (при возможности, совместимый с Lua 5.1/5.2). Поэтому мне нужен компилятор или инструмент, который сделает это за меня.
Причина, по которой я это делаю, заключается в том, что я хочу выполнить код Lua в игре Flash (“Transformice”). В этой игре Lua реализован на стороне сервера с использованием LuaJ (он написан на Java), и LuaJ не похож на LuaJIT, который оптимизирует таблицы с помощью встроенного кэширования и т.д. Уникальное, что я могу сделать, – это открыть окно Lua (отправить /lua
в игровом чате) и выполнить свой код там, в доме племени.
Язык должен по крайней мере содержать классы с последовательными членами (как в C++ struct
/class
, Java
и т.д.), функции, интерфейс для доступа к таблицам (включая длину таблицы) и таблицу окружения Lua (которая в Lua 5.1 – это _G
, _ENV
) и точку входа выполнения (например, основную функцию).
Язык будет практически сильно/статически типизирован, поскольку классы будут иметь члены с фиксированными именами, например, class A { A parent; }
(где Parent
– это экземпляр члена и к нему обращаются как a[1]
), и должно быть возможно присвоить nil
всему типа A
.
Также компилятор должен быть осторожен, когда код присваивает nil
чему-то, потому что обычно это nil
может нарушить длину массивов в разных средах выполнения Lua – пожалуйста, присваивайте nil
в качестве другого значения, например, false
, когда это возможно.
Эквивалентный код Lua в целом должен использовать массивы для представления экземпляров классов, как это…
Пример кода
(Файл-вход для компиляции.)
#include <debug>
struct Ball
{
int Weight;
Ball() : Weight(15);
};
void main()
{
Ball b = Ball();
trace(b.Weight); // Печатает 15
}
(Вывод компилятора.)
local print = print;
local function Ball()
return { 15 };
end
local function main()
local b = Ball();
print(b[1]); -- trace(b.Weight);
end
main();
(Поскольку вы написали Мне нужен язык с фиксированными ресурсами, такими как классы, типы, пространства имен и т.д., массивы, которые могут изменяться в размере и предоставляют интерфейс для доступа к таблице окружения Lua. Я рискну и порекомендую вам этот скриптовый язык.)
Angelscript имеет все функции ООП, которые вы хотите, и утверждает, что он “крайне гибкий”, так что я вполне уверен, что вы сможете (с небольшими правками) хорошо интегрировать его с окружением Lua.
Angelscript не предоставляет массивы динамического размера, но есть плагин для этого.
Посмотрите на весьма впечатляющие функции здесь.
Ответ или решение
Вопрос о наличии компиляторов статических языков, способных генерировать оптимизированный код для Lua 5.1/5.2, представляет собой комплексную задачу. Ваша цель — создать код на языке, имеющем статические семантики, и преобразовать его в эквивалентный Lua-код, который можно будет выполнить в рамках среды, построенной на LuaJ (Java реализация Lua).
Подбор подходящего языка
Для начала, важно выбрать язык, который поддерживает необходимые вам конструкции: классы, функции, управление таблицами и доступ к окружению Lua (таким, как _G
и _ENV
). Один из языков, который может подойти вашему запросу, — AngelScript. Он предлагает систему объектно-ориентированного программирования с поддержкой классов и статической типизации. Более того, AngelScript достаточно гибок, что позволяет интегрировать его с Lua.
Особенности AngelScript
-
Ограничения массивов: AngelScript не предоставляет динамические массивы по умолчанию, но существует дополнительный механизм, позволяющий расширять массивы. Это может быть полезно для реализации вашего класса.
-
Гибкость: Язык поддерживает объектно-ориентированные концепции, такие как интерфейсы и инкапсуляцию, что является критично важным для вашей задачи.
-
Статическая типизация: AngelScript использует строгую типизацию, что соответствует вашим требованиям к языку.
Пример компиляции
Исходный код на AngelScript может выглядеть следующим образом:
class Ball {
int Weight;
Ball() {
Weight = 15;
}
}
void main() {
Ball b;
print(b.Weight); // Печать 15
}
С применением компилятора, можно получить эквивалентный Lua-код, похожий на следующий:
local print = print
local Ball = {}
Ball.__index = Ball
function Ball:new()
local instance = {}
setmetatable(instance, Ball)
instance.Weight = 15
return instance
end
function main()
local b = Ball:new()
print(b.Weight) -- Печать 15
end
main()
Оптимизация кода
При компиляции вашего кода компилятор должен учитывать, что присвоение значения nil
может вызывать проблемы. При этом, целесообразно использовать вместо nil
другие значения, такие как false
, что позволит избежать ошибок в различных версиях Lua, особенно в контексте управления массивами.
Заключение
Использование AngelScript как статического языка для генерации Lua-кода соответствует вышеуказанным требованиям. Однако, стоит учитывать, что необходима будет дополнительная работа по интеграции и настройке среды для работы с LuaJ. Обратите внимание и на возможности других языков, таких как TypeScript, но они могут потребовать больше усилий для трансляции в Lua-код, чем AngelScript.
Таким образом, подходя к вашей задаче с точки зрения выбранного языка, правил настраивания и оптимизации кода, вы сможете добиться желаемого функционирования в игре Transformice.