ДраконТех
ДраконТех
Скачать

Генерация кода на языке Lua

Логотип 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

Существуют два исключения:

  1. В функции module использование ключевого слова local разрешено, но не обязательно.
  2. В замыканиях явное объявление переменных при помощи 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 существует три способа задать «Цикл Для»:

  1. Перебор массива. Конструкция for _, item in ipairs(array) do ... end записывается в иконе цикла как item; array.
  2. Перебор объекта. Конструкция for key, item in pairs(map) do ... end записывается как key, item; map.
  3. Цикл в стиле for. Конструкция i = 0; i < count; i = i + 1 работает так же, как в JavaScript.
Перебор массива в Lua

Перебор массива в Lua

Перебор объекта в Lua

Перебор объекта в Lua

Цикл в стиле for в JavaScript

Цикл в стиле for в JavaScript

Важное отличие состоит в том, что для Lua генератор в некоторых случаях не добавляет pairs() или ipairs():

  1. Когда коллекция является вызовом функции, например: x, y; fun.iter(some_object).
  2. Когда коллекция является выражением-итератором, например: i, code; utf8.next, text.
Цикл по значению, возвращаемому функцией в Lua

Цикл по значению, возвращаемому функцией в Lua

Цикл по итератору в 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 = {...}.

Обратная связь

drakon.editor@gmail.com