Генерация кода на языке Lua
ДраконТех создаёт один Lua-модуль для проекта.
Код модуля возвращает объект с экспортируемыми функциями.
Чтобы поместить код в начало модуля, создайте функцию со специальным названием module.
Генератор кода на Lua поддерживает классы и конечные автоматы.
Сгенерированный код на Lua выглядит примерно так:
local math = require("math") local os = require("os") setfenv(1, {}) function random() return math.randomseed(os.time()) end return { random = random }
Автоматическое объявление переменных
В обычных Lua-функциях ДраконТех объявляет переменные автоматически. Это значит, что ключевое слово local запрещено в теле функции.
Если нужно объявить локальную переменную, присвойте ей значение. Генератор кода объявит вашу переменную автоматически.
Вы пишете:
x = 10
Генератор кода выдаст:
local x x = 10
Существуют два исключения:
- В функции module использование ключевого слова local разрешено, но не обязательно.
- В замыканиях явное объявление переменных при помощи local обязательно.
В этом примере переменная items объявляется автоматически, а переменные leftName и rightName нужно объявлять вручную, потому что они находятся в замыкании:
items = {
{ name = "Charlie" },
{ name = "Alice" },
{ name = "Bob" }
}
table.sort(items, function(left, right)
local leftName = left.name or ""
local rightName = right.name or ""
return leftName < rightName
end)
Цикл Для
Икона "Цикл Для" является аналогом операторов цикла for и foreach.
В ДРАКОН-Lua существует три способа задать «Цикл Для»:
- Перебор массива. Конструкция
for _, item in ipairs(array) do ... endзаписывается в иконе цикла какitem; array. - Перебор объекта. Конструкция
for key, item in pairs(map) do ... endзаписывается какkey, item; map. - Цикл в стиле for. Конструкция
i = 0; i < count; i = i + 1работает так же, как в JavaScript.
Перебор массива в Lua
Перебор объекта в Lua
Цикл в стиле for в JavaScript
Важное отличие состоит в том, что для Lua генератор в некоторых случаях не добавляет pairs() или ipairs():
- Когда коллекция является вызовом функции, например:
x, y; fun.iter(some_object). - Когда коллекция является выражением-итератором, например:
i, code; utf8.next, text.
Цикл по значению, возвращаемому функцией в Lua
Цикл по итератору в Lua
Изоляция модуля
В Lua-модулях ДраконТех необходимо изолировать модуль от глобальной среды. Это нужно сделать в связи с тем, что ДраконТех объявляет функции глобально, то есть без помощи ключевого слова local. Это приводит к засорению глобальной среды. Применять local function невозможно из-за ограничения Lua на максимальное количество локальных переменных.
Для изоляции модуля в LuaJIT 5.1 применяют следующее выражение:
setfenv(1, {})
Это выражение следует поместить в функцию module. Пример:
local table = table local string = string local pairs = pairs local ipairs = ipairs local type = type local math = require("math") local os = require("os") setfenv(1, {})
Для более старших версий Lua для изоляции модуля применяют другой трюк:
local _ENV = { print = print, pairs = pairs, ipairs = ipairs, tostring = tostring, tonumber = tonumber, table = table, string = string, math = math, os = os }
Для Tarantool и Redis обычно подходит setfenv(1, {}). Для Lua 5.2 и новее вместо этого используют _ENV = {...}.