Реклама


Lua

Lua
Lua-logo-nolabel.svg
Класс языка мультипарадигмальный: императивный, функциональный, объектно-ориентированный (прототипный), скриптовый, встраиваемый
Тип исполнения интерпретируемый, JIT-компилируемый
Появился в 1993
Автор Роберту Иерузалимски,
Валдемар Селиш,
Луиш Энрике ди Фигейреду
Разработчик Роберту Иерузалимски[1]
Расширение файлов .lua
Выпуск 5.3.5 (10 июля 2018 (2018-07-10))
Система типов динамическая, сильная, «утиная»
Основные реализации: Lua, LuaJIT, LLVM-Lua, LuaCLR, Nua, Lua Alchemy и др.[2]
Диалекты MetaLua
Испытал влияние Scheme, Снобол, Модула, Клу, C++
Повлиял на JavaScript, Ruby, Io, GameMonkey, Squirrel, Dao, MiniD
Лицензия лицензия MIT
ОС кроссплатформенность[3]
Сайт lua.org

Lua (лу́а, с порт. — «луна»[4]) — скриптовый язык программирования, разработанный в подразделении Tecgraf (Computer Graphics Technology Group) Католического университета Рио-де-Жанейро (Бразилия). Интерпретатор языка является свободно распространяемым, с открытыми исходными текстами на языке Си.

По идеологии и реализации язык Lua ближе всего к JavaScript, в частности, он также реализует прототипную модель ООП, но отличается Паскале-подобным синтаксисом и более мощными и гибкими конструкциями. Характерной особенностью Lua является реализация большого числа программных сущностей минимумом синтаксических средств. Так, все составные пользовательские типы данных (массивы, структуры, множества, очереди, списки) реализуются через механизм таблиц, а механизмы объектно-ориентированного программирования, включая множественное наследование — с использованием метатаблиц, которые также отвечают за перегрузку операций и ряд других возможностей.

Язык широко используется для создания тиражируемого программного обеспечения (например, на нём написан графический интерфейс пакета Adobe Lightroom). Также получил известность как язык программирования уровней и расширений во многих играх (в том числе World of Warcraft) из-за удобства встраивания, скорости исполнения кода и лёгкости обучения[5][неавторитетный источник?].

Содержание

История[ | код]

Язык разработан подразделением Tecgraf (группа технологий компьютерной графики) Католического университета Рио-де-Жанейро в Бразилии, история языка ведёт отсчёт с 1993 года. Авторы языка — Роберту Иерузалимски, Луиш Энрике ди Фигейреду (Luiz Henrique de Figueiredo) и Валдемар Селиш (Waldemar Celes). Lua распространяется свободно, с открытыми исходными текстами на языке Си.

Историческими родителями языка были языки конфигурирования и описания данных SOL (Simple Object Language) и DEL (Data-Entry Language)[6], они были независимо разработаны в Tecgraf в 1992—1993 годах для добавления некоторой гибкости в два отдельных проекта (оба были интерактивными графическими приложениями для конструкторских нужд в компании Petrobras). В SOL и DEL отсутствовали какие-либо управляющие конструкции, и Petrobras чувствовал растущую необходимость в добавлении к ним полноценного программирования.

Как пишет автор языка в The Evolution of Lua:[7]

В 1993 году единственным реальным претендентом был Tcl, который был специально создан для встраивания в приложения. Однако у Tcl был непривычный синтаксис, не было хорошей поддержки описания данных, и запускался он только на платформах Unix. Мы не рассматривали Лисп или Scheme из-за их недружелюбного синтаксиса. Python был ещё во младенческом возрасте. В атмосфере «сделай сам», которая тогда царила в Tecgraf, было вполне естественно, что мы решили разработать наш собственный скриптовый язык. Из-за того, что большинство пользователей не были профессиональными программистами, языку следовало избегать замысловатого синтаксиса и семантики. Реализация нового языка должна быть легко портируема, так как клиенты Tecgraf имели очень разнообразные платформы. Наконец, поскольку мы ожидали, что другим продуктам Tecgraf также понадобится встроенный скриптовый язык, новый язык должен следовать примеру SOL и предоставляться в виде библиотеки с API на C.

Lua 1.0 была спроектирован таким образом, что конструкторы объектов, тогда чуть отличающиеся от текущего лёгкого и гибкого стиля, включали в себя синтаксис языка SOL (отсюда название Lua: по-португальски sol — «солнце», lua — «луна»). Управляющие конструкции Lua в основном заимствованы из Модулы-2 (if, while, repeat/until), хотя на них также повлияли Клу (параллельное присваивание, множественное возвращаемое значение функции как более простая альтернатива вместо передачи параметров по ссылке или явных указателей), C++ («отличная идея объявлять локальные переменные лишь тогда, когда они нужны»), Снобол и awk (ассоциативные массивы). Создатели Lua также признают, что единый вездесущий механизм структурирования данных в Лиспе и Scheme (связный список) оказал большое влияние на их решение о выборе таблиц в качестве основной структуры данных для Lua[8].

Версии Lua вплоть до 5.0 выпускались под лицензией, подобной лицензии BSD. Начиная с версии 5.0 и выше Lua распространяется под лицензией MIT. Обе лицензии являются пермиссивными и практически идентичны.

Общая характеристика[ | код]

Lua предназначена для использования в качестве отдельного либо встроенного в приложение скриптового языка. Она изначально создавалась достаточно простой и компактной, чтобы поместиться на различных исполняющих платформах и обеспечить приемлемую производительность. Также при проектировании учитывались требования простоты обучения и возможности использования не профессиональными программистами.

Lua — это процедурный динамически типизированный модульный язык с автоматическим управлением памятью. Включает базовые элементы для поддержки функционального и объектного стилей программирования. Таким образом, Lua можно называть мультипарадигменным языком. Встроенные средства параллельного программирования позволяют писать многопоточные программы только средствами языка, не обращаясь к API операционной системы или внешним библиотекам. Так как основным назначением Lua является встраивание, она имеет эффективные средства межъязыкового взаимодействия, ориентированные, главным образом, на вызов библиотек Си и на работу в Си-окружении.

Язык поддерживает небольшое количество встроенных типов данных: логические значения, числа, строки, функции, потоки. Типичные комбинированные структуры данных, такие как массивы, наборы, списки и записи, отсутствуют, вместо всех их используется одна базовая структура Lua — таблица (см. ниже). Отдельный тип userdata предназначен специально для низкоуровневого программирования и обмена данными с внешним кодом на других языках. Функции в Lua являются объектами первого класса, могут присваиваться и передаваться в параметрах. Поддерживаются замыкания, есть возможность создания функций высших порядков. Объектная система прототипная, отсутствует явная поддержка наследования, однако оно легко реализуется с помощью метатаблиц.

Вообще, Lua стремится обеспечить гибкие метафункции, которые могут быть расширены по мере необходимости, а не поставлять набор функций, специфичных для конкретной парадигмы программирования. Как результат, основа языка проста и легко адаптируема к большинству приложений. Предоставляя минимальный набор базовых средств, Lua пытается найти баланс между мощностью и размером.

Синтаксис[ | код]

Синтаксис Lua в основном построен на основе поздних паскалеподобных языков, таких как Модула-2 или Оберон. Формат записи текста — свободный, команды в тексте программы разделяются любыми пробельными символами. Допускается, но не является обязательным применение точки с запятой для разделения операций.

Лексика[ | код]

Основной алфавит языка — английский, в строковых литералах допускается использование символов других языков. Идентификаторы могут состоять из букв, цифр и знака подчёркивания, но не могут начинаться с цифры или совпадать с одним из ключевых слов. Руководство по языку не рекомендует использовать идентификаторы, начинающиеся с подчёркивания, так как такие идентификаторы используются для системных целей.

Язык регистро-зависимый, все ключевые слова пишутся в нижнем регистре, идентификаторы, отличающиеся только регистром букв, считаются различными. В Lua 22 ключевых слова:

  and   break  do     else elseif 
  end   false  goto   for  function 
  if    in     local  nil  not 
  or    repeat return then true
  until while

Комментарии[ | код]

Для комментариев используется следующий синтаксис, близкий к языкам Ada, SQL и VHDL:

-- Простой однострочный комментарий в Lua начинаются с двойного дефиса и продолжается до конца строки.
dim = { "one", "two", "three" } -- Строчный комментарий не обязан начинаться с начала строки, 
                                -- он может следовать за другими языковыми конструкциями,
                                -- поясняя их.
--[[Многострочный комментарий начинается с идущих подряд за двумя минусами двух открывающихся квадратных скобок
  и продолжается до двух подряд закрывающихся квадратных скобок. Как здесь: ]] 

-- Интересный эффект можно получить сочетанием строчных и многострочных комментариев: 
--[[ Чтобы раскомментировать код ниже, достаточно добавить в этой строке пробел между минусами и скобками.
for i=1,#dim do
  print(dim[i])
end
-- Если выше между минусами и скобками будет добавлен пробел, то 
--]] -- здесь конец многострочного комментария превратится в обычный строчный

Типы данных[ | код]

Lua представляет собой язык с неявным динамическим определением типов данных. Переменная языка может содержать значения любого типа. Все значения в Lua могут храниться в переменных, использоваться в качестве аргументов при вызове функций и возвращаться в виде результата их выполнения.

В Lua восемь основных типов:

nil — это тип значения nil [пустое значение], главное свойство которого — отличаться от всех остальных значений и обозначать отсутствие пригодного значения. К типу boolean относятся значения false (ложь) и true (истина).

К типу number относятся обычно вещественные числа (double). В первых версиях Lua целые числа не выделялись в отдельный тип; такое решение мотивируется тем, что вещественное представление позволяет точно представить достаточно широкий диапазон целых чисел. Начиная с версии 5.3 добавлена возможность явного определения целого или вещественного формата числа. Внутреннее представление чисел можно изменить при сборке интерпретатора.

Тип string обозначает массивы символов. Строки Lua могут содержать любые 8-битные символы, включая ноль ('\0'). Строки неизменяемы. Строковые литералы могут записываться в одинарных или двойных кавычках, служебные символы помещаются в них в стандартной для C нотации с ведущим обратным слэшем. Многострочные литералы ограничиваются двумя подряд открывающимися и двумя подряд закрывающимися квадратными скобками.

Встроенная в язык поддержка Юникода отсутствует, хотя допускается использование символов UTF-8 в строковых литералах, а сама система представления UTF-8 позволяет вводить, выводить и частично обрабатывать строки в этой кодировке стандартными системными средствами. В последние версии Lua входит библиотека utf8, обеспечивающая более развитую поддержку UTF-8, существуют также библиотеки сторонних разработчиков, предоставляющие средства работы с Юникод-строками в различных кодировках.

Функции в Lua являются полноправными объектами, допускающими присваивание, передачу в функцию в параметре и возврат из функции как одного из значений. Тип thread имеют сопрограммы, тип userdata предназначен для представления внешних данных, полученных или предоставляемых из/в код на другом языке (главным образом, на C/C++).

Операции[ | код]

Присваивание
Оператором присваивания служит символ =. Подобно таким скриптовым языкам, как Perl, Python, Ruby и Icon, допускает параллельное присваивание. В простейшем случае это позволяет писать выражения вида:
  x, y = y, x
В отличие, например, от языка Go, параллельное присваивание в Lua очень либерально, оно не требует точного соответствия числа переменных числу значений. Если значений больше, чем переменных, то последние значения отбрасываются, если значений меньше — последние переменные в списке получают значение nil.
Сравнения и логические операторы
Операторы сравнения: <, >, <=, >=, ==, ~= (последние два означают, соответственно, сравнение на равенство и на неравенство). Сравнения на равенство и неравенство применимы к любым типам данных, прочие — только к строкам и числам.
Логические операторы: and, or, not — логические «и», «или» и «не», соответственно, могут применяться к значениям любых типов и возвращают true либо false. В параметрах этих операция значения nil и false считаются ложными, любые другие значения — истинными. В отличие от C и ряда других языков, даже числовой нуль (0) или пустая строка ("") с точки зрения логических операторов представляют значение «истина». Вычисление бинарных логических операторов традиционно выполняется до тех пор, пока результат не будет определён, причём в качестве результата возвращается последнее вычисленное подвыражение. Поэтому их можно использовать как тернарный оператор ?: в языке Си:
-- аналогично r = ( a < b)? f(a) : f(b); в Си, 
r = ( a < b ) and f(a) or f(b)
-- r получит значение функции f() от меньшего из двух значений: a и b,
-- при условии, что f(a) не равно nil или false.
Арифметические операторы
+ — сложение;
- — вычитание;
* — умножение;
/ — деление;
- — унарный минус;
% — остаток от деления;
^ — возведение в степень.

Все арифметические операторы поддерживают вещественные операнды, давая предсказуемый результат. Так, x^0.5 возвращает квадратный корень из x, x^(-1/3) — значение, обратное кубическому корню из x. Оператор % определяется выражением: a % b = a - math.floor(a / b) * b, где функция math.floor() вычисляет целую часть своего аргумента. Для целых аргументов его результат вполне обычен. Для вещественного делимого нужно учитывать, что операция не производит никаких дополнительных округлений или отбрасывания дробной части, поэтому результат сохранит дробную часть делимого. Например, math.pi % 2 вернёт не 1, а 1.1415926535898. Такая реализация даёт некоторые дополнительные возможности. Например, для усечения x до трёх знаков после запятой достаточно взять выражение x - x % 0.001

Таблицы[ | код]

Таблица в Lua — это динамический гетерогенный ассоциативный массив, то есть множество пар «ключ-значение». Ключами могут быть значения любых типов Lua, кроме nil. Ключи также могут быть литералами (идентификаторами) Lua. Запись nil в элемент таблицы равносильна удалению данного элемента.

Таблицы являются единственным в Lua составным типом данных. Они являются фундаментом для всех пользовательских типов данных, таких как структуры, массивы, множества и другие:

-- Таблица общего вида:
empty = {} -- Пустая таблица
empty[1] = "первый"        -- Добавление элемента с целым индексом
empty[3] = "второй"        -- Добавление элемента с целым индексом
empty["третий"] = "третий" -- Добавление элемента со строковым индексом
empty[1] = nil             -- Удаление элемента из таблицы  

-- Классический массив - строки индексируются по умолчанию целыми числами, начиная с 1
days1 = {"понедельник", "вторник", "среда", "четверг", "пятница", "суббота", "воскресенье"}

-- Массив с произвольной индексацией
days2 = {[0]="воскресенье", [1]="понедельник", [2]="вторник", [3]="среда", [4]="четверг", [5]="пятница", [6]="суббота"}

-- Запись (структура) - значения различных типов индексируются литералами
person = {tabnum = 123342,                   -- Табельный номер
          fio = "Иванов Степан Васильевич",  -- Ф.И.О.
          post = "слесарь-инструментальщик", -- Должность
          salary = 25800.45,                 -- Оклад
          sdate = "23.10.2013",              -- Дата приёма на работу
          bdate = "08.08.1973"}              -- Дата рождения 

pfio = person.fio --Обращение к элементу структуры.

-- Множество - индексы используются для хранения значений
workDays = {["понедельник"]=true, ["вторник"]=true, ["среда"]=true, ["четверг"]=true, ["пятница"]=true}
workDays["суббота"] = true -- Добавление субботы в число рабочих дней
workDays["среда"] = nil    -- По средам больше не работаем

-- Проверка, является ли d рабочим днём
if workDays[d] then 
  print (d.." - рабочий день")
else
  print (d.." - выходной день")
end

Мультимножества (множества, которые могут содержать более одного экземпляра одного и того же элемента) реализуются аналогично последнему примеру, только в качестве значений используются не логические, а целые — счётчики числа соответствующих элементов в множестве. Связанные списки могут быть представлены как массивы двухэлементных массивов, хранящих значение и ссылку на следующий элемент. Многомерные массивы могут быть реализованы как массивы массивов. Более сложные структуры, такие как очереди, графы, сети также реализуются на основе таблиц, конкретный способ реализации определяется задачей.

Замыкания[ | код]

Lua поддерживает концепцию замыканий, например:

function makeaddfunc(x)
  -- Возвращает новую анонимную функцию, которая добавляет x к аргументу
  return function(y)
    -- Когда мы ссылаемся на переменную x, которая вне текущей области,
    -- и время жизни которой меньше, чем этой анонимной функции, 
    -- Lua создаёт замыкание.
    return x + y
  end
end
plustwo = makeaddfunc(2)
print(plustwo(5)) -- Выводит 7

Каждый раз, когда вызывается makeaddfunc, создаётся новое замыкание для переменной x, так что каждая возвращаемая анонимная функция будет ссылаться на свой параметр x. Как и у любого другого объекта Lua, временем жизни замыкания управляет сборщик мусора.

Средства и методы программирования[ | код]

Метатаблицы[ | код]

Механизм метатаблиц обеспечивает многие возможности, в других языках предоставляемые за счёт введения отдельных синтаксических механизмов. Метатаблицы по структуре являются обычными таблицами Luа, подчиняющимися всем правилам и ограничениям языка. Особенность их состоит в применении. Метатаблица хранит дополнительные метаданные типов и объектов, то есть информацию о параметрах и функциях, связанных с ними. Сведения, хранящиеся в метатаблицах, используются интерпретатором Lua, их использование позволяет изменить или расширить функциональность программных объектов.

Метатаблица в Lua может быть связана со значением любого типа. Скалярные типы данных (все, кроме userdata и таблиц) имеют общие метатаблицы для каждого типа. Таблицы и значения типа userdata имеют индивидуальные ссылки на метатаблицы в каждом экземпляре. Изменять метатаблицы всех типов, кроме таблиц, можно только посредством внешнего кода на Си. Непосредственно из Lua доступны только метатаблицы таблиц.

Созданная «с нуля» таблица Lua не имеет метатаблицы (её ссылка на метатаблицу равна nil). Но метатаблица для неё может быть в любой момент создана либо получена от другой таблицы. Встроенная функция getmetatable(t) возвращает метатаблицу таблицы t, а функция setmetatable(t, m) устанавливает для таблицы t метатаблицу m.

Для метатаблиц документирован набор полей, которые могут использоваться интерпретатором языка. Для указания на особую роль этих полей для них принято специальное правило именования: их идентификаторы начинаются с двух подчёркиваний. Некоторые из таких полей содержат информацию о специфических свойствах объекта, к которому относится метатаблица. Например, параметр __mode, когда он задан, может превратить таблицу в слабую, то есть таблицу, все ссылки на объекты которой являются слабыми ссылками. Но значениями большинства возможных полей метатаблицы являются так называемые метаметоды, то есть ссылки на функции, которые интерпретатор вызывает при определённых условиях. Общая логика использования метаметодов интерпретатором состоит в следующем: когда интерпретатор встречает в программе операцию, которая не определена для объекта-операнда, он обращается к связанной с операндом метатаблице, находит в ней соответствующий метаметод и вызывает его.

--[[ Создание операции сложения для таблиц ]]
-- Операнды
t1 = {1,2,3}     
t2 = {10,20,30}  
-- Создание метатаблицы
mt = {}
-- Запись в метатаблицу метаметода "__add"
mt.__add = function(a, b) 
             local res = {}
             for k in pairs(a) do res[k] = a[k] + b[k] end
             return res
           end
-- Привязка метатаблицы к таблице t1
setmetatable(t1, mt)

-- Теперь сложение таблиц - корректная операция
t3 = t1 + t2
-- соединяем с t3 метатаблицу с метаметодом __tostring
setmetatable(t3, {__tostring=function(t) 
                    local res = "\n"
                    for _,v in pairs(t) do 
                      res = res .. tostring(v) .. "-"
                    end
                    return res.."\n"
                  end})
-- В результате будет выведено: "11,22,33,"
for _,v in ipairs(t3) do 
  io.write (v,",")
end
print(tostring(t3))  -- выведет "11-22-33-"

В Lua поддерживаются метаметоды для всех арифметических операций и операций сравнения, так что с их помощью можно реализовать арифметику для любых объектов, созданных программистом. Помимо стандартных, можно использовать так называемые «библиотечные» метаметоды, которые поддерживаются не ядром языка, а конкретными библиотеками. В примере выше это метаметод __tostring, поддерживаемый библиотекой string; этот метод выполняет конвертацию таблицы в строку.

Наибольший интерес представляет поле __index. Обращение к нему происходит тогда, когда интерпретатор пытается прочитать элемент таблицы, но не находит его. Поле __index может ссылаться либо на метод, либо на таблицу. В первом случае интерпретатор, не найдя искомого значения в основной таблице, будет искать его в таблице __index. Во втором вместо обращения к таблице будет происходить вызов этого метода. Задавая таблицы или метаметоды для данного поля, в Lua можно реализовать наследование, сокрытие данных объекта, отслеживание операций с данными таблицы и многое другое.

Объектно-ориентированное программирование[ | код]

Основой для ООП в Lua являются таблицы. В принципе, таблица и есть объект в ООП-смысле, так как она может иметь поля, именованные с помощью идентификаторов, и хранить в этих полях произвольные значения (свойства объекта) и функции для реализации поведения объекта (методы объекта). Некоторый синтаксический сахар, предоставляемый Lua, делает описание и обращение с объектами более привычным для программистов, имеющих опыт работы с традиционными ООП-языками. Понятия «класса» в Lua нет, поэтому описывается отдельный объект и все поля и методы относятся именно к нему. Свойства описываются аналогично элементам таблицы с ключами-идентификаторами, методы — как поля-функции. Подобно классическому Оберону, описание методов включает явное указание в первом параметре так называемого «получателя» — параметра, который при вызове метода ссылается на объект, для которого он вызван. Но помимо стандартного обращения к полю таблицы, через точку, которое требует и в вызове метода явно указывать получателя, Lua поддерживает дополнительный синтаксис: когда в вызове или описании метода его заголовок записываются в виде «Объект:метод», то получатель не указывается. При этом в теле метода он всё равно доступен под именем self:

-- Объект
Account = {                     -- Объект "счёт"
  id, name, balance=0,          -- свойства объекта: номер, название, баланс
  credit = function (self, v)   -- метод "расход" - описание внутри объекта с явным указанием получателя
    if self.balance < v then error "Недостаточно денег на счёте" end
    self.balance = self.balance - v
  end
}

function Account:debet(v)       -- метод "приход" - внешнее сокращённое описание (self не указывается)
  self.balance = self.balance + v
end

Account.debet(Account, 10000)   -- вызов метода - полный вариант
Account:credit(5000)            -- вызов метода - сокращённый вариант

Наследование, в том числе множественное, реализуется с помощью метатаблиц и метаметодов. Также с помощью метаметодов можно реализовать сокрытие данных и контролируемый доступ к полям таблицы-объекта. Если сравнивать данный подход с другими языками, где всё вышеперечисленное реализуется с помощью специальных языковых средств, то можно заметить, что реализация Lua сложнее и требует более тщательного кодирования, но обеспечивает бо́льшую гибкость и упрощает интерпретатор.

Примеры кода[ | код]

Классическая программа «Hello, world!» на Lua выглядит так:

print("Hello World!")

Факториал — пример рекурсивной функции:

function factorial(n)
  if n == 0 then
    return 1
  else
    return n * factorial(n - 1)
  end
end

Цикл со счётчиком:

for i = 1,5 do
     -- Statements
end

Работа с функциями как с объектами первого класса демонстрируется в следующем примере, в котором модифицируется поведение функции print:

do
  local oldprint = print   -- Сохраняем текущую функцию print как oldprint
  function print(s)        -- Переопределяем функцию print
    if s == "foo" then
      oldprint("bar")
    else
      oldprint(s)
    end
  end
end

Любой будущий вызов print теперь будет перенаправлен к новой функции, и благодаря поддержке в Lua лексического контекста, старая функция print будет доступна только посредством новой, модифицированной функции print. Lua также поддерживает замыкания, как описано выше, в соответствующем разделе.

Ключевой особенностью Lua является расширяемая семантика, механизм метатаблиц даёт большие возможности по настройке уникального поведения для таблиц Lua. В следующем примере демонстрируется «бесконечная» таблица. Для любого , fibs[n] даст число Фибоначчи с использованием мемоизации.

fibs = { 1, 1 } -- Первоначальные значения для fibs[1] и fibs[2].
setmetatable(fibs, { 
  __index = function(name, n)            -- Вызов функции, если fibs[n] не существует.
    name[n] = name[n - 1] + name[n - 2]  -- Расчёт и мемоизация fibs[n].
    return name[n]                       
  end
})

Реализация[ | код]

Как и многие интерпретируемые языки программирования, реализация Lua имеет отдельно компилятор с исходного языка в исполняемый байт-код и виртуальную машину для исполнения сгенерированного байт-кода. Причём байт-код — это не команды стековой машины, а команды некоего виртуального процессора с несколькими регистрами, что повышает эффективность исполнения. В стандартной виртуальной машине Lua используется распределение памяти со сборкой мусора (аналогично Java или .NET).

Lua использует единый строковый пул, что позволяет снизить расходы памяти на хранение строк.

Для задач, критичных по времени, имеется JIT-компилятор Lua — LuaJIT[9]. Также разработан компилятор llvm-lua[10], генерирующий код для виртуальной машины LLVM, предоставляющей возможность последующей компиляции в очень эффективный машинный код для процессоров различной архитектуры.

Использование[ | код]

В настоящее время используется в различных проектах, где требуется встроить достаточно быстрый и нетрудный в освоении скриптовый язык программирования — например, в разработке игр, где Lua часто используется в качестве прослойки между игровым движком и данными для написания сценариев поведения и взаимодействия объектов. Благодаря компактности применим и в портативных устройствах, в частности один из графических микрокалькуляторов Texas Instruments использует язык вместо традиционного для такого класса устройств Бейсика.

Игры[ | код]

Первыми в разработку компьютерных игр язык Lua внедрила компания LucasArts, начиная с игры Grim Fandango[11]. Авторы языка в своём докладе на конференции HOPL (англ.) вспоминают, что в январе 1997 они получили сообщение от Брета Могилефски, главного разработчика Grim Fandango, где он писал, что, прочитав о языке в статье 1996 года в Dr. Dobb’s Journal, он планирует заменить используемый ими самодельный скриптовый язык SCUMM на Lua[12]. В результате им был создан игровой движок GrimE, используемый также более поздним квестом от LucasArts — Escape from Monkey Island.

В 2003 году в результате опроса на сайте GameDev.net Lua был признан самым популярным скриптовым языком для разработки игр[13].

Примером игры, программируемой с помощью Lua, является World of Warcraft[14][15]. На языке Lua описываются уровни игры-головоломки Enigma[16].

Доступен ряд свободных игровых движков, программируемых на Lua, таких, как Defold[17], аркадный движок LÖVE[18][19], игровой конструктор Novashell[20] и ориентированный на квесты (преимущественно — текстовые) INSTEAD[21].

Также используется в авиасимуляторе X-Plane, в движке X-Ray для S.T.A.L.K.E.R[22].

Для популярной игры Minecraft созданы модификации ComputerCraft и его более совершенный аналог OpenComputers, которые добавляют компьютеры, программируемые на языке Lua[23].

Достаточно известная игра Garry's Mod программируется, а также поддерживает модификации, написанные на Lua.

Команда Croteam (разработчики Serious Sam и The Talos Principle) используют Lua в скриптах начиная с версии Serious Engine 3.5[24].

Для игры GTA: San Andreas создаются модификации, написанные на языке Lua и поддерживаемые плагином Moonloader.[25]

IDE[ | код]

Существует как минимум две «родные» среды разработки для Lua, это:

Кроме того, Lua поддерживается некоторыми универсальными IDE, в частности:

Существовал модуль поддержки Lua для среды NetBeans, но его развитие прекратилось в 2013 году и он доступен только для версии NetBeans 7.4 и более ранних. В NetBeans 8 плагин не поддерживается.

Примечания[ | код]

  1. 1 2 https://www.lua.org/authors.html
  2. Lua Implementations (англ.). Lua-users wiki. Проверено 18 мая 2009. Архивировано 24 августа 2011 года.
  3. https://www.lua.org/about.html
  4. About Lua. Lua.org. Проверено 19 июня 2013.
  5. Why is Lua considered a game language?. Stack Overflow. Проверено 23 апреля 2010. Архивировано 20 августа 2013 года.
  6. The evolution of an extension language: a history of Lua (2001). Проверено 24 августа 2016.
  7. HOPL, 2007, p. 2–1–2–26.
  8. Lua: an Extensible Embedded Language. A few metamechanisms replace a host of features (December 1996), стр. 26–33.
  9. The LuaJIT Project
  10. llvm-lua. JIT/Static compiler for Lua using LLVM on the backend.
  11. Bret Mogilefsky. Lua in Grim Fandango. Проверено 9 декабря 2011. Архивировано 4 февраля 2012 года.
  12. HOPL, 2007, с. 11.
  13. Which language do you use for scripting in your game engine?. GameDev.net — Poll Results
  14. Paul Emmerich. Beginning Lua with World of Warcraft Add-ons. — Apress, July 2009. — ISBN 1430223715.
  15. James Whitehead II, Bryan McLemore, and Matthew Orlando. World of Warcraft Programming. — Wiley, May 2008. — ISBN 0470229810.
  16. Tom Gutschmidt. Ch. 8. The Lua Game Community → Game Engines // Game Programming with Python, Lua, and Ruby. — Premier Press, 2003. — 472 p. — ISBN 1-59200-079-7.
  17. Defold game development manual - Lua in Defold. Defold game engine. Проверено 2 марта 2017.
  18. Dj Walker-Morgan. The H Speed Guide to Lua → Developing with Lua. The H (17 April 2012). Проверено 26 февраля 2015.
  19. Darmie Akinlaja. LÖVE for Lua Game Programming. — Packt, 2013. — 106 p. — ISBN 978-1-78216-160-8.
  20. Alan Thorn. Chapter 8. Novashell and 2D Games // Cross Platform Game Development. — Jones & Bartlett Learning, 2008. — P. 225—264. — 421 p. — ISBN 978-1-59822-056-8.
  21. Пётр Косых. INSTEAD: Как все начиналось // IFPrint.org. — Март 18, 2013. — Вып. 1. — ISSN 2307-535X. Архивировано 26 февраля 2015 года.
  22. Ronnie Tucker. Full Circle Magazine #90: THE INDEPENDENT MAGAZINE FOR THE UBUNTU LINUX COMMUNITY. — Full Circle Magazine, 2014-10-31. — 50 с.
  23. Matthew Monk, Simon Monk. ComputerCraft: Lua Programming in Minecraft. — CreateSpace Independent Publishing Platform, 2013-01-28. — 58 с. — ISBN 9781481927659.
  24. Zero_Cool. История технологий - Serious Engine | History | Тест GPU. gamegpu.com. Проверено 10 апреля 2016.
  25. Избранное - Lua - ASI - MoonLoader (рус.), BlastHack - Cheating as Art. Проверено 28 января 2018.
  26. ZeroBrane Studio — Lua IDE/editor/debugger for Windows, Mac OSX, and Linux
  27. Lua Development Tools
  28. EmmyLua :: JetBrains Plugin Repository (англ.). JetBrains Plugin Repository. Проверено 26 февраля 2018.

Литература[ | код]

История языка

Ссылки[ | код]

Lua на русском[ | код]

Переводы руководств
Статьи и обзоры
Реклама