Руководство по Lua 5.1
by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes1 – Введение
Lua — это язык программирования расширений, предназначенный для поддержки общей процедурной программирования с возможностями описания данных. Он также предоставляет хорошую поддержку объектно-ориентированного программирования, функционального программирования и программирования, ориентированного на данные. Lua предназначен для использования в качестве мощного и лёгкого скриптового языка для любой программы, нуждающейся в нём. Lua реализован как библиотека, написанная на чистом C (то есть, на общем подмножестве ANSI C и C++).
Будучи языком расширений, Lua не имеет понятия о программе «main»: он работает только в встроенном режиме в клиентской программе-хосте, называемой программой встраивания или просто хостом. Эта программа-хост может вызывать функции для выполнения фрагмента кода Lua, может записывать и читать переменные Lua, а также регистрировать функции C, которые могут вызываться кодом Lua. С помощью функций C Lua можно расширить для работы с широким спектром различных областей, создавая тем самым пользовательские языки программирования, использующие общую синтаксическую основу. Распространение Lua включает в себя пример программы-хоста, называемый lua, которая использует библиотеку Lua для предоставления полного автономного интерпретатора Lua.
Lua является свободным программным обеспечением и предоставляется без каких-либо гарантий, как указано в его лицензии. Реализация, описанная в этом руководстве, доступна на официальном веб-сайте Lua, www.lua.org.
Как и любое другое справочное руководство, этот документ местами сух. Для обсуждения решений, лежащих в основе проектирования Lua, см. технические статьи, доступные на веб-сайте Lua. Для получения подробного введения в программирование на Lua см. книгу Роберто, Программирование на Lua (Второе издание).
2 – Язык
В этом разделе описываются лексика, синтаксис и семантика Lua. Другими словами, этот раздел описывает, какие токены допустимы, как их можно комбинировать и что означают эти комбинации.
Конструкции языка будут объяснены с использованием обычной расширенной нотации Бэкуса-Наура, в которой {a} означает 0 или более a, а [a] означает необязательное a. Нетерминалы показаны как non-terminal, ключевые слова — как kword, а другие терминальные символы — как `=´. Полный синтаксис Lua можно найти в §8 в конце этого руководства.
2.1 – Лексические соглашения
Имена (также называемые идентификаторами) в Lua могут быть любой строкой букв, цифр и нижних подчеркиваний, не начинающейся с цифры. Это совпадает с определением имен в большинстве языков. (Определение буквы зависит от текущего региональных настроек: в идентификаторе можно использовать любой символ, считающийся буквенным в текущих региональных настройках). Идентификаторы используются для именования переменных и полей таблиц.
Следующие ключевые слова зарезервированы и не могут использоваться в качестве имен:
and break do else elseif end false for function if in local nil not or repeat return then true until while
Lua — это язык, чувствительный к регистру: and — зарезервированное слово, но And и AND — два разных допустимых имени. В соответствии с соглашениями, имена, начинающиеся с нижнего подчеркивания, за которым следуют заглавные буквы (например, _VERSION), зарезервированы для внутренних глобальных переменных, используемых Lua.
Следующие строки обозначают другие токены:
+ - * / % ^ #
== ~= <= >= < > =
( ) { } [ ]
; : , . .. ... Литеральные строки могут быть ограничены соответствующими одинарными или двойными кавычками и могут содержать следующие похожие на C escape-последовательности: '\a' (звонок), '\b' (ввод), '\f' (формат страницы), '\n' (новая строка), '\r' (возврат каретки), '\t' (горизонтальная табуляция), '\v' (вертикальная табуляция), '\\' (обратный слеш), '\"' (двойная кавычка), и '\'' (одинарная кавычка). Кроме того, обратный слеш, за которым следует реальная новая строка, приводит к новой строке в строке. Символ в строке также может быть указан по его числовому значению с использованием escape-последовательности \ddd, где ddd — последовательность из до трёх десятичных цифр. (Обратите внимание, что если числовой escape-символ должен быть после цифры, он должен быть выражен ровно тремя цифрами.) Строки в Lua могут содержать любое 8-битовое значение, включая встроенные нули, которые можно указать как '\0'.
Литеральные строки также могут быть определены с использованием длинного формата, заключённого в длинные скобки. Мы определяем открывающую длинную скобку уровня n как открывающую квадратную скобку, за которой следуют n знаков равенства, за которыми следует ещё одна открывающая квадратная скобка. Таким образом, открывающая длинная скобка уровня 0 записывается как [[, открывающая длинная скобка уровня 1 записывается как [=[, и так далее. Закрывающая длинная скобка определяется аналогично; например, закрывающая длинная скобка уровня 4 записывается как ]====]. Длинная строка начинается с открывающей длинной скобки любого уровня и заканчивается первой закрывающей длинной скобкой того же уровня. Литералы в этой скобочной форме могут занимать несколько строк, не интерпретировать никакие escape-последовательности и игнорировать длинные скобки любого другого уровня. Они могут содержать что угодно, кроме закрывающей скобки соответствующего уровня.
Для удобства, если открывающая длинная скобка непосредственно следует за новой строкой, новая строка не включается в строку. Например, в системе, использующей ASCII (в которой 'a' закодировано как 97, новая строка закодирована как 10, а '1' закодировано как 49), пять литеральных строк ниже обозначают одну и ту же строку:
a = 'alo\n123"' a = "alo\n123\"" a = '\97lo\10\04923"' a = [[alo 123"]] a = [==[ alo 123"]==]
Числовая константа может быть записана с необязательной десятичной частью и необязательным десятичным экспонентом. Lua также допускает целочисленные шестнадцатеричные константы, предваряя их 0x. Примеры допустимых числовых констант:
3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56
Комментарий начинается с двух дефисов (--) в любом месте вне строки. Если текст сразу после -- не является открывающей длинной скобкой, комментарий является коротким комментарием, который продолжается до конца строки. В противном случае это длинный комментарий, который продолжается до соответствующей закрывающей длинной скобки. Длинные комментарии часто используются для временного отключения кода.
2.2 – Значения и типы
Lua — это язык с динамической типизацией. Это означает, что переменные не имеют типов; типы есть только у значений. В языке нет определений типов. Все значения несут свой собственный тип.
Все значения в Lua являются значениями первого класса. Это означает, что все значения могут храниться в переменных, передаваться в качестве аргументов другим функциям и возвращаться в качестве результатов.
В Lua есть восемь основных типов: nil, boolean, number, string, function, userdata, thread и table. Nil — это тип значения nil, основное свойство которого заключается в том, что оно отличается от любого другого значения; обычно оно представляет отсутствие полезного значения. Boolean — это тип значений false и true. И nil, и false делают условие ложным; любое другое значение делает его истинным. Number представляет вещественные (с двойной точностью с плавающей запятой) числа. (Легко создать интерпретаторы Lua, которые используют другие внутренние представления для чисел, такие как числа с одинарной точностью или целые числа с большой точностью; см. файл luaconf.h.) String представляет массивы символов. Lua предназначен для работы с 8-битной системой: строки могут содержать любой 8-битный символ, включая встроенные нули ('\0') (см. §2.1).
Lua может вызывать (и манипулировать) функциями, написанными на Lua, и функциями, написанными на C (см. §2.5.8).
Тип userdata предназначен для хранения произвольных данных C в переменных Lua. Этот тип соответствует блоку сырой памяти и не имеет предопределённых операций в Lua, за исключением присваивания и проверки тождественности. Однако, используя метатаблицы, программист может определить операции для значений userdata (см. §2.8). Значения userdata нельзя создать или изменить в Lua, только через API C. Это гарантирует целостность данных, принадлежащих программе-хосту.
Тип thread представляет независимые потоки выполнения и используется для реализации сопроцедур (см. §2.11). Не следует путать потоки Lua с потоками операционной системы. Lua поддерживает сопроцедуры на всех системах, даже на тех, которые не поддерживают потоки.
Тип table реализует ассоциативные массивы, то есть массивы, которые могут индексироваться не только числами, но и любыми значениями (кроме nil). Таблицы могут быть неоднородными; то есть они могут содержать значения всех типов (кроме nil). Таблицы — единственный механизм структурирования данных в Lua; они могут использоваться для представления обычных массивов, таблиц символов, множеств, записей, графов, деревьев и т. д. Для представления записей Lua использует имя поля в качестве индекса. Язык поддерживает это представление, предоставляя a.name в качестве синтаксического сахара для a["name"]. Существует несколько удобных способов создания таблиц в Lua (см. §2.5.7).
Как и индексы, значение поля таблицы может быть любого типа (кроме nil). В частности, поскольку функции являются значениями первого класса, поля таблиц могут содержать функции. Таким образом, таблицы также могут содержать методы (см. §2.5.9).
Таблицы, функции, потоки и (полные) значения userdata являются объектами: переменные фактически не содержат эти значения, а только ссылки на них. Присваивание, передача параметров и возвращение функций всегда манипулируют ссылками на такие значения; эти операции не подразумевают никаких копий.
Функция библиотеки type возвращает строку, описывающую тип данного значения.
2.2.1 – Преобразование типов
Lua предоставляет автоматическое преобразование между строковыми и числовыми значениями во время выполнения. Любая арифметическая операция, применённая к строке, пытается преобразовать эту строку в число, следуя обычным правилам преобразования. Наоборот, всякий раз, когда число используется там, где ожидается строка, число преобразуется в строку в разумном формате. Для полного контроля над тем, как числа преобразуются в строки, используйте функцию format из библиотеки строк (см. string.format).
2.3 – Переменные
Переменные — это места, хранящие значения. В Lua есть три типа переменных: глобальные переменные, локальные переменные и поля таблиц.
Одно имя может обозначать глобальную переменную или локальную переменную (или формальный параметр функции, который является особым видом локальной переменной):
var ::= Name
Имя обозначает идентификаторы, как определено в §2.1.
Любая переменная предполагается глобальной, если не объявлена явно как локальная (см. §2.4.7). Локальные переменные имеют лексическую область видимости: локальные переменные могут свободно использоваться функциями, определёнными внутри их области видимости (см. §2.6).
Перед первым присваиванием переменной её значение равно nil.
Квадратные скобки используются для индексирования таблицы:
var ::= prefixexp `[´ exp `]´
Значение доступа к глобальным переменным и полям таблиц может быть изменено через метатаблицы. Доступ к индексированной переменной t[i] эквивалентен вызову gettable_event(t,i). (См. §2.8 для полного описания функции gettable_event. Эта функция не определена и не вызывается в Lua. Мы используем её здесь только для пояснительных целей.)
Синтаксис var.Name — это просто синтаксический сахар для var["Name"]:
var ::= prefixexp `.´ Name
Все глобальные переменные существуют в виде полей в обычных Lua таблицах, называемых таблицами окружения или просто окружениями (см. §2.9). Каждая функция имеет свою ссылку на окружение, так что все глобальные переменные в этой функции будут ссылаться на эту таблицу окружения. При создании функции она наследует окружение от функции, которая ее создала. Чтобы получить таблицу окружения Lua функции, вызывайте getfenv. Чтобы заменить ее, вызывайте setfenv. (Вы можете манипулировать окружением C-функций только через библиотеку отладки; (см. §5.9).)
Обращение к глобальной переменной x эквивалентно _env.x, что в свою очередь эквивалентно
gettable_event(_env, "x")
где _env — окружение выполняемой функции. (См. §2.8 для полного описания функции gettable_event. Эта функция не определена и не вызываема в Lua. Аналогично, переменная _env не определена в Lua. Мы используем их здесь только для пояснительных целей.)
2.4 – Операторы
Lua поддерживает почти стандартный набор операторов, похожий на операторы в Pascal или C. Этот набор включает присваивания, управляющие структуры, вызовы функций и объявления переменных.
2.4.1 – Блоки кода
Единицей выполнения в Lua является блок кода. Блок кода — это просто последовательность операторов, выполняемых последовательно. Каждый оператор можно необязательно дополнить точкой с запятой:
chunk ::= {stat [`;´]}
Пустых операторов нет, и поэтому ';;' не является допустимым кодом.
Lua обрабатывает блок кода как тело анонимной функции с переменным числом аргументов (см. §2.5.9). Таким образом, блоки кода могут определять локальные переменные, получать аргументы и возвращать значения.
Блок кода может храниться в файле или в строке внутри программы-хоста. Для выполнения блока кода Lua сначала прекомпилирует его в инструкции для виртуальной машины, а затем выполняет скомпилированный код с интерпретатором для виртуальной машины.
Блоки кода также могут быть предварительно скомпилированы в двоичный формат; см. программу luac для подробностей. Программы в исходной и скомпилированной формах взаимозаменяемы; Lua автоматически определяет тип файла и действует соответствующим образом.
2.4.2 – Блоки
Блок — это список операторов; синтаксически блок такой же, как и блок кода:
block ::= chunk
Блок можно явно ограничить, чтобы получить один оператор:
stat ::= do block end
Явные блоки полезны для управления областью видимости объявлений переменных. Явные блоки также иногда используются для добавления оператора return или break в середине другого блока (см. §2.4.4).
2.4.3 – Присваивание
Lua позволяет выполнять несколько присваиваний. Поэтому синтаксис присваивания определяет список переменных слева и список выражений справа. Элементы в обоих списках разделены запятыми:
stat ::= varlist `=´ explist
varlist ::= var {`,´ var}
explist ::= exp {`,´ exp}
Выражения рассматриваются в §2.5.
Перед присваиванием список значений корректируется до длины списка переменных. Если значений больше, чем нужно, избыточные значения отбрасываются. Если значений меньше, чем нужно, список дополняется нужным числом значений nil. Если список выражений заканчивается вызовом функции, то все значения, возвращаемые этим вызовом, попадают в список значений перед корректировкой (за исключением случаев, когда вызов заключен в скобки; см. §2.5).
Оператор присваивания сначала вычисляет все свои выражения, и только затем выполняются присваивания. Таким образом, код
i = 3 i, a[i] = i+1, 20
устанавливает a[3] в 20, не затрагивая a[4], потому что i в a[i] вычисляется (в 3) перед присваиванием 4. Аналогично, строка
x, y = y, x
меняет местами значения x и y, и
x, y, z = y, z, x
циклически переставляет значения x, y и z.
Значение присваивания глобальным переменным и полям таблиц может быть изменено с помощью метатаблиц. Присваивание индексированной переменной t[i] = val эквивалентно settable_event(t,i,val). (См. §2.8 для полного описания функции settable_event. Эта функция не определена и не вызываема в Lua. Мы используем ее здесь только для пояснительных целей.)
Присваивание глобальной переменной x = val эквивалентно присваиванию _env.x = val, которое в свою очередь эквивалентно
settable_event(_env, "x", val)
где _env — окружение выполняемой функции. (Переменная _env не определена в Lua. Мы используем ее здесь только для пояснительных целей.)
2.4.4 – Управляющие структуры
Управляющие структуры if, while и repeat имеют обычное значение и знакомый синтаксис:
stat ::= while exp do block end
stat ::= repeat block until exp
stat ::= if exp then block {elseif exp then block} [else block] end
Lua также имеет оператор for, в двух вариантах (см. §2.4.5).
Выражение условия управляющей структуры может возвращать любое значение. И false, и nil считаются ложными. Все значения, отличные от nil и false, считаются истинными (в частности, число 0 и пустая строка также истинны).
В цикле repeat–until внутренний блок не заканчивается на ключевом слове until, а только после проверки условия. Таким образом, условие может ссылаться на локальные переменные, объявленные внутри блока цикла.
Оператор return используется для возвращения значений из функции или блока кода (который является просто функцией). Функции и блоки кода могут возвращать более одного значения, и поэтому синтаксис оператора return таков
stat ::= return [explist]
Оператор break используется для прерывания выполнения цикла while, repeat или for, переходя к следующему оператору после цикла:
stat ::= break
Оператор break прерывает ближайший вложенный цикл.
Операторы return и break могут быть записаны только в качестве последнего оператора блока. Если действительно необходимо использовать return или break в середине блока, то можно использовать явный внутренний блок, как в примерах do return end и do break end, так как теперь return и break являются последними операторами в своих (внутренних) блоках.
2.4.5 – Оператор For
Оператор for имеет два вида: числовой и обобщённый.
Числовой цикл for повторяет блок кода, пока управляющая переменная проходит через арифметическую прогрессию. Он имеет следующий синтаксис:
stat ::= for Name `=´ exp `,´ exp [`,´ exp] do block end
Блок повторяется для имени, начиная со значения первого выражения, до тех пор, пока оно не превысит значение второго выражения с шагом третьего выражения. Более точно, оператор for вида
for v = e1, e2, e3 do block end
эквивалентен коду:
do
local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
if not (var and limit and step) then error() end
while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
local v = var
block
var = var + step
end
end
Обратите внимание на следующее:
- Все три выражения управления вычисляются только один раз, до начала цикла. Все они должны быть числами.
-
var,limit, иstep— скрытые переменные. Имена, показанные здесь, используются только для пояснительных целей. - Если третье выражение (шаг) отсутствует, используется шаг 1.
- Вы можете использовать break для выхода из цикла for.
- Переменная цикла
vлокальна для цикла; вы не можете использовать ее значение после окончания цикла for или его прерывания. Если вам нужно это значение, присвойте его другой переменной перед прерыванием или выходом из цикла.
Обобщённый оператор for работает с функциями, называемыми итераторами. На каждой итерации функция-итератор вызывается для получения нового значения, остановка происходит, когда это новое значение равно nil. Обобщённый оператор for имеет следующий синтаксис:
stat ::= for namelist in explist do block end
namelist ::= Name {`,´ Name}
Оператор for вида
for var_1, ···, var_n in explist do block end
эквивалентен коду:
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
var = var_1
if var == nil then break end
block
end
end
Обратите внимание на следующее:
-
explistвычисляется только один раз. Его результаты — это функция-итератор, состояние и начальное значение для первой переменной-итератора. -
f,s, иvar— скрытые переменные. Имена здесь используются только для пояснительных целей. - Вы можете использовать break для выхода из цикла for.
- Переменные цикла
var_iлокальны для цикла; вы не можете использовать их значения после окончания цикла for. Если вам нужны эти значения, присвойте их другим переменным перед прерыванием или выходом из цикла.
2.4.6 – Вызовы функций как операторы
Для возможности побочных эффектов вызовы функций могут выполняться как операторы:
stat ::= functioncall
В этом случае все возвращаемые значения отбрасываются. Вызовы функций объяснены в §2.5.8.
2.4.7 – Объявления локальных переменных
Локальные переменные могут быть объявлены в любом месте внутри блока. Объявление может включать начальное присваивание:
stat ::= local namelist [`=´ explist]
Если присутствует начальное присваивание, оно имеет ту же семантику, что и множественное присваивание (см. §2.4.3). В противном случае все переменные инициализируются значением nil.
Блок кода также является блоком (см. §2.4.1), и поэтому локальные переменные могут быть объявлены в блоке кода вне любого явного блока. Область видимости таких локальных переменных распространяется до конца блока кода.
Правила видимости локальных переменных объяснены в §2.6.
2.5 – Выражения
Основные выражения в Lua следующие:
exp ::= prefixexp exp ::= nil | false | true exp ::= Number exp ::= String exp ::= function exp ::= tableconstructor exp ::= `...´ exp ::= exp binop exp exp ::= unop exp prefixexp ::= var | functioncall | `(´ exp `)´
Числа и литеральные строки объяснены в §2.1; переменные объяснены в §2.3; определения функций объяснены в §2.5.9; вызовы функций объяснены в §2.5.8; конструкторы таблиц объяснены в §2.5.7. Выражения Vararg, обозначаемые тремя точками ('...'), могут использоваться только непосредственно внутри функции Vararg; они объяснены в §2.5.9.
Бинарные операторы включают арифметические операторы (см. §2.5.1), реляционные операторы (см. §2.5.2), логические операторы (см. §2.5.3) и оператор конкатенации (см. §2.5.4). Унарные операторы включают унарный минус (см. §2.5.1), унарный not (см. §2.5.3) и унарный оператор длины (см. §2.5.5).
Как вызовы функций, так и выражения vararg могут давать несколько значений. Если выражение используется как оператор (возможно только для вызовов функций (см. §2.4.6)), то его список возвращаемых значений корректируется до нуля элементов, тем самым отбрасывая все возвращаемые значения. Если выражение используется в качестве последнего (или единственного) элемента списка выражений, то корректировка не выполняется (если вызов не заключен в скобки). Во всех остальных контекстах Lua корректирует список результатов до одного элемента, отбрасывая все значения, кроме первого.
Вот некоторые примеры:
f() -- adjusted to 0 results
g(f(), x) -- f() is adjusted to 1 result
g(x, f()) -- g gets x plus all results from f()
a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil)
a,b = ... -- a gets the first vararg parameter, b gets
-- the second (both a and b can get nil if there
-- is no corresponding vararg parameter)
a,b,c = x, f() -- f() is adjusted to 2 results
a,b,c = f() -- f() is adjusted to 3 results
return f() -- returns all results from f()
return ... -- returns all received vararg parameters
return x,y,f() -- returns x, y, and all results from f()
{f()} -- creates a list with all results from f()
{...} -- creates a list with all vararg parameters
{f(), nil} -- f() is adjusted to 1 result Любое выражение, заключённое в скобки, всегда возвращает только одно значение. Таким образом, (f(x,y,z)) всегда является единственным значением, даже если f возвращает несколько значений. (Значение (f(x,y,z)) является первым значением, возвращаемым f, или nil, если f не возвращает никаких значений.)
2.5.1 – Арифметические операторы
Lua поддерживает обычные арифметические операторы: бинарные + (сложение), - (вычитание), * (умножение), / (деление), % (остаток от деления) и ^ (возведение в степень); и унарный - (отрицание). Если операнды являются числами или строками, которые могут быть преобразованы в числа (см. §2.2.1), все операции имеют обычный смысл. Возведение в степень работает для любого показателя степени. Например, x^(-0.5) вычисляет обратное значение квадратного корня из x. Остаток от деления определяется как
a % b == a - math.floor(a/b)*b
То есть, это остаток от деления, при котором частное округляется до минус бесконечности.
2.5.2 – Операторы сравнения
Операторы сравнения в Lua следующие:
== ~= < > <= >=
Эти операторы всегда возвращают false или true.
Равенство (==) сначала сравнивает тип своих операндов. Если типы разные, результат — false. В противном случае сравниваются значения операндов. Числа и строки сравниваются обычным способом. Объекты (таблицы, userdata, потоки и функции) сравниваются по ссылке: два объекта считаются равными только если они являются одним и тем же объектом. Каждый раз, когда вы создаёте новый объект (таблицу, userdata, поток или функцию), этот новый объект отличается от любого ранее существовавшего объекта.
Вы можете изменить способ сравнения Lua для таблиц и userdata, используя метаметод "eq" (см. §2.8).
Правила преобразования из §2.2.1 не применяются к сравнениям на равенство. Таким образом, "0"==0 вычисляется в false, а t[0] и t["0"] обозначают разные записи в таблице.
Оператор ~= является точным отрицанием равенства (==).
Операторы порядка работают следующим образом. Если оба аргумента являются числами, они сравниваются как числа. В противном случае, если оба аргумента являются строками, их значения сравниваются в соответствии с текущим языковым стандартом. В противном случае Lua пытается вызвать метаметод "lt" или "le" (см. §2.8). Сравнение a > b преобразуется в b < a, а a >= b преобразуется в b <= a.
2.5.3 – Логические операторы
Логические операторы в Lua — это and, or и not. Как и управляющие структуры (см. §2.4.4), все логические операторы рассматривают как false, так и nil как ложные, а всё остальное как истинное.
Оператор отрицания not всегда возвращает false или true. Оператор конъюнкции and возвращает свой первый аргумент, если это значение является false или nil; в противном случае and возвращает свой второй аргумент. Оператор дизъюнкции or возвращает свой первый аргумент, если это значение отлично от nil и false; в противном случае or возвращает свой второй аргумент. Как and, так и or используют короткую вычисление; то есть, второй операнд вычисляется только при необходимости. Вот несколько примеров:
10 or 20 --> 10 10 or error() --> 10 nil or "a" --> "a" nil and 10 --> nil false and error() --> false false and nil --> false false or nil --> nil 10 and 20 --> 20
(В этом руководстве --> обозначает результат предыдущего выражения.)
2.5.4 – Конкатенация
Оператор конкатенации строк в Lua обозначается двумя точками ('..'). Если оба операнда являются строками или числами, они преобразуются в строки в соответствии с правилами, указанными в §2.2.1. В противном случае вызывается метаметод "concat" (см. §2.8).
2.5.5 – Оператор длины
Оператор длины обозначается унарным оператором #. Длина строки — это её число байтов (то есть, обычный смысл длины строки, когда каждый символ занимает один байт).
Длина таблицы t определяется как любой целочисленный индекс n, такой, что t[n] не является nil, а t[n+1] — nil; кроме того, если t[1] — nil, n может быть нулём. Для обычного массива, содержащего значения, отличные от nil, от 1 до заданного n, его длина — это точно этот n, индекс его последнего значения. Если массив содержит «дыры» (то есть, значения nil между другими значениями, отличными от nil), то #t может быть любым из индексов, непосредственно предшествующих значению nil (то есть, он может рассматривать любое такое значение nil как конец массива).
2.5.6 – Приоритет
Приоритет операторов в Lua соответствует таблице ниже, от низшего к высшему:
or and < > <= >= ~= == .. + - * / % not # - (unary) ^
Как обычно, вы можете использовать скобки для изменения приоритетов выражения. Операторы конкатенации ('..') и возведения в степень ('^') являются правоассоциативными. Все остальные бинарные операторы — левоассоциативные.
2.5.7 – Конструкторы таблиц
Конструкторы таблиц — это выражения, которые создают таблицы. Каждый раз, когда оценивается конструктор, создаётся новая таблица. Конструктор может быть использован для создания пустой таблицы или для создания таблицы и инициализации некоторых её полей. Общая синтаксическая конструкция для конструкторов:
tableconstructor ::= `{´ [fieldlist] `}´
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
fieldsep ::= `,´ | `;´ Каждое поле вида [exp1] = exp2 добавляет в новую таблицу запись с ключом exp1 и значением exp2. Поле вида name = exp эквивалентно ["name"] = exp. Наконец, поля вида exp эквивалентны [i] = exp, где i — последовательные целочисленные значения, начиная с 1. Поля в других форматах не влияют на это подсчёт. Например,
a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
эквивалентно
do
local t = {}
t[f(1)] = g
t[1] = "x" -- 1st exp
t[2] = "y" -- 2nd exp
t.x = 1 -- t["x"] = 1
t[3] = f(x) -- 3rd exp
t[30] = 23
t[4] = 45 -- 4th exp
a = t
end Если последнее поле в списке имеет вид exp и выражение является вызовом функции или выражением с переменным числом аргументов, все значения, возвращаемые этим выражением, последовательно входят в список (см. §2.5.8). Чтобы избежать этого, заключите вызов функции или выражение с переменным числом аргументов в скобки (см. §2.5).
Список полей может иметь необязательный заключительный разделитель, как удобство для машиночитаемого кода.
2.5.8 – Вызовы функций
Вызов функции в Lua имеет следующий синтаксис:
functioncall ::= prefixexp args
При вызове функции сначала оцениваются prefixexp и args. Если значение prefixexp имеет тип функция, то эта функция вызывается с указанными аргументами. В противном случае вызывается метаметод "вызов" prefixexp, имеющий в качестве первого параметра значение prefixexp, за которым следуют исходные аргументы вызова (см. §2.8).
Форма
functioncall ::= prefixexp `:´ Name args
может использоваться для вызова «методов». Вызов v:name(args) является синтаксическим сахаром для v.name(v,args), за исключением того, что v оценивается только один раз.
Аргументы имеют следующий синтаксис:
args ::= `(´ [explist] `)´ args ::= tableconstructor args ::= String
Все выражения аргументов оцениваются до вызова. Вызов в форме f{fields} является синтаксическим сахаром для f({fields}); то есть, список аргументов — это одна новая таблица. Вызов в форме f'string' (или f"string" или f[[string]]) является синтаксическим сахаром для f('string'); то есть, список аргументов — это одна строковая константа.
В отличие от свободного синтаксиса Lua, вы не можете поместить перевод строки перед '(' в вызове функции. Это ограничение позволяет избежать неоднозначностей в языке. Если вы напишете
a = f (g).x(a)
Lua воспримет это как одно утверждение, a = f(g).x(a). Поэтому, если вы хотите два утверждения, вы должны добавить точку с запятой между ними. Если вы действительно хотите вызвать f, вы должны удалить перевод строки перед (g).
Вызов вида return functioncall называется хвостовым вызовом. Lua реализует правильные хвостовые вызовы (или правильную хвостовую рекурсию): при хвостовом вызове вызываемая функция использует запись стека вызывающей функции. Поэтому нет ограничений на количество вложенных хвостовых вызовов, которые может выполнить программа. Однако хвостовой вызов стирает любую отладочную информацию о вызывающей функции. Обратите внимание, что хвостовой вызов происходит только с определённым синтаксисом, где return имеет один вызов функции в качестве аргумента; этот синтаксис заставляет вызывающую функцию возвращать ровно возвращаемые значения вызываемой функции. Таким образом, ни один из следующих примеров не является хвостовым вызовом:
return (f(x)) -- results adjusted to 1 return 2 * f(x) return x, f(x) -- additional results f(x); return -- results discarded return x or f(x) -- results adjusted to 1
2.5.9 – Определения функций
Синтаксис определения функции:
function ::= function funcbody funcbody ::= `(´ [parlist] `)´ block end
Следующий синтаксический сахар упрощает определения функций:
stat ::= function funcname funcbody
stat ::= local function Name funcbody
funcname ::= Name {`.´ Name} [`:´ Name]
Утверждение
function f () body end
преобразуется в
f = function () body end
Утверждение
function t.a.b.c.f () body end
преобразуется в
t.a.b.c.f = function () body end
Утверждение
local function f () body end
преобразуется в
local f; f = function () body end
а не в
local f = function () body end
(Это имеет значение только тогда, когда тело функции содержит ссылки на f.)
Определение функции — это исполняемое выражение, значение которого имеет тип функция. Когда Lua предварительно компилирует блок, все его тела функций также компилируются предварительно. Затем, всякий раз, когда Lua выполняет определение функции, функция инстанцируется (или закрывается). Этот экземпляр функции (или замыкание) является конечным значением выражения. Разные экземпляры одной и той же функции могут ссылаться на разные внешние локальные переменные и могут иметь разные таблицы окружения.
Параметры действуют как локальные переменные, которые инициализируются значениями аргументов:
parlist ::= namelist [`,´ `...´] | `...´
Когда функция вызывается, список аргументов корректируется в соответствии с длиной списка параметров, если функция не является функцией с переменным числом аргументов или функцией с произвольным числом аргументов, что указывается тремя точками ('...') в конце списка параметров. Функция с переменным числом аргументов не корректирует список аргументов; вместо этого она собирает все дополнительные аргументы и предоставляет их функции через выражение с произвольным числом аргументов, которое также записывается как три точки. Значение этого выражения — список всех фактически дополнительных аргументов, аналогично функции с несколькими результатами. Если выражение с произвольным числом аргументов используется внутри другого выражения или посередине списка выражений, его список возвращаемых значений корректируется до одного элемента. Если выражение используется в качестве последнего элемента списка выражений, корректировка не производится (если только последнее выражение не заключено в скобки).
В качестве примера рассмотрим следующие определения:
function f(a, b) end function g(a, b, ...) end function r() return 1,2,3 end
Тогда у нас есть следующее сопоставление аргументов с параметрами и с выражением с переменным числом аргументов:
CALL PARAMETERS f(3) a=3, b=nil f(3, 4) a=3, b=4 f(3, 4, 5) a=3, b=4 f(r(), 10) a=1, b=10 f(r()) a=1, b=2 g(3) a=3, b=nil, ... --> (nothing) g(3, 4) a=3, b=4, ... --> (nothing) g(3, 4, 5, 8) a=3, b=4, ... --> 5 8 g(5, r()) a=5, b=1, ... --> 2 3
Результаты возвращаются с помощью оператора return (см. §2.4.4). Если выполнение доходит до конца функции без встречи оператора return, то функция возвращается без результатов.
Синтаксис с двоеточием используется для определения методов, то есть функций, имеющих неявный дополнительный параметр self. Таким образом, оператор
function t.a.b.c:f (params) body end
является синтаксическим сахаром для
t.a.b.c.f = function (self, params) body end
2.6 – Правила видимости
Lua — язык с лексическим охватом области видимости. Область видимости переменных начинается с первого оператора после их объявления и длится до конца самого внутреннего блока, который включает объявление. Рассмотрим следующий пример:
x = 10 -- global variable
do -- new block
local x = x -- new 'x', with value 10
print(x) --> 10
x = x+1
do -- another block
local x = x+1 -- another 'x'
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (the global one) Обратите внимание, что в объявлении, подобном local x = x, новое x объявление ещё не находится в области видимости, поэтому второе x ссылается на внешнюю переменную.
Из-за правил лексического охватывания, локальные переменные могут свободно использоваться функциями, определенными внутри их области видимости. Локальная переменная, используемая внутренней функцией, называется замыканием или внешней локальной переменной внутри внутренней функции.
Обратите внимание, что каждое выполнение оператора local определяет новые локальные переменные. Рассмотрим следующий пример:
a = {}
local x = 20
for i=1,10 do
local y = 0
a[i] = function () y=y+1; return x+y end
end
Цикл создает десять замыканий (то есть десять экземпляров анонимной функции). Каждое из этих замыканий использует разную переменную y, в то время как все они используют одну и ту же переменную x.
2.7 – Обработка ошибок
Поскольку Lua — это встроенный язык расширений, все действия Lua начинаются с кода C в программе-хосте, вызывающей функцию из библиотеки Lua (см. lua_pcall). Всякий раз, когда возникает ошибка во время компиляции или выполнения Lua, управление возвращается в C, который может принять соответствующие меры (например, вывести сообщение об ошибке).
Код Lua может явно сгенерировать ошибку, вызвав функцию error. Если вам нужно перехватывать ошибки в Lua, вы можете использовать функцию pcall.
2.8 – Метатаблицы
Каждый значение в Lua может иметь метатаблицу. Эта метатаблица — обычная таблица Lua, которая определяет поведение исходного значения при определенных специальных операциях. Вы можете изменить несколько аспектов поведения операций над значением, установив определенные поля в его метатаблице. Например, когда нечисловое значение является операндом сложения, Lua проверяет наличие функции в поле "__add" в его метатаблице. Если такая функция найдена, Lua вызывает её для выполнения сложения.
Мы называем ключи в метатаблице событиями, а значения — метаметодами. В предыдущем примере событие — "add", а метаметод — функция, выполняющая сложение.
Вы можете запросить метатаблицу любого значения с помощью функции getmetatable.
Вы можете заменить метатаблицу таблиц с помощью функции setmetatable. Вы не можете изменить метатаблицу других типов из Lua (за исключением использования библиотеки отладки); для этого необходимо использовать API C.
Таблицы и полные пользовательские данные имеют отдельные метатаблицы (хотя несколько таблиц и пользовательских данных могут использовать общие метатаблицы). Значения всех других типов используют одну общую метатаблицу на тип; то есть, есть одна метатаблица для всех чисел, одна для всех строк и т. д.
Метатаблица управляет поведением объекта в арифметических операциях, сравнениях порядка, конкатенации, операциях длины и индексировании. Метатаблица также может определить функцию, которая будет вызвана при сборке мусора для пользовательских данных. Для каждой из этих операций Lua связывает определенный ключ, называемый событием. Когда Lua выполняет одну из этих операций над значением, оно проверяет, имеет ли это значение метатаблицу с соответствующим событием. Если да, то ассоциированное с этим ключом значение (метаметод) контролирует, как Lua выполнит операцию.
Метатаблицы контролируют перечисленные ниже операции. Каждая операция идентифицируется своим соответствующим именем. Ключ для каждой операции — строка с её именем, префикс которой — два символа подчеркивания, '__'; например, ключ для операции "add" — строка "__add". Семантика этих операций лучше объясняется функцией Lua, описывающей, как интерпретатор выполняет операцию.
Приведенный здесь код на Lua является лишь иллюстративным; реальное поведение жёстко запрограммировано в интерпретаторе и значительно эффективнее этой симуляции. Все функции, используемые в этих описаниях (rawget, tonumber и т. д.), описаны в §5.1. В частности, для извлечения метаметода данного объекта используется выражение
metatable(obj)[event]
Это следует читать как
rawget(getmetatable(obj) or {}, event)
То есть, обращение к метаметоду не вызывает другие метаметоды, и доступ к объектам без метатаблиц не приводит к ошибке (это просто приводит к nil).
-
"add": операция
+.Функция
getbinhandlerниже определяет, как Lua выбирает обработчик для бинарной операции. Сначала Lua проверяет первый операнд. Если его тип не определяет обработчик для операции, тогда Lua проверяет второй операнд.function getbinhandler (op1, op2, event) return metatable(op1)[event] or metatable(op2)[event] end
Используя эту функцию, поведение
op1 + op2такое:function add_event (op1, op2) local o1, o2 = tonumber(op1), tonumber(op2) if o1 and o2 then -- both operands are numeric? return o1 + o2 -- '+' here is the primitive 'add' else -- at least one of the operands is not numeric local h = getbinhandler(op1, op2, "__add") if h then -- call the handler with both operands return (h(op1, op2)) else -- no handler available: default behavior error(···) end end end -
"sub": операция
-. Поведение аналогично операции "add". -
"mul": операция
*. Поведение аналогично операции "add". -
"div": операция
/. Поведение аналогично операции "add". -
"mod": операция
%. Поведение аналогично операции "add", с операциейo1 - floor(o1/o2)*o2в качестве примитивной операции. -
"pow": операция
^(возведение в степень). Поведение аналогично операции "add", с функциейpow(из библиотеки C math) в качестве примитивной операции. -
"unm": унарная операция
-.function unm_event (op) local o = tonumber(op) if o then -- operand is numeric? return -o -- '-' here is the primitive 'unm' else -- the operand is not numeric. -- Try to get a handler from the operand local h = metatable(op).__unm if h then -- call the handler with the operand return (h(op)) else -- no handler available: default behavior error(···) end end end -
"concat": операция
..(конкатенация).function concat_event (op1, op2) if (type(op1) == "string" or type(op1) == "number") and (type(op2) == "string" or type(op2) == "number") then return op1 .. op2 -- primitive string concatenation else local h = getbinhandler(op1, op2, "__concat") if h then return (h(op1, op2)) else error(···) end end end -
"len": операция
#.function len_event (op) if type(op) == "string" then return strlen(op) -- primitive string length elseif type(op) == "table" then return #op -- primitive table length else local h = metatable(op).__len if h then -- call the handler with the operand return (h(op)) else -- no handler available: default behavior error(···) end end endСм. §2.5.5 для описания длины таблицы.
-
"eq": операция
==. Функцияgetcomphandlerопределяет, как Lua выбирает метаметод для операторов сравнения. Метаметод выбирается только тогда, когда оба сравниваемых объекта имеют одинаковый тип и одинаковый метаметод для выбранной операции.function getcomphandler (op1, op2, event) if type(op1) ~= type(op2) then return nil end local mm1 = metatable(op1)[event] local mm2 = metatable(op2)[event] if mm1 == mm2 then return mm1 else return nil end end
Событие "eq" определяется следующим образом:
function eq_event (op1, op2) if type(op1) ~= type(op2) then -- different types? return false -- different objects end if op1 == op2 then -- primitive equal? return true -- objects are equal end -- try metamethod local h = getcomphandler(op1, op2, "__eq") if h then return (h(op1, op2)) else return false end enda ~= bэквивалентноnot (a == b). -
"lt": операция
<.function lt_event (op1, op2) if type(op1) == "number" and type(op2) == "number" then return op1 < op2 -- numeric comparison elseif type(op1) == "string" and type(op2) == "string" then return op1 < op2 -- lexicographic comparison else local h = getcomphandler(op1, op2, "__lt") if h then return (h(op1, op2)) else error(···) end end enda > bэквивалентноb < a. -
"le": операция
<=.function le_event (op1, op2) if type(op1) == "number" and type(op2) == "number" then return op1 <= op2 -- numeric comparison elseif type(op1) == "string" and type(op2) == "string" then return op1 <= op2 -- lexicographic comparison else local h = getcomphandler(op1, op2, "__le") if h then return (h(op1, op2)) else h = getcomphandler(op1, op2, "__lt") if h then return not h(op2, op1) else error(···) end end end enda >= bэквивалентноb <= a. Обратите внимание, что при отсутствии метаметода "le" Lua пытается использовать "lt", предполагая, чтоa <= bэквивалентноnot (b < a). -
"index": Доступ к индексу
table[key].function gettable_event (table, key) local h if type(table) == "table" then local v = rawget(table, key) if v ~= nil then return v end h = metatable(table).__index if h == nil then return nil end else h = metatable(table).__index if h == nil then error(···) end end if type(h) == "function" then return (h(table, key)) -- call the handler else return h[key] -- or repeat operation on it end end -
"newindex": Присваивание по индексу
table[key] = value.function settable_event (table, key, value) local h if type(table) == "table" then local v = rawget(table, key) if v ~= nil then rawset(table, key, value); return end h = metatable(table).__newindex if h == nil then rawset(table, key, value); return end else h = metatable(table).__newindex if h == nil then error(···) end end if type(h) == "function" then h(table, key,value) -- call the handler else h[key] = value -- or repeat operation on it end end -
"call": вызывается при вызове Lua значения.
function function_event (func, ...) if type(func) == "function" then return func(...) -- primitive call else local h = metatable(func).__call if h then return h(func, ...) else error(···) end end end
2.9 – Среды
Помимо метатаблиц, объекты типов поток, функция и пользовательские данные имеют связанную с ними другую таблицу, называемую их средой. Как и метатаблицы, среды — это обычные таблицы, и несколько объектов могут использовать одну и ту же среду.
Потоки создаются с использованием среды создающего потока. Пользовательские данные и функции C создаются с использованием среды создающей функции C. Невложенные функции Lua (созданные с помощью loadfile, loadstring или load) создаются с использованием среды создающего потока. Вложенные функции Lua создаются с использованием среды создающей функции Lua.
Среды, связанные с пользовательскими данными, не имеют значения для Lua. Это только удобная функция для программистов, чтобы связать таблицу с пользовательскими данными.
Среды, связанные с потоками, называются глобальными средами. Они используются в качестве среды по умолчанию для потоков и невложенных функций Lua, созданных потоком, и к ним можно напрямую получить доступ из кода C (см. §3.3).
Среду, связанную с функцией C, можно напрямую получить доступ из кода C (см. §3.3). Она используется в качестве среды по умолчанию для других функций C и пользовательских данных, созданных функцией.
Среды, связанные с функциями Lua, используются для разрешения всех обращений к глобальным переменным внутри функции (см. §2.3). Они используются в качестве среды по умолчанию для вложенных функций Lua, созданных функцией.
Вы можете изменить среду функции Lua или текущего потока, вызвав setfenv. Вы можете получить среду функции Lua или текущего потока, вызвав getfenv. Для манипулирования средой других объектов (пользовательские данные, функции C, другие потоки) необходимо использовать API C.
2.10 – Сбор мусора
Lua выполняет автоматическое управление памятью. Это означает, что вам не нужно беспокоиться ни о выделении памяти для новых объектов, ни об освобождении её, когда объекты больше не нужны. Lua автоматически управляет памятью, периодически запуская сборщик мусора для сбора всех мертвых объектов (то есть объектов, которые больше недоступны из Lua). Вся память, используемая Lua, подлежит автоматическому управлению: таблицы, пользовательские данные, функции, потоки, строки и т. д.
Lua реализует инкрементальный сборщик мусора помечания и очистки. Он использует два числа для управления циклами сбора мусора: паузу сборщика мусора и множитель шага сборщика мусора. Оба используют процентные точки в качестве единиц (так что значение 100 означает внутреннее значение 1).
Пауза сборщика мусора контролирует, как долго сборщик ждёт перед запуском нового цикла. Большие значения делают сборщик менее агрессивным. Значения меньше 100 означают, что сборщик не будет ждать для запуска нового цикла. Значение 200 означает, что сборщик ждёт удвоения общего объёма используемой памяти перед запуском нового цикла.
Множитель шага контролирует относительную скорость сборщика по отношению к выделению памяти. Большие значения делают сборщик более агрессивным, но также увеличивают размер каждого инкрементного шага. Значения меньше 100 делают сборщик слишком медленным, и это может привести к тому, что сборщик никогда не завершит цикл. Значение по умолчанию 200 означает, что сборщик работает в «два раза» быстрее, чем выделение памяти.
Вы можете изменить эти значения, вызвав lua_gc в C или collectgarbage в Lua. С помощью этих функций вы также можете напрямую контролировать сборщик (например, остановить и перезапустить его).
2.10.1 – Метаметоды сбора мусора
Используя API C, вы можете установить метаметоды сборки мусора для пользовательских данных (см. §2.8). Эти метаметоды также называются финализаторами. Финализаторы позволяют вам согласовать сборку мусора Lua с управлением внешними ресурсами (такими как закрытие файлов, сетевых или баз данных подключений или освобождение своей памяти).
Необработанные пользовательские данные с полем __gc в их метатаблицах не собираются сборщиком мусора немедленно. Вместо этого Lua помещает их в список. После сбора мусора Lua выполняет эквивалент следующей функции для каждого пользовательского данных в этом списке:
function gc_event (udata)
local h = metatable(udata).__gc
if h then
h(udata)
end
end В конце каждого цикла сбора мусора финализаторы для пользовательских данных вызываются в обратном порядке их создания среди тех, которые были собраны в этом цикле. То есть, первый финализатор, который будет вызван, — это финализатор, связанный с пользовательскими данными, созданными последними в программе. Сами пользовательские данные освобождаются только в следующем цикле сбора мусора.
2.10.2 – Слабые таблицы
Слабая таблица — это таблица, элементы которой являются слабыми ссылками. Слабая ссылка игнорируется сборщиком мусора. Другими словами, если единственные ссылки на объект — это слабые ссылки, то сборщик мусора соберет этот объект.
Слабая таблица может иметь слабые ключи, слабые значения или оба. Таблица со слабыми ключами позволяет собирать ее ключи, но предотвращает сбор ее значений. Таблица со слабыми ключами и слабыми значениями позволяет собирать и ключи, и значения. В любом случае, если ключ или значение собираются, вся пара удаляется из таблицы. Слабость таблицы контролируется полем __mode её метатаблицы. Если поле __mode является строкой, содержащей символ 'k', ключи в таблице являются слабыми. Если __mode содержит 'v', значения в таблице являются слабыми.
После использования таблицы в качестве метатаблицы вы не должны изменять значение её поля __mode. В противном случае, слабое поведение таблиц, управляемых этой метатаблицей, является неопределенным.
2.11 – Корутины
Lua поддерживает корутины, также называемые кооперативным многопоточностью. Корутина в Lua представляет собой независимую нить выполнения. Однако в отличие от потоков в многопоточных системах корутина приостанавливает своё выполнение только при явном вызове функции yield.
Вы создаёте корутину с помощью вызова coroutine.create. Единственный её аргумент — функция, которая является основной функцией корутины. Функция create только создаёт новую корутину и возвращает ссылку на неё (объект типа thread); она не запускает выполнение корутины.
Когда вы впервые вызываете coroutine.resume, передавая в качестве первого аргумента поток, возвращённый coroutine.create, корутина начинает своё выполнение с первой строки её основной функции. Дополнительные аргументы, переданные в coroutine.resume, передаются основной функции корутины. После того, как корутина начнёт выполняться, она выполняется до тех пор, пока не завершится или не передаст управление.
Корутина может завершить своё выполнение двумя способами: нормально, когда её главная функция возвращается (явным или неявным образом, после последней инструкции); и аномально, если произошла неохраняемая ошибка. В первом случае, coroutine.resume возвращает true, а также любые значения, возвращённые основной функцией корутины. В случае ошибок coroutine.resume возвращает false и сообщение об ошибке.
Корутина передаёт управление, вызывая coroutine.yield. Когда корутина передаёт управление, соответствующий вызов coroutine.resume возвращает немедленно, даже если передача управления происходит внутри вложенных вызовов функций (то есть не в основной функции, а в функции, непосредственно или косвенно вызываемой основной функцией). В случае передачи управления coroutine.resume также возвращает true и любые значения, переданные в coroutine.yield. В следующий раз, когда вы возобновляете ту же корутину, она продолжает своё выполнение с точки, где передавала управление, при этом вызов coroutine.yield возвращает любые дополнительные аргументы, переданные в coroutine.resume.
Как и coroutine.create, функция coroutine.wrap также создаёт корутину, но вместо возврата самой корутины она возвращает функцию, которая при вызове возобновляет корутину. Любые аргументы, передаваемые в эту функцию, передаются как дополнительные аргументы в coroutine.resume. coroutine.wrap возвращает все значения, возвращённые coroutine.resume, за исключением первого (булевый код ошибки). В отличие от coroutine.resume, coroutine.wrap не обрабатывает ошибки; любая ошибка передаётся вызывающей функции.
В качестве примера рассмотрим следующий код:
function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body", a, b)
local r = foo(a+1)
print("co-body", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body", r, s)
return b, "end"
end)
print("main", coroutine.resume(co, 1, 10))
print("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))
При его выполнении выводится следующий результат:
co-body 1 10 foo 2 main true 4 co-body r main true 11 -9 co-body x y main true 10 end main false cannot resume dead coroutine
3 – API приложения
В этом разделе описан C API для Lua, то есть набор C функций, доступных программе-хосту для взаимодействия с Lua. Все функции API, связанные типы и константы объявлены в файле заголовков lua.h.
Даже когда мы используем термин «функция», любая возможность в API может быть реализована как макрос вместо этого. Все такие макросы используют каждый из своих аргументов ровно один раз (кроме первого аргумента, который всегда является состоянием Lua), и поэтому не генерируют никаких скрытых побочных эффектов.
Как и в большинстве C библиотек, функции API Lua не проверяют свои аргументы на корректность или согласованность. Однако вы можете изменить это поведение, скомпилировав Lua с надлежащим определением для макроса luai_apicheck, в файле luaconf.h.
3.1 – Стек
Lua использует виртуальный стек для передачи значений в C и из C. Каждый элемент этого стека представляет собой значение Lua (nil, число, строка и т. д.).
Всякий раз, когда Lua вызывает C, вызываемая функция получает новый стек, который независим от предыдущих стеков и от стеков C функций, которые всё ещё активны. Этот стек изначально содержит любые аргументы функции C, и именно в него функция C помещает свои результаты, которые будут возвращены вызывающей стороне (см. lua_CFunction).
Для удобства большинство операций запроса в API не следуют строгой дисциплине стека. Вместо этого они могут ссылаться на любой элемент в стеке, используя индекс: положительный индекс представляет абсолютную позицию в стеке (начиная с 1); отрицательный индекс представляет смещение относительно вершины стека. Более точно, если стек имеет n элементов, то индекс 1 представляет первый элемент (то есть элемент, который был помещён в стек первым), а индекс n представляет последний элемент; индекс -1 также представляет последний элемент (то есть элемент на вершине) и индекс -n представляет первый элемент. Мы говорим, что индекс валиден, если он лежит между 1 и вершиной стека (то есть, если 1 ≤ abs(index) ≤ top).
3.2 – Размер стека
При взаимодействии с API Lua вы несете ответственность за обеспечение согласованности. В частности, вы несёте ответственность за предотвращение переполнения стека. Вы можете использовать функцию lua_checkstack для увеличения размера стека.
Всякий раз, когда Lua вызывает C, она гарантирует, что доступно по меньшей мере LUA_MINSTACK позиций стека. LUA_MINSTACK определена как 20, так что, как правило, вам не нужно беспокоиться о пространстве стека, если только ваш код не содержит циклов, которые добавляют элементы в стек.
Большинство функций запроса принимают в качестве индексов любые значения внутри доступного пространства стека, то есть индексы до максимального размера стека, который вы установили с помощью lua_checkstack. Такие индексы называются допустимыми индексами. Более формально, мы определяем допустимый индекс следующим образом:
(index < 0 && abs(index) <= top) || (index > 0 && index <= stackspace)
Обратите внимание, что 0 никогда не является допустимым индексом.
3.3 – Псевдоиндексы
Если не указано иное, любая функция, которая принимает допустимые индексы, также может быть вызвана с псевдоиндексами, которые представляют некоторые значения Lua, доступные коду C, но которые не находятся в стеке. Псевдоиндексы используются для доступа к среде потока, среде функции, регистру и значениям-указателям функции C (см. §3.4).
Среда потока (где хранятся глобальные переменные) всегда находится по псевдоиндексу LUA_GLOBALSINDEX. Среда выполняемой функции C всегда находится по псевдоиндексу LUA_ENVIRONINDEX.
Для доступа и изменения значения глобальных переменных вы можете использовать обычные операции над таблицей среды. Например, чтобы получить значение глобальной переменной, выполните
lua_getfield(L, LUA_GLOBALSINDEX, varname);
3.4 – C-замыкания
При создании функции C возможно ассоциировать с ней некоторые значения, таким образом создавая C-замыкание; эти значения называются указателями и доступны функции всякий раз, когда она вызывается (см. lua_pushcclosure).
Всякий раз, когда вызывается функция C, её указатели расположены по определённым псевдоиндексам. Эти псевдоиндексы генерируются макросом lua_upvalueindex. Первое значение, связанное с функцией, находится по позиции lua_upvalueindex(1), и так далее. Любой доступ к lua_upvalueindex(n), где n больше числа указателей текущей функции (но не больше 256), создаёт допустимый (но недействительный) индекс.
3.5 – Регистр
Lua предоставляет регистр, предопределённую таблицу, которую любой код C может использовать для хранения любого значения Lua, которое ему нужно сохранить. Эта таблица всегда находится по псевдоиндексу LUA_REGISTRYINDEX. Любая C библиотека может хранить данные в этой таблице, но она должна позаботиться о выборе ключей, отличных от используемых другими библиотеками, чтобы избежать коллизий. Обычно вы должны использовать в качестве ключа строку, содержащую имя вашей библиотеки, или лёгкий пользовательский данные с адресом C объекта в вашем коде.
Целочисленные ключи в регистре используются механизмом ссылок, реализованным вспомогательной библиотекой, и поэтому не должны использоваться для других целей.
3.6 – Обработка ошибок в C
Внутренне Lua использует C механизм longjmp для обработки ошибок. (Вы также можете выбрать использование исключений, если вы используете C++; см. файл luaconf.h.) Когда Lua сталкивается с какой-либо ошибкой (например, ошибки выделения памяти, ошибки типа, синтаксические ошибки и ошибки выполнения), она генерирует ошибку; то есть она выполняет длинный прыжок. Защищённая среда использует setjmp для установки точки восстановления; любая ошибка переходит к самой последней активной точке восстановления.
Большинство функций API могут генерировать ошибку, например, из-за ошибки выделения памяти. Документация для каждой функции указывает, может ли она генерировать ошибки.
Внутри C функции вы можете сгенерировать ошибку, вызвав lua_error.
3.7 – Функции и типы[-o, +p, x]
Здесь мы перечислим все функции и типы из C API в алфавитном порядке. Каждая функция имеет индикатор, такой как этот:
Первое поле, o, указывает, сколько элементов функция извлекает из стека. Второе поле, p, определяет, сколько элементов функция помещает в стек. (Любая функция всегда помещает свои результаты в стек после извлечения аргументов.) Поле в формате x|y означает, что функция может поместить (или извлечь) x или y элементов в зависимости от ситуации; вопросительный знак '?' означает, что невозможно определить, сколько элементов функция извлекает/помещает, только глядя на её аргументы (например, это может зависеть от содержимого стека). Третье поле, x, указывает, может ли функция генерировать ошибки: '-' означает, что функция никогда не генерирует ошибку; 'm' означает, что функция может генерировать ошибку только из-за недостатка памяти; 'e' означает, что функция может генерировать другие виды ошибок; 'v' означает, что функция может намеренно сгенерировать ошибку.
lua_Alloc
typedef void * (*lua_Alloc) (void *ud,
void *ptr,
size_t osize,
size_t nsize); Тип функции выделения памяти, используемой состояниями Lua. Функция выделения должна обеспечивать функциональность, аналогичную realloc, но не идентичную. Её аргументы: ud, неявный указатель, переданный в lua_newstate; ptr, указатель на выделяемый/перевыделяемый/освобождаемый блок; osize, исходный размер блока; nsize, новый размер блока. ptr равно NULL тогда и только тогда, когда osize равно нулю. Когда nsize равно нулю, функция выделения должна возвращать NULL; если osize не равно нулю, она должна освободить блок, на который указывает ptr. Когда nsize не равно нулю, функция выделения возвращает NULL тогда и только тогда, когда не может удовлетворить запрос. Когда nsize не равно нулю, а osize равно нулю, функция выделения должна вести себя как malloc. Когда nsize и osize не равны нулю, функция выделения ведет себя как realloc. Lua предполагает, что функция выделения никогда не терпит неудачу, когда osize >= nsize.
Вот простое реализация функции выделения. Она используется в вспомогательной библиотеке для luaL_newstate.
static void *l_alloc (void *ud, void *ptr, size_t osize,
size_t nsize) {
(void)ud; (void)osize; /* not used */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
Этот код предполагает, что free(NULL) не имеет эффекта и что realloc(NULL, size) эквивалентно malloc(size). ANSI C гарантирует оба поведения.
lua_atpanic[-0, +0, -]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
Устанавливает новую функцию обработки критических ошибок и возвращает предыдущую.
Если ошибка происходит вне любой защищённой среды, Lua вызывает функцию обработки критических ошибок, а затем вызывает exit(EXIT_FAILURE), тем самым завершая работу прикладного приложения. Ваша функция обработки критических ошибок может избежать этого завершения, никогда не возвращаясь (например, используя длинный прыжок).
Функция обработки критических ошибок может получить доступ к сообщению об ошибке в верхней части стека.
lua_call[-(nargs + 1), +nresults, e]
void lua_call (lua_State *L, int nargs, int nresults);
Вызывает функцию.
Для вызова функции используется следующий протокол: сначала функция, которую нужно вызвать, помещается в стек; затем аргументы функции помещаются в прямом порядке; то есть, первый аргумент помещается первым. Наконец, вызывается lua_call; nargs — количество аргументов, помещённых в стек. Все аргументы и значение функции извлекаются из стека при вызове функции. Результаты функции помещаются в стек при возвращении функции. Количество результатов корректируется до nresults, если nresults не LUA_MULTRET. В этом случае в стек помещаются все результаты от функции. Lua позаботится о том, чтобы возвращаемые значения уместились в области стека. Результаты функции помещаются в стек в прямом порядке (первый результат помещается первым), так что после вызова последний результат находится в верхней части стека.
Любые ошибки внутри вызываемой функции передаются вверх (с помощью longjmp).
Следующий пример показывает, как приложение может выполнить эквивалент данного кода Lua:
a = f("how", t.x, 14)
Вот он на C:
lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */ lua_pushstring(L, "how"); /* 1st argument */ lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* table to be indexed */ lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */ lua_remove(L, -2); /* remove 't' from the stack */ lua_pushinteger(L, 14); /* 3rd argument */ lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */ lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* set global 'a' */
Обратите внимание, что код выше «сбалансирован»: в конце он возвращает стек в исходное состояние. Это считается хорошей практикой программирования.
lua_CFunction
typedef int (*lua_CFunction) (lua_State *L);
Тип для функций C.
Для корректного взаимодействия с Lua функция C должна использовать следующий протокол, определяющий способ передачи параметров и результатов: функция C получает свои аргументы из Lua из стека в прямом порядке (первый аргумент помещается первым). Таким образом, когда функция начинается, lua_gettop(L) возвращает количество аргументов, полученных функцией. Первый аргумент (если он есть) находится на индексе 1, а последний — на индексе lua_gettop(L). Для возвращения значений в Lua функция C просто помещает их в стек в прямом порядке (первый результат помещается первым), и возвращает количество результатов. Любое другое значение в стеке ниже результатов будет правильно удалено Lua. Как и функция Lua, вызываемая Lua, функция C также может возвращать множество результатов.
В качестве примера, следующая функция получает переменное число числовых аргументов и возвращает их среднее значение и сумму:
static int foo (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number sum = 0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushstring(L, "incorrect argument");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* first result */
lua_pushnumber(L, sum); /* second result */
return 2; /* number of results */
}
lua_checkstack[-0, +0, m]
int lua_checkstack (lua_State *L, int extra);
Обеспечивает, что в стеке есть как минимум extra свободных слотов. Возвращает false, если не удаётся увеличить стек до этого размера. Эта функция никогда не уменьшает размер стека; если стек уже больше нового размера, он остаётся без изменений.
lua_close[-0, +0, -]
void lua_close (lua_State *L);
Уничтожает все объекты в данном состоянии Lua (вызывая соответствующие методы мета-сборки мусора, если таковые имеются) и освобождает всю динамическую память, используемую этим состоянием. На некоторых платформах вам может не потребоваться вызывать эту функцию, так как все ресурсы естественным образом освобождаются при завершении работы приложения. С другой стороны, долгоживущие программы, такие как демон или веб-сервер, могут потребовать освобождения состояний, как только они больше не нужны, чтобы избежать чрезмерного роста.
lua_concat[-n, +1, e]
void lua_concat (lua_State *L, int n);
Объединяет n значений в верхней части стека, извлекает их и оставляет результат в верхней части. Если n равно 1, результатом является единственное значение в стеке (то есть, функция ничего не делает); если n равно 0, результатом является пустая строка. Объединение выполняется в соответствии с обычной семантикой Lua (см. §2.5.4).
lua_cpcall[-0, +(0|1), -]
int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
Вызывает функцию C func в защищённом режиме. func начинается с одного элемента в стеке, лёгкого пользователя, содержащего ud. В случае ошибок lua_cpcall возвращает те же коды ошибок, что и lua_pcall, плюс объект ошибки в верхней части стека; в противном случае возвращает ноль и не изменяет стек. Все значения, возвращаемые func отбрасываются.
lua_createtable[-0, +1, m]
void lua_createtable (lua_State *L, int narr, int nrec);
Создаёт новую пустую таблицу и помещает её в стек. Новая таблица предварительно выделяет место для narr элементов массива и nrec элементов, не являющихся элементами массива. Это предварительное выделение полезно, когда известно точное количество элементов в таблице. В противном случае вы можете использовать функцию lua_newtable.
lua_dump[-0, +0, m]
int lua_dump (lua_State *L, lua_Writer writer, void *data);
Преобразует функцию в бинарный фрагмент. Принимает функцию Lua в верхней части стека и производит бинарный фрагмент, который, при повторной загрузке, приводит к функции, эквивалентной той, что была преобразована. При генерации частей фрагмента lua_dump вызывает функцию writer (см. lua_Writer) с заданным data для их записи.
Возвращаемое значение — код ошибки, возвращённый последним вызовом функции записи; 0 означает отсутствие ошибок.
Эта функция не извлекает функцию Lua из стека.
lua_equal[-0, +0, e]
int lua_equal (lua_State *L, int index1, int index2);
Возвращает 1, если два значения по допустимым индексам index1 и index2 равны, следуя семантике оператора Lua == (то есть, может вызывать метаметоды). В противном случае возвращает 0. Также возвращает 0, если любой из индексов недопустим.
lua_error[-1, +0, v]
int lua_error (lua_State *L);
Генерирует ошибку Lua. Сообщение об ошибке (которое может фактически быть значением Lua любого типа) должно находиться в верхней части стека. Эта функция выполняет длинный прыжок и поэтому никогда не возвращается. (см. luaL_error).
lua_gc[-0, +0, e]
int lua_gc (lua_State *L, int what, int data);
Управляет сборщиком мусора.
Эта функция выполняет несколько задач в зависимости от значения параметра %%%CODE_BLOCK_409%%:
-
LUA_GCSTOP: останавливает сборщик мусора. -
LUA_GCRESTART: перезапускает сборщик мусора. -
LUA_GCCOLLECT: выполняет полный цикл сборки мусора. -
LUA_GCCOUNT: возвращает текущее количество используемой памяти (в Кбайтах) Lua. -
LUA_GCCOUNTB: возвращает остаток от деления текущего объёма памяти, используемой Lua, в байтах, на 1024. -
LUA_GCSTEP: выполняет инкрементный шаг сборки мусора. Размер шага контролируетсяdata(более крупные значения означают больше шагов) не определённым способом. Если вы хотите контролировать размер шага, вам нужно экспериментально подобрать значениеdata. Функция возвращает 1, если шаг завершил цикл сборки мусора. -
LUA_GCSETPAUSE: устанавливаетdataв качестве нового значения для паузы сборщика (см. §2.10). Функция возвращает предыдущее значение паузы. -
LUA_GCSETSTEPMUL: устанавливаетdataв качестве нового значения для множителя шага сборщика (см. §2.10). Функция возвращает предыдущее значение множителя шага.
lua_getallocf[-0, +0, -]
lua_Alloc lua_getallocf (lua_State *L, void **ud);
Возвращает функцию выделения памяти данного состояния. Если ud не NULL, Lua сохраняет в *ud неявный указатель, переданный в lua_newstate.
lua_getfenv[-0, +1, -]
void lua_getfenv (lua_State *L, int index);
Помещает в стек таблицу окружения значения по заданному индексу.
lua_getfield[-0, +1, e]
void lua_getfield (lua_State *L, int index, const char *k);
Помещает на стек значение t[k], где t — значение по заданному допустимому индексу. Как и в Lua, эта функция может вызывать метаметод для события "index" (см. §2.8).
lua_getglobal[-0, +1, e]
void lua_getglobal (lua_State *L, const char *name);
Помещает на стек значение глобальной переменной name. Она определена как макрос:
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
lua_getmetatable[-0, +(0|1), -]
int lua_getmetatable (lua_State *L, int index);
Помещает на стек метатаблицу значения по заданному допустимому индексу. Если индекс недопустим или у значения нет метатаблицы, функция возвращает 0 и ничего не помещает на стек.
lua_gettable[-1, +1, e]
void lua_gettable (lua_State *L, int index);
Помещает на стек значение t[k], где t — значение по заданному допустимому индексу, а k — значение, находящееся в верхней части стека.
Эта функция извлекает ключ со стека (помещая полученное значение на его место). Как и в Lua, эта функция может вызывать метаметод для события "index" (см. §2.8).
lua_gettop[-0, +0, -]
int lua_gettop (lua_State *L);
Возвращает индекс верхнего элемента стека. Так как индексы начинаются с 1, это значение равно количеству элементов на стеке (и 0 означает пустой стек).
lua_insert[-1, +1, -]
void lua_insert (lua_State *L, int index);
Перемещает верхний элемент в заданный допустимый индекс, сдвигая элементы над этим индексом вверх, чтобы освободить место. Нельзя вызывать с псевдоиндексом, так как псевдоиндекс не является фактической позицией в стеке.
lua_Integer
typedef ptrdiff_t lua_Integer;
Тип, используемый API Lua для представления целых чисел.
По умолчанию это ptrdiff_t, что обычно является наибольшим знаковым целочисленным типом, который машина обрабатывает "без проблем".
lua_isboolean[-0, +0, -]
int lua_isboolean (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу имеет тип boolean, и 0 в противном случае.
lua_iscfunction[-0, +0, -]
int lua_iscfunction (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу является функцией C, и 0 в противном случае.
lua_isfunction[-0, +0, -]
int lua_isfunction (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу является функцией (C или Lua), и 0 в противном случае.
lua_islightuserdata[-0, +0, -]
int lua_islightuserdata (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу является лёгким userdata, и 0 в противном случае.
lua_isnil[-0, +0, -]
int lua_isnil (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу равно nil, и 0 в противном случае.
lua_isnone[-0, +0, -]
int lua_isnone (lua_State *L, int index);
Возвращает 1, если заданный допустимый индекс недействителен (то есть, ссылается на элемент за пределами текущего стека), и 0 в противном случае.
lua_isnoneornil[-0, +0, -]
int lua_isnoneornil (lua_State *L, int index);
Возвращает 1, если заданный допустимый индекс недействителен (то есть, ссылается на элемент за пределами текущего стека) или значение по этому индексу равно nil, и 0 в противном случае.
lua_isnumber[-0, +0, -]
int lua_isnumber (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу является числом или строкой, преобразуемой в число, и 0 в противном случае.
lua_isstring[-0, +0, -]
int lua_isstring (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу является строкой или числом (которое всегда может быть преобразовано в строку), и 0 в противном случае.
lua_istable[-0, +0, -]
int lua_istable (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу является таблицей, и 0 в противном случае.
lua_isthread[-0, +0, -]
int lua_isthread (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу является потоком, и 0 в противном случае.
lua_isuserdata[-0, +0, -]
int lua_isuserdata (lua_State *L, int index);
Возвращает 1, если значение по заданному допустимому индексу является userdata (полное или лёгкое), и 0 в противном случае.
lua_lessthan[-0, +0, e]
int lua_lessthan (lua_State *L, int index1, int index2);
Возвращает 1, если значение по допустимому индексу index1 меньше значения по допустимому индексу index2, следуя семантике оператора Lua < (то есть, может вызывать метаметоды). В противном случае возвращает 0. Также возвращает 0, если любой из индексов недействителен.
lua_load[-0, +1, -]
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname); Загружает Lua фрагмент кода. Если ошибок нет, lua_load помещает скомпилированный фрагмент как Lua функцию в верхнюю часть стека. В противном случае, помещает сообщение об ошибке. Возвращаемые значения lua_load:
- 0: без ошибок;
-
LUA_ERRSYNTAX: синтаксическая ошибка во время предварительной компиляции; -
LUA_ERRMEM: ошибка выделения памяти.
Эта функция только загружает фрагмент; она не выполняет его.
lua_load автоматически определяет, является ли фрагмент текстовым или двоичным, и загружает его соответствующим образом (см. программу luac).
Функция lua_load использует предоставленную пользователем функцию reader для чтения фрагмента (см. lua_Reader). Аргумент data — это непрозрачное значение, передаваемое функции-чтецу.
Аргумент chunkname задаёт имя фрагменту, которое используется для сообщений об ошибках и в отладочной информации (см. §3.8).
lua_newstate[-0, +0, -]
lua_State *lua_newstate (lua_Alloc f, void *ud);
Создаёт новый, независимый состояние. Возвращает NULL если состояние не может быть создано (из-за недостатка памяти). Аргумент f — функция-аллокатор; Lua выполняет все выделения памяти для этого состояния через эту функцию. Второй аргумент, ud, — это непрозрачный указатель, который Lua просто передаёт аллокатору в каждом вызове.
lua_newtable[-0, +1, m]
void lua_newtable (lua_State *L);
Создаёт новую пустую таблицу и помещает её на стек. Эквивалентно lua_createtable(L, 0, 0).
lua_newthread[-0, +1, m]
lua_State *lua_newthread (lua_State *L);
Создаёт новый поток, помещает его на стек и возвращает указатель на lua_State, который представляет этот новый поток. Новое состояние, возвращаемое этой функцией, совместно использует все глобальные объекты (такие как таблицы) с исходным состоянием, но имеет независимый стек выполнения.
Нет явной функции для закрытия или уничтожения потока. Потоки подвержены сбору мусора, как и любой Lua объект.
lua_newuserdata[-0, +1, m]
void *lua_newuserdata (lua_State *L, size_t size);
Эта функция выделяет новый блок памяти заданного размера, помещает на стек новый полный userdata с адресом блока и возвращает этот адрес.
Userdata представляют C значения в Lua. Полный userdata представляет собой блок памяти. Это объект (как таблица): его необходимо создать, у него может быть собственный метатаблица, и можно определить, когда он собирается. Полный userdata равен только самому себе (при сыром сравнении).
Когда Lua собирает полный userdata с метаметодом gc, Lua вызывает метаметод и отмечает userdata как завершённый. Когда этот userdata собирается снова, Lua освобождает соответствующую память.
lua_next[-1, +(2|0), e]
int lua_next (lua_State *L, int index);
Извлекает ключ со стека и помещает пару ключ-значение из таблицы по данному индексу (следующую пару после данного ключа). Если больше элементов в таблице нет, lua_next возвращает 0 (и ничего не помещает на стек).
Типичный обход выглядит так:
/* table is in the stack at index 't' */
lua_pushnil(L); /* first key */
while (lua_next(L, t) != 0) {
/* uses 'key' (at index -2) and 'value' (at index -1) */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* removes 'value'; keeps 'key' for next iteration */
lua_pop(L, 1);
} Во время обхода таблицы не вызывайте lua_tolstring непосредственно на ключе, если вы не уверены, что ключ на самом деле является строкой. Помните, что lua_tolstring меняет значение по данному индексу; это запутывает следующий вызов lua_next.
lua_Number
typedef double lua_Number;
Тип чисел в Lua. По умолчанию это double, но это можно изменить в luaconf.h.
Через файл конфигурации можно изменить Lua на работу с другим типом чисел (например, float или long).
lua_objlen[-0, +0, -]
size_t lua_objlen (lua_State *L, int index);
Возвращает "длину" значения по заданному допустимому индексу: для строк — это длина строки; для таблиц — результат оператора длины ('#'); для userdata — размер блока памяти, выделенного для userdata; для других значений — 0.
lua_pcall[-(nargs + 1), +(nresults|1), -]
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
Вызывает функцию в защищённом режиме.
Как nargs и nresults, имеют то же значение, что и в lua_call. Если ошибок во время вызова нет, lua_pcall ведёт себя точно как lua_call. Однако, если возникает какая-либо ошибка, lua_pcall перехватывает её, помещает единственное значение на стек (сообщение об ошибке) и возвращает код ошибки. Как и lua_call, lua_pcall всегда удаляет функцию и её аргументы со стека.
Если errfunc равно 0, то сообщение об ошибке, возвращённое на стеке, — это точное исходное сообщение об ошибке. В противном случае, errfunc — индекс стека функции обработки ошибок. (В текущей реализации этот индекс не может быть псевдоиндексом.) В случае ошибок во время выполнения эта функция будет вызвана с сообщением об ошибке, а её возвращаемое значение будет сообщением, возвращённым на стеке lua_pcall.
Обычно функция обработки ошибок используется для добавления дополнительной отладочной информации к сообщению об ошибке, например, трассировки стека. Такая информация не может быть собрана после возвращения lua_pcall, так как к тому времени стек уже развёрнут.
Функция lua_pcall возвращает 0 в случае успеха или один из следующих кодов ошибки (определённых в lua.h):
-
LUA_ERRRUN: ошибка во время выполнения. -
LUA_ERRMEM: ошибка выделения памяти. В таких случаях Lua не вызывает функцию обработчика ошибок. -
LUA_ERRERR: ошибка при выполнении функции обработчика ошибок.
lua_pop[-n, +0, -]
void lua_pop (lua_State *L, int n);
Извлекает n элементов из стека.
lua_pushboolean[-0, +1, -]
void lua_pushboolean (lua_State *L, int b);
Помещает булево значение с значением b на стек.
lua_pushcclosure[-n, +1, m]
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
Помещает новый C-замыкание на стек.
При создании C-функции можно ассоциировать с ней некоторые значения, создавая C-замыкание (см. §3.4); эти значения доступны функции при её вызове. Для ассоциации значений с C-функцией сначала эти значения должны быть помещены на стек (если значений несколько, то первое значение помещается первым). Затем вызывается lua_pushcclosure для создания и помещения C-функции на стек, при этом аргумент n указывает, сколько значений должно быть ассоциировано с функцией. lua_pushcclosure также извлекает эти значения со стека.
Максимальное значение для n равно 255.
lua_pushcfunction[-0, +1, m]
void lua_pushcfunction (lua_State *L, lua_CFunction f);
Помещает C-функцию на стек. Эта функция получает указатель на C-функцию и помещает на стек значение Lua типа function, которое, при вызове, вызывает соответствующую C-функцию.
Любая функция, регистрируемая в Lua, должна следовать правильному протоколу для получения параметров и возвращения результатов (см. lua_CFunction).
lua_pushcfunction определён как макрос:
#define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)
lua_pushfstring[-0, +1, m]
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
Помещает отформатированную строку на стек и возвращает указатель на эту строку. Аналогично C-функции sprintf, но с некоторыми важными отличиями:
- Вам не нужно выделять память для результата: результат — строка Lua, и Lua заботится об выделении (и освобождении через сборку мусора) памяти.
- Спецификаторы преобразования довольно ограничены. Нет флагов, ширины или точности. Спецификаторы преобразования могут быть только '
%%' (вставляет '%' в строку), '%s' (вставляет нуль-терминированную строку без ограничений по размеру), '%f' (вставляетlua_Number), '%p' (вставляет указатель как шестнадцатеричное число), '%d' (вставляетint), и '%c' (вставляетintкак символ).
lua_pushinteger[-0, +1, -]
void lua_pushinteger (lua_State *L, lua_Integer n);
Помещает число со значением n на стек.
lua_pushlightuserdata[-0, +1, -]
void lua_pushlightuserdata (lua_State *L, void *p);
Помещает легкое пользовательское данные на стек.
Пользовательские данные представляют C-значения в Lua. Легкое пользовательское данные представляют указатель. Это значение (как число): вы его не создаёте, у него нет отдельного мета-таблицы и он не собирается мусор (поскольку никогда не создавался). Легкое пользовательское данные равно «любому» легкому пользовательскому данным с тем же C-адресом.
lua_pushliteral[-0, +1, m]
void lua_pushliteral (lua_State *L, const char *s);
Этот макрос эквивалентен lua_pushlstring, но может использоваться только когда s является литеральной строкой. В этих случаях он автоматически предоставляет длину строки.
lua_pushlstring[-0, +1, m]
void lua_pushlstring (lua_State *L, const char *s, size_t len);
Помещает строку по указателю s с размером len на стек. Lua создает (или повторно использует) внутреннюю копию данной строки, поэтому память по адресу s может быть освобождена или повторно использована сразу после возврата функции. Строка может содержать вложенные нули.
lua_pushnil[-0, +1, -]
void lua_pushnil (lua_State *L);
Помещает значение nil на стек.
lua_pushnumber[-0, +1, -]
void lua_pushnumber (lua_State *L, lua_Number n);
Помещает число со значением n на стек.
lua_pushstring[-0, +1, m]
void lua_pushstring (lua_State *L, const char *s);
Помещает нуль-терминированную строку по указателю s на стек. Lua создает (или повторно использует) внутреннюю копию данной строки, поэтому память по адресу s может быть освобождена или повторно использована сразу после возврата функции. Строка не может содержать вложенных нулей; предполагается, что она заканчивается на первом нуле.
lua_pushthread[-0, +1, -]
int lua_pushthread (lua_State *L);
Помещает поток, представленный L на стек. Возвращает 1, если этот поток является основным потоком его состояния.
lua_pushvalue[-0, +1, -]
void lua_pushvalue (lua_State *L, int index);
Помещает копию элемента по данному индексу на стек.
lua_pushvfstring[-0, +1, m]
const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp); Эквивалентно lua_pushfstring, за исключением того, что получает va_list вместо переменного числа аргументов.
lua_rawequal[-0, +0, -]
int lua_rawequal (lua_State *L, int index1, int index2);
Возвращает 1, если два значения в допустимых индексах index1 и index2 примитивно равны (то есть без вызова мета-методов). В противном случае возвращает 0. Также возвращает 0, если любой из индексов недопустим.
lua_rawget[-1, +1, -]
void lua_rawget (lua_State *L, int index);
Аналогично lua_gettable, но выполняет прямой доступ (т. е. без мета-методов).
lua_rawgeti[-0, +1, -]
void lua_rawgeti (lua_State *L, int index, int n);
Помещает на стек значение t[n], где t — значение по данному допустимому индексу. Доступ прямой; то есть, он не вызывает мета-методы.
lua_rawset[-2, +0, m]
void lua_rawset (lua_State *L, int index);
Аналогично lua_settable, но выполняет присваивание без мета-методов.
lua_rawseti[-1, +0, m]
void lua_rawseti (lua_State *L, int index, int n);
Выполняет эквивалент t[n] = v, где t — значение по данному допустимому индексу, а v — значение в верхней части стека.
Эта функция извлекает значение со стека. Присваивание производится без вызова мета-методов.
lua_Reader
typedef const char * (*lua_Reader) (lua_State *L,
void *data,
size_t *size); Функция чтения, используемая функцией lua_load. Каждый раз, когда требуется следующий фрагмент куска, lua_load вызывает функцию чтения, передавая ей параметр data. Функция чтения должна вернуть указатель на блок памяти с новым фрагментом куска и установить size на размер блока. Блок должен существовать до тех пор, пока функция чтения не будет вызвана снова. Для сигнализации о конце куска функция чтения должна вернуть NULL или установить size в ноль. Функция чтения может возвращать фрагменты любого размера, большего нуля.
lua_register[-0, +0, e]
void lua_register (lua_State *L,
const char *name,
lua_CFunction f); Устанавливает C-функцию f в качестве нового значения глобальной переменной name. Определена как макрос:
#define lua_register(L,n,f) \
(lua_pushcfunction(L, f), lua_setglobal(L, n))
lua_remove[-1, +0, -]
void lua_remove (lua_State *L, int index);
Удаляет элемент по указанному допустимому индексу, сдвигая элементы выше этого индекса для заполнения пробела. Не может быть вызван с псевдо-индексом, поскольку псевдо-индекс не является фактической позицией в стеке.
lua_replace[-1, +0, -]
void lua_replace (lua_State *L, int index);
Перемещает верхний элемент в заданную позицию (и извлекает его), не сдвигая никакой элемент (следовательно, заменяет значение в заданной позиции).
lua_resume[-?, +?, -]
int lua_resume (lua_State *L, int narg);
Запускает и возобновляет сопрограмму в заданном потоке.
Для запуска сопрограммы сначала создаётся новый поток (см. lua_newthread); затем на его стек помещается основная функция и любые аргументы; затем вызывается lua_resume с narg — количеством аргументов. Этот вызов возвращается, когда сопрограмма приостанавливается или завершает своё выполнение. При возврате стек содержит все значения, переданные в lua_yield, или все значения, возвращённые функцией тела. lua_resume возвращает LUA_YIELD, если сопрограмма уступает, 0, если сопрограмма завершается без ошибок, или код ошибки в случае ошибок (см. lua_pcall). В случае ошибок стек не разворачивается, поэтому вы можете использовать API отладки над ним. Сообщение об ошибке находится в верхней части стека. Для перезапуска сопрограммы вы помещаете на её стек только значения, которые должны быть переданы в качестве результатов из yield, и затем вызываете lua_resume.
lua_setallocf[-0, +0, -]
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
Изменяет функцию выделения памяти заданного состояния на f с данными пользователя ud.
lua_setfenv[-1, +0, -]
int lua_setfenv (lua_State *L, int index);
Извлекает таблицу со стека и устанавливает её в качестве новой среды для значения по указанному индексу. Если значение по заданному индексу не является функцией, потоком или пользовательскими данными, lua_setfenv возвращает 0. В противном случае возвращает 1.
lua_setfield[-1, +0, e]
void lua_setfield (lua_State *L, int index, const char *k);
Выполняет эквивалент t[k] = v, где t — значение по указанному допустимому индексу, а v — значение в верхней части стека.
Эта функция извлекает значение со стека. Как и в Lua, эта функция может вызвать мета-метод для события «newindex» (см. §2.8).
lua_setglobal[-1, +0, e]
void lua_setglobal (lua_State *L, const char *name);
Извлекает значение со стека и устанавливает его в качестве нового значения глобальной переменной name. Определяется как макрос:
#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)
lua_setmetatable[-1, +0, -]
int lua_setmetatable (lua_State *L, int index);
Извлекает таблицу со стека и устанавливает её в качестве нового метатаблицы для значения по указанному допустимому индексу.
lua_settable[-2, +0, e]
void lua_settable (lua_State *L, int index);
Выполняет эквивалент t[k] = v, где t — значение по указанному допустимому индексу, v — значение на вершине стека, а k — значение, расположенное непосредственно под вершиной.
Эта функция извлекает из стека и ключ, и значение. Как и в Lua, эта функция может вызвать метаметод для события "newindex" (см. §2.8).
lua_settop[-?, +?, -]
void lua_settop (lua_State *L, int index);
Принимает любой допустимый индекс или 0 и устанавливает вершину стека в этот индекс. Если новая вершина больше старой, новые элементы заполняются значением nil. Если index равно 0, все элементы стека удаляются.
lua_State
typedef struct lua_State lua_State;
Непрозрачная структура, хранящая весь состояние интерпретатора Lua. Библиотека Lua полностью реентерабельна: она не имеет глобальных переменных. Вся информация о состоянии хранится в этой структуре.
Указатель на это состояние должен передаваться в качестве первого аргумента каждой функции в библиотеке, кроме lua_newstate, которая создаёт состояние Lua с нуля.
lua_status[-0, +0, -]
int lua_status (lua_State *L);
Возвращает состояние потока L.
Состояние может быть 0 для обычного потока, кодом ошибки, если поток завершился с ошибкой, или LUA_YIELD, если поток приостановлен.
lua_toboolean[-0, +0, -]
int lua_toboolean (lua_State *L, int index);
Преобразует Lua-значение по указанному допустимому индексу в значение C-булевого типа (0 или 1). Как и все проверки в Lua, lua_toboolean возвращает 1 для любого Lua-значения, отличного от false и nil; в противном случае возвращает 0. Также возвращает 0 при вызове с недопустимым индексом. (Если вы хотите принимать только фактические значения boolean, используйте lua_isboolean для проверки типа значения.)
lua_tocfunction[-0, +0, -]
lua_CFunction lua_tocfunction (lua_State *L, int index);
Преобразует значение по указанному допустимому индексу в C-функцию. Это значение должно быть C-функцией; в противном случае, возвращает NULL.
lua_tointeger[-0, +0, -]
lua_Integer lua_tointeger (lua_State *L, int index);
Преобразует Lua-значение по указанному допустимому индексу в целочисленное значение C-типа lua_Integer. Lua-значение должно быть числом или строкой, преобразуемой в число (см. §2.2.1); в противном случае, lua_tointeger возвращает 0.
Если число не является целым, оно усекается каким-то неопределённым способом.
lua_tolstring[-0, +0, m]
const char *lua_tolstring (lua_State *L, int index, size_t *len);
Преобразует Lua-значение по указанному допустимому индексу в C-строку. Если len не NULL, он также устанавливает *len с длиной строки. Lua-значение должно быть строкой или числом; в противном случае функция возвращает NULL. Если значение является числом, то lua_tolstring также изменяет фактическое значение в стеке на строку. (Это изменение вводит путаницу в lua_next при применении lua_tolstring к ключам во время обхода таблицы.)
lua_tolstring возвращает полностью выровненный указатель на строку внутри состояния Lua. Эта строка всегда имеет ноль ('\0') после последнего символа (как в C), но может содержать другие нули в своём теле. Поскольку Lua имеет сборку мусора, нет гарантии, что указатель, возвращаемый lua_tolstring, будет действителен после удаления соответствующего значения со стека.
lua_tonumber[-0, +0, -]
lua_Number lua_tonumber (lua_State *L, int index);
Преобразует Lua-значение по указанному допустимому индексу в C-тип lua_Number (см. lua_Number). Lua-значение должно быть числом или строкой, преобразуемой в число (см. §2.2.1); в противном случае, lua_tonumber возвращает 0.
lua_topointer[-0, +0, -]
const void *lua_topointer (lua_State *L, int index);
Преобразует значение по указанному допустимому индексу в универсальный C-указатель (void*). Значение может быть пользовательским данными, таблицей, потоком или функцией; в противном случае lua_topointer возвращает NULL. Разные объекты дадут разные указатели. Нет способа преобразовать указатель обратно в исходное значение.
Как правило, эта функция используется только для отладочной информации.
lua_tostring[-0, +0, m]
const char *lua_tostring (lua_State *L, int index);
Эквивалентно lua_tolstring с len равным NULL.
lua_tothread[-0, +0, -]
lua_State *lua_tothread (lua_State *L, int index);
Преобразует значение по указанному допустимому индексу в Lua-поток (представленный как lua_State*). Это значение должно быть потоком; в противном случае функция возвращает NULL.
lua_touserdata[-0, +0, -]
void *lua_touserdata (lua_State *L, int index);
Если значение по указанному допустимому индексу является полными пользовательскими данными, возвращает адрес его блока. Если значение является лёгкими пользовательскими данными, возвращает его указатель. В противном случае, возвращает NULL.
lua_type[-0, +0, -]
int lua_type (lua_State *L, int index);
Возвращает тип значения по указанному допустимому индексу или LUA_TNONE для недопустимого индекса (то есть индекса "пустой" позиции в стеке). Типы, возвращаемые lua_type, закодированы следующими константами, определёнными в lua.h: LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, и LUA_TLIGHTUSERDATA.
lua_typename[-0, +0, -]
const char *lua_typename (lua_State *L, int tp);
Возвращает имя типа, закодированного значением tp, которое должно быть одним из значений, возвращаемых lua_type.
lua_Writer
typedef int (*lua_Writer) (lua_State *L,
const void* p,
size_t sz,
void* ud); Тип функции-запись, используемой lua_dump. Каждый раз, когда она производит ещё один кусок чанка, lua_dump вызывает функцию-запись, передавая буфер для записи (p), его размер (sz) и параметр data, переданный в lua_dump.
Функция-запись возвращает код ошибки: 0 означает отсутствие ошибок; любое другое значение означает ошибку и останавливает lua_dump от повторного вызова функции-записи.
lua_xmove[-?, +?, -]
void lua_xmove (lua_State *from, lua_State *to, int n);
Обмен значениями между различными потоками одного глобального состояния.
Эта функция извлекает n значений со стека from, и помещает их на стек to.
lua_yield[-?, +?, -]
int lua_yield (lua_State *L, int nresults);
Возобновление корутины.
Эта функция должна вызываться только как выражение возврата C-функции, следующим образом:
return lua_yield (L, nresults);
Когда C-функция вызывает lua_yield таким образом, выполняемая корутина приостанавливает свою работу, и вызов lua_resume, который запустил эту корутину, возвращает значения. Параметр nresults — количество значений со стека, передаваемых в качестве результатов в lua_resume.
3.8 – Интерфейс отладки
Lua не имеет встроенных средств отладки. Вместо этого он предлагает специальный интерфейс с помощью функций и хуков. Этот интерфейс позволяет создавать различные виды отладчиков, профайлеров и других инструментов, которым требуется «внутренняя информация» от интерпретатора.
lua_Debug
typedef struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) */
const char *what; /* (S) */
const char *source; /* (S) */
int currentline; /* (l) */
int nups; /* (u) number of upvalues */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
other fields
} lua_Debug; Структура, используемая для переноса различных фрагментов информации об активной функции. lua_getstack заполняет только закрытую часть этой структуры для последующего использования. Для заполнения других полей структуры lua_Debug полезной информацией, вызовите lua_getinfo.
Поля lua_Debug имеют следующее значение:
-
source: Если функция была определена в строке, тогдаsource— эта строка. Если функция была определена в файле, тогдаsourceначинается с '@' за которым следует имя файла. -
short_src: «печатьная» версияsource, для использования в сообщениях об ошибках. -
linedefined: номер строки, с которой начинается определение функции. -
lastlinedefined: номер строки, на которой заканчивается определение функции. -
what: строка"Lua", если функция является Lua-функцией,"C", если это C-функция,"main", если это основная часть чанка, и"tail", если это функция, которая выполнила хвостовой вызов. В последнем случае Lua не имеет другой информации о функции. -
currentline: текущая строка, в которой выполняется данная функция. Когда информация о строке недоступна,currentlineустанавливается в -1. -
name: разумное имя для данной функции. Поскольку функции в Lua являются значениями первого класса, они не имеют фиксированного имени: некоторые функции могут быть значением нескольких глобальных переменных, в то время как другие могут храниться только в поле таблицы. Функцияlua_getinfoпроверяет, как вызывалась функция, чтобы найти подходящее имя. Если она не может найти имя, тоnameустанавливается вNULL. -
namewhat: объясняет полеname. Значениеnamewhatможет быть"global","local","method","field","upvalue", или""(пустая строка), в зависимости от того, как была вызвана функция. (Lua использует пустую строку, когда не кажется, что подходит другой вариант.) -
nups: количество upvalues функции.
lua_gethook[-0, +0, -]
lua_Hook lua_gethook (lua_State *L);
Возвращает текущую функцию обработки.
lua_gethookcount[-0, +0, -]
int lua_gethookcount (lua_State *L);
Возвращает текущий счётчик обработки.
lua_gethookmask[-0, +0, -]
int lua_gethookmask (lua_State *L);
Возвращает текущую маску обработки.
lua_getinfo[-(0|1), +(0|1|2), m]
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
Возвращает информацию о конкретной функции или вызове функции.
Для получения информации о вызове функции, параметр ar должен быть допустимой записью активации, заполненной предыдущим вызовом lua_getstack или переданной в качестве аргумента обработчику (см. lua_Hook).
Чтобы получить информацию о функции, поместите её на стек и начните строку what с символа '>'. (В этом случае, lua_getinfo удаляет функцию с вершины стека.) Например, чтобы узнать, на какой строке была определена функция f, можно написать следующий код:
lua_Debug ar;
lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* get global 'f' */
lua_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined); Каждый символ в строке what выбирает некоторые поля структуры ar для заполнения или значение для помещения на стек:
- '
n': заполняет поляnameиnamewhat; - '
S': заполняет поляsource,short_src,linedefined,lastlinedefined, иwhat; - '
l': заполняет полеcurrentline; - '
u': заполняет полеnups; - '
f': помещает на стек функцию, выполняющуюся на заданном уровне; - '
L': помещает на стек таблицу, индексами которой являются номера строк, допустимые для функции. (Допустимая строка — это строка с ассоциированным кодом, то есть строка, в которой можно установить точку останова. Недопустимые строки включают пустые строки и комментарии.)
Эта функция возвращает 0 при ошибке (например, при недопустимом параметре в what).
lua_getlocal[-0, +(0|1), -]
const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);
Получает информацию о локальной переменной данной записи активации. Параметр ar должен быть допустимой записью активации, заполненной предыдущим вызовом lua_getstack или переданной в качестве аргумента обработчику (см. lua_Hook). Индекс n выбирает, какую локальную переменную исследовать (1 — первый параметр или активная локальная переменная и так далее, до последней активной локальной переменной). lua_getlocal помещает значение переменной на стек и возвращает её имя.
Имена переменных, начинающиеся с '(' (открывающая скобка), представляют внутренние переменные (переменные управления циклом, временные переменные и локальные переменные C-функций).
Возвращает NULL (и ничего не помещает на стек), когда индекс больше, чем количество активных локальных переменных.
lua_getstack[-0, +0, -]
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
Получает информацию о стеке выполнения интерпретатора.
Эта функция заполняет части структуры lua_Debug идентификацией записи активации функции, выполняющейся на данном уровне. Уровень 0 — текущая выполняемая функция, а уровень n+1 — функция, которая вызвала уровень n. При отсутствии ошибок lua_getstack возвращает 1; при вызове с уровнем, превышающим глубину стека, возвращает 0.
lua_getupvalue[-0, +(0|1), -]
const char *lua_getupvalue (lua_State *L, int funcindex, int n);
Получает информацию об upvalue замыкания. (Для Lua-функций upvalue — это внешние локальные переменные, которые использует функция и, следовательно, включены в её замыкание.) lua_getupvalue получает индекс n upvalue, помещает значение upvalue на стек и возвращает его имя. funcindex указывает на замыкание на стеке. (Upvalue не имеют определённого порядка, так как они активны на протяжении всей функции. Поэтому они пронумерованы в произвольном порядке.)
Возвращает NULL (и ничего не помещает на стек), когда индекс больше, чем количество upvalue. Для C-функций эта функция использует пустую строку "" в качестве имени для всех upvalue.
lua_Hook
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
Тип функций обработки отладки.
Всякий раз, когда вызывается обработчик, его аргумент ar имеет поле event, установленное на конкретное событие, которое вызвало обработчик. Lua идентифицирует эти события с помощью следующих констант: LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKTAILRET, LUA_HOOKLINE и LUA_HOOKCOUNT. Кроме того, для событий строк поле currentline также устанавливается. Чтобы получить значение любого другого поля в ar, обработчик должен вызвать lua_getinfo. Для событий возврата event может быть LUA_HOOKRET, нормальным значением, или LUA_HOOKTAILRET. В последнем случае Lua моделирует возврат из функции, которая выполнила tail call; в этом случае вызов lua_getinfo бесполезен.
Пока Lua выполняет обработчик, он отключает другие вызовы обработчиков. Поэтому, если обработчик вызывает Lua для выполнения функции или куска кода, это выполнение происходит без вызовов обработчиков.
lua_sethook[-0, +0, -]
int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
Устанавливает функцию обработки отладки.
Аргумент f — это функция обработки. mask указывает, на какие события будет реагировать обработчик: он образуется путём побитового или констант LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE и LUA_MASKCOUNT. Аргумент count имеет смысл только тогда, когда маска включает LUA_MASKCOUNT. Для каждого события обработчик вызывается, как описано ниже:
- Обработчик вызова: вызывается, когда интерпретатор вызывает функцию. Обработчик вызывается сразу после того, как Lua входит в новую функцию, перед тем, как функция получает свои аргументы.
- Обработчик возврата: вызывается, когда интерпретатор возвращается из функции. Обработчик вызывается непосредственно перед тем, как Lua покидает функцию. У вас нет доступа к значениям, которые функция должна вернуть.
- Обработчик строки: вызывается, когда интерпретатор собирается начать выполнение новой строки кода или когда он возвращается в код (даже в ту же строку). (Это событие происходит только при выполнении Lua-функции.)
-
Обработчик счётчика: вызывается после того, как интерпретатор выполнит каждые
countинструкций. (Это событие происходит только при выполнении Lua-функции.)
Обработчик отключается, установив mask в ноль.
lua_setlocal[-(0|1), +0, -]
const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);
Устанавливает значение локальной переменной данной записи активации. Параметры ar и n такие же, как в lua_getlocal (см. lua_getlocal). lua_setlocal присваивает значение, находящееся на вершине стека, переменной и возвращает её имя. Также удаляет значение из стека.
Возвращает NULL (и не удаляет ничего со стека), когда индекс больше, чем количество активных локальных переменных.
lua_setupvalue[-(0|1), +0, -]
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
Устанавливает значение upvalue замыкания. Присваивает значение с вершины стека upvalue и возвращает её имя. Также удаляет значение со стека. Параметры funcindex и n такие же, как в lua_getupvalue (см. lua_getupvalue).
Возвращает NULL (и не удаляет ничего со стека), когда индекс больше, чем количество upvalue.
4 – Вспомогательная библиотека
Вспомогательная библиотека предоставляет несколько удобных функций для взаимодействия C с Lua. В то время как базовый API предоставляет базовые функции для всех взаимодействий между C и Lua, вспомогательная библиотека предоставляет функции более высокого уровня для некоторых распространённых задач.
Все функции вспомогательной библиотеки определены в заголовочном файле lauxlib.h и имеют префикс luaL_.
Все функции вспомогательной библиотеки построены на базе базового API и, следовательно, не предоставляют ничего, чего нельзя сделать с помощью этого API.
Несколько функций вспомогательной библиотеки используются для проверки аргументов C-функций. Их имена всегда luaL_check* или luaL_opt*. Все эти функции генерируют ошибку, если проверка не пройдена. Поскольку сообщение об ошибке отформатировано для аргументов (например, "bad argument #1"), не следует использовать эти функции для других значений стека.
4.1 – Функции и типы
Здесь мы перечисляем все функции и типы вспомогательной библиотеки в алфавитном порядке.
luaL_addchar[-0, +0, m]
void luaL_addchar (luaL_Buffer *B, char c);
Добавляет символ c в буфер B (см. luaL_Buffer).
luaL_addlstring[-0, +0, m]
void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
Добавляет строку, указанную по адресу s длиной l в буфер B (см. luaL_Buffer). Строка может содержать вложенные нули.
luaL_addsize[-0, +0, m]
void luaL_addsize (luaL_Buffer *B, size_t n);
Добавляет в буфер B (см. luaL_Buffer) строку длиной n , ранее скопированную в область буфера (см. luaL_prepbuffer).
luaL_addstring[-0, +0, m]
void luaL_addstring (luaL_Buffer *B, const char *s);
Добавляет завершающую нулём строку, указанную по адресу s в буфер B (см. luaL_Buffer). Строка не может содержать вложенные нули.
luaL_addvalue[-1, +0, m]
void luaL_addvalue (luaL_Buffer *B);
Добавляет значение с вершины стека в буфер B (см. luaL_Buffer). Удаляет значение.
Это единственная функция для строковых буферов, которая может (и должна) вызываться с дополнительным элементом на стеке, который является значением, подлежащим добавлению в буфер.
luaL_argcheck[-0, +0, v]
void luaL_argcheck (lua_State *L,
int cond,
int narg,
const char *extramsg); Проверяет, является ли cond истинным. Если нет, генерирует ошибку с сообщением следующего вида, где func извлекается из стека вызовов:
bad argument #<narg> to <func> (<extramsg>)
luaL_argerror[-0, +0, v]
int luaL_argerror (lua_State *L, int narg, const char *extramsg);
Генерирует ошибку с сообщением следующего вида, где func извлекается из стека вызовов:
bad argument #<narg> to <func> (<extramsg>)
Эта функция никогда не возвращает значение, но её используют в функциях C в качестве return luaL_argerror(args).
luaL_Buffer
typedef struct luaL_Buffer luaL_Buffer;
Тип для буфера строк.
Буфер строк позволяет коду C собирать строки Lua по частям. Шаблон использования:
- Сначала вы объявляете переменную
bтипаluaL_Buffer. - Затем вы инициализируете её вызовом
luaL_buffinit(L, &b). - Затем вы добавляете фрагменты строк в буфер, вызывая любые из функций
luaL_add*. - Вы завершаете, вызывая
luaL_pushresult(&b). Этот вызов помещает конечную строку в начало стека.
Во время обычной работы буфер строк использует переменное количество слотов стека. Поэтому, работая с буфером, нельзя предполагать, что вы знаете, где находится верх стека. Вы можете использовать стек между последовательными вызовами операций с буфером, если это использование сбалансировано; то есть, когда вы вызываете операцию с буфером, стек находится на том же уровне, что и сразу после предыдущей операции с буфером. (Единственное исключение из этого правила — luaL_addvalue.) После вызова luaL_pushresult стек возвращается к своему уровню, когда буфер был инициализирован, плюс конечная строка вверху.
luaL_buffinit[-0, +0, -]
void luaL_buffinit (lua_State *L, luaL_Buffer *B);
Инициализирует буфер B. Эта функция не выделяет никакого места; буфер должен быть объявлен как переменная (см. luaL_Buffer).
luaL_callmeta[-0, +(0|1), e]
int luaL_callmeta (lua_State *L, int obj, const char *e);
Вызывает метаметод.
Если объект в индексе obj имеет метатаблицу, и эта метатаблица имеет поле e, эта функция вызывает это поле и передает объект в качестве единственного аргумента. В этом случае функция возвращает 1 и помещает на стек значение, возвращённое вызовом. Если метатаблицы нет или метаметода нет, эта функция возвращает 0 (без помещения какого-либо значения в стек).
luaL_checkany[-0, +0, v]
void luaL_checkany (lua_State *L, int narg);
Проверяет, содержит ли функция аргумент любого типа (включая nil) в позиции narg.
luaL_checkint[-0, +0, v]
int luaL_checkint (lua_State *L, int narg);
Проверяет, является ли аргумент функции narg числом, и возвращает это число, преобразованное в int.
luaL_checkinteger[-0, +0, v]
lua_Integer luaL_checkinteger (lua_State *L, int narg);
Проверяет, является ли аргумент функции narg числом и возвращает это число, преобразованное в lua_Integer.
luaL_checklong[-0, +0, v]
long luaL_checklong (lua_State *L, int narg);
Проверяет, является ли аргумент функции narg числом и возвращает это число, преобразованное в long.
luaL_checklstring[-0, +0, v]
const char *luaL_checklstring (lua_State *L, int narg, size_t *l);
Проверяет, является ли аргумент функции narg строкой, и возвращает эту строку; если l не NULL, заполняет *l длиной строки.
Эта функция использует lua_tolstring для получения результата, поэтому все преобразования и замечания этой функции применимы и здесь.
luaL_checknumber[-0, +0, v]
lua_Number luaL_checknumber (lua_State *L, int narg);
Проверяет, является ли аргумент функции narg числом и возвращает это число.
luaL_checkoption[-0, +0, v]
int luaL_checkoption (lua_State *L,
int narg,
const char *def,
const char *const lst[]); Проверяет, является ли аргумент функции narg строкой и ищет эту строку в массиве lst (который должен быть завершён нулём). Возвращает индекс в массиве, где была найдена строка. Генерирует ошибку, если аргумент не является строкой или строка не найдена.
Если def не NULL, функция использует def в качестве значения по умолчанию, если нет аргумента narg или он равен nil.
Эта функция полезна для сопоставления строк с перечислениями C. (Обычная практика в библиотеках Lua — использовать строки вместо чисел для выбора опций.)
luaL_checkstack[-0, +0, v]
void luaL_checkstack (lua_State *L, int sz, const char *msg);
Увеличивает размер стека до top + sz элементов, генерируя ошибку, если стек не может быть увеличен до такого размера. msg — дополнительный текст для сообщения об ошибке.
luaL_checkstring[-0, +0, v]
const char *luaL_checkstring (lua_State *L, int narg);
Проверяет, является ли аргумент функции narg строкой и возвращает эту строку.
Эта функция использует lua_tolstring для получения результата, поэтому все преобразования и замечания этой функции применимы и здесь.
luaL_checktype[-0, +0, v]
void luaL_checktype (lua_State *L, int narg, int t);
Проверяет, имеет ли аргумент функции narg тип t. См. lua_type для кодирования типов для t.
luaL_checkudata[-0, +0, v]
void *luaL_checkudata (lua_State *L, int narg, const char *tname);
Проверяет, является ли аргумент функции narg пользовательским данными типа tname (см. luaL_newmetatable).
luaL_dofile[-0, +?, m]
int luaL_dofile (lua_State *L, const char *filename);
Загружает и выполняет указанный файл. Он определяется как макрос:
(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
Возвращает 0, если ошибок нет, или 1 в случае ошибок.
luaL_dostring[-0, +?, m]
int luaL_dostring (lua_State *L, const char *str);
Загружает и выполняет указанную строку. Он определяется как макрос:
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
Возвращает 0, если ошибок нет, или 1 в случае ошибок.
luaL_error[-0, +0, v]
int luaL_error (lua_State *L, const char *fmt, ...);
Генерирует ошибку. Формат сообщения об ошибке задаётся fmt, плюс любые дополнительные аргументы, следуя тем же правилам, что и lua_pushfstring. Он также добавляет в начало сообщения имя файла и номер строки, где произошла ошибка, если эта информация доступна.
Эта функция никогда не возвращает значение, но её используют в функциях C в качестве return luaL_error(args).
luaL_getmetafield[-0, +(0|1), m]
int luaL_getmetafield (lua_State *L, int obj, const char *e);
Помещает в стек поле e из метатаблицы объекта в индексе obj. Если у объекта нет метатаблицы или в метатаблице нет этого поля, возвращает 0 и ничего не помещает.
luaL_getmetatable[-0, +1, -]
void luaL_getmetatable (lua_State *L, const char *tname);
Помещает в стек метатаблицу, связанную с именем tname в реестре (см. luaL_newmetatable).
luaL_gsub[-0, +1, m]
const char *luaL_gsub (lua_State *L,
const char *s,
const char *p,
const char *r); Создаёт копию строки s путём замены всех вхождений строки p строкой r. Помещает получившуюся строку в стек и возвращает её.
luaL_loadbuffer[-0, +1, m]
int luaL_loadbuffer (lua_State *L,
const char *buff,
size_t sz,
const char *name); Загружает буфер как блок Lua. Эта функция использует lua_load для загрузки блока в буфере, указанном buff, с размером sz.
Эта функция возвращает те же результаты, что и lua_load. name — имя блока, используемое для отладки и сообщений об ошибках.
luaL_loadfile[-0, +1, m]
int luaL_loadfile (lua_State *L, const char *filename);
Загружает файл как блок Lua. Эта функция использует lua_load для загрузки блока из файла с именем filename. Если filename — NULL, тогда она загружает из стандартного ввода. Первая строка в файле игнорируется, если она начинается с #.
Эта функция возвращает те же результаты, что и lua_load, но имеет дополнительный код ошибки LUA_ERRFILE, если не удаётся открыть/прочитать файл.
Как и lua_load, эта функция только загружает блок; она его не выполняет.
luaL_loadstring[-0, +1, m]
int luaL_loadstring (lua_State *L, const char *s);
Загружает строку как блок Lua. Эта функция использует lua_load для загрузки блока в строке с нулевым завершением s.
Эта функция возвращает те же результаты, что и lua_load.
Также, как и lua_load, эта функция только загружает блок; она его не выполняет.
luaL_newmetatable[-0, +1, m]
int luaL_newmetatable (lua_State *L, const char *tname);
Если в реестре уже есть ключ tname, возвращает 0. В противном случае создаёт новую таблицу, которая будет использоваться как метатаблица для пользовательских данных, добавляет её в реестр с ключом tname, и возвращает 1.
В обоих случаях помещает в стек конечное значение, связанное с tname в реестре.
luaL_newstate[-0, +0, -]
lua_State *luaL_newstate (void);
Создаёт новый состояние Lua. Она вызывает lua_newstate с выделением памяти, основанным на стандартной C-функции realloc, и затем устанавливает функцию обработки ошибок (см. lua_atpanic), которая выводит сообщение об ошибке в стандартный поток ошибок в случае критических ошибок.
Возвращает новое состояние или NULL, если произошла ошибка выделения памяти.
luaL_openlibs[-0, +0, m]
void luaL_openlibs (lua_State *L);
Открывает все стандартные библиотеки Lua в данном состоянии.
luaL_optint[-0, +0, v]
int luaL_optint (lua_State *L, int narg, int d);
Если аргумент функции narg — число, возвращает это число, преобразованное в int. Если аргумент отсутствует или равен nil, возвращает d. В противном случае генерирует ошибку.
luaL_optinteger[-0, +0, v]
lua_Integer luaL_optinteger (lua_State *L,
int narg,
lua_Integer d); Если аргумент функции narg — число, возвращает это число, преобразованное в lua_Integer. Если аргумент отсутствует или равен nil, возвращает d. В противном случае генерирует ошибку.
luaL_optlong[-0, +0, v]
long luaL_optlong (lua_State *L, int narg, long d);
Если аргумент функции narg — число, возвращает это число, преобразованное в long. Если аргумент отсутствует или равен nil, возвращает d. В противном случае генерирует ошибку.
luaL_optlstring[-0, +0, v]
const char *luaL_optlstring (lua_State *L,
int narg,
const char *d,
size_t *l); Если аргумент функции narg — строка, возвращает эту строку. Если аргумент отсутствует или равен nil, возвращает d. В противном случае генерирует ошибку.
Если l не равно NULL, заполняет позицию *l длиной результата.
luaL_optnumber[-0, +0, v]
lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);
Если аргумент функции narg — число, возвращает это число. Если аргумент отсутствует или равен nil, возвращает d. В противном случае генерирует ошибку.
luaL_optstring[-0, +0, v]
const char *luaL_optstring (lua_State *L,
int narg,
const char *d); Если аргумент функции narg — строка, возвращает эту строку. Если аргумент отсутствует или равен nil, возвращает d. В противном случае генерирует ошибку.
luaL_prepbuffer[-0, +0, -]
char *luaL_prepbuffer (luaL_Buffer *B);
Возвращает адрес области памяти размером LUAL_BUFFERSIZE, куда можно скопировать строку, которую нужно добавить в буфер B (см. luaL_Buffer). После копирования строки в эту область необходимо вызвать luaL_addsize с размером строки, чтобы фактически добавить её в буфер.
luaL_pushresult[-?, +1, m]
void luaL_pushresult (luaL_Buffer *B);
Завершает использование буфера B, помещая итоговую строку на вершину стека.
luaL_ref[-1, +0, m]
int luaL_ref (lua_State *L, int t);
Создаёт и возвращает ссылку в таблице по индексу t, для объекта на вершине стека (и удаляет объект).
Ссылка — это уникальный целочисленный ключ. Пока вы не добавляете целочисленные ключи в таблицу t, luaL_ref гарантирует уникальность возвращаемого ключа. Вы можете получить объект, на который ссылается ссылка r, вызвав lua_rawgeti(L, t, r). Функция luaL_unref освобождает ссылку и связанный с ней объект.
Если объект на вершине стека равен nil, luaL_ref возвращает константу LUA_REFNIL. Константа LUA_NOREF гарантированно отличается от любой ссылки, возвращённой luaL_ref.
luaL_Reg
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg; Тип для массивов функций, регистрируемых с помощью luaL_register. name — имя функции, а func — указатель на функцию. Любой массив luaL_Reg должен заканчиваться стоп-записью, в которой как name, так и func равны NULL.
luaL_register[-(0|1), +1, m]
void luaL_register (lua_State *L,
const char *libname,
const luaL_Reg *l); Открывает библиотеку.
При вызове с libname равным NULL, просто регистрирует все функции в списке l (см. luaL_Reg) в таблицу на вершине стека.
При вызове с ненулевым libname, luaL_register создаёт новую таблицу t, устанавливает её как значение глобальной переменной libname, устанавливает её как значение package.loaded[libname], и регистрирует в ней все функции из списка l. Если в package.loaded[libname] или в переменной libname уже есть таблица, используется эта таблица вместо создания новой.
В любом случае функция оставляет таблицу на вершине стека.
luaL_typename[-0, +0, -]
const char *luaL_typename (lua_State *L, int index);
Возвращает имя типа значения по заданному индексу.
luaL_typerror[-0, +0, v]
int luaL_typerror (lua_State *L, int narg, const char *tname);
Генерирует ошибку с сообщением следующего вида:
location: bad argument narg to 'func' (tname expected, got rt)
где location получено с помощью luaL_where, func — имя текущей функции, а rt — имя типа фактического аргумента.
luaL_unref[-0, +0, -]
void luaL_unref (lua_State *L, int t, int ref);
Освобождает ссылку ref из таблицы по индексу t (см. luaL_ref). Запись удаляется из таблицы, так что ссылаемый объект может быть собран сборщиком мусора. Ссылка ref также освобождается, чтобы её можно было использовать снова.
Если ref равно LUA_NOREF или LUA_REFNIL, luaL_unref ничего не делает.
luaL_where[-0, +1, m]
void luaL_where (lua_State *L, int lvl);
Помещает на стек строку, идентифицирующую текущую позицию управления на уровне lvl в стеке вызовов. Обычно эта строка имеет следующий формат:
chunkname:currentline:
Уровень 0 — текущая выполняемая функция, уровень 1 — функция, которая вызвала текущую, и т. д.
Эта функция используется для построения префикса сообщений об ошибках.
5 – Стандартные Библиотеки
Стандартные библиотеки Lua предоставляют полезные функции, реализованные непосредственно через C API. Некоторые из этих функций предоставляют необходимые сервисы языку (например, type и getmetatable); другие предоставляют доступ к «внешним» сервисам (например, Ввод/Вывод); а другие могли бы быть реализованы на Lua, но являются достаточно полезными или имеют критические требования к производительности, которые заслуживают реализации на C (например, table.sort).
Все библиотеки реализуются через официальный C API и предоставляются как отдельные C модули. В настоящее время Lua имеет следующие стандартные библиотеки:
- базовая библиотека, которая включает подбиблиотеку сопроцедур;
- библиотека пакетов;
- обработка строк;
- обработка таблиц;
- математические функции (sin, log и т. д.);
- ввод и вывод;
- обслуживание операционной системы;
- средства отладки.
За исключением базовой и библиотеки пакетов, каждая библиотека предоставляет все свои функции как поля глобальной таблицы или как методы своих объектов.
Чтобы получить доступ к этим библиотекам, программа-хост C должна вызвать функцию luaL_openlibs, которая откроет все стандартные библиотеки. В качестве альтернативы, она может открыть их по отдельности, вызвав luaopen_base (для базовой библиотеки), luaopen_package (для библиотеки пакетов), luaopen_string (для библиотеки строк), luaopen_table (для библиотеки таблиц), luaopen_math (для математической библиотеки), luaopen_io (для библиотеки Ввод/Вывод), luaopen_os (для библиотеки операционной системы) и luaopen_debug (для отладочной библиотеки). Эти функции объявлены в lualib.h и не должны вызываться напрямую: вы должны вызывать их как любую другую Lua C функцию, например, с помощью lua_call.
5.1 – Базовые Функции
Базовая библиотека предоставляет некоторые основные функции для Lua. Если вы не включаете эту библиотеку в своё приложение, вам следует внимательно проверить, нужно ли вам предоставлять реализации некоторых её функций.
assert (v [, message])
Вызывает ошибку, когда значение её аргумента v ложно (т.е., nil или false); в противном случае возвращает все свои аргументы. message — сообщение об ошибке; при отсутствии оно по умолчанию равно "assertion failed!"
collectgarbage ([opt [, arg]])
Эта функция — это обобщённый интерфейс к сборщику мусора. Она выполняет различные функции в зависимости от своего первого аргумента, opt:
- "collect": выполняет полный цикл сборки мусора. Это опция по умолчанию.
- "stop": останавливает сборщик мусора.
- "restart": перезапускает сборщик мусора.
- "count": возвращает общее количество используемой памяти Lua (в Кбайтах).
-
"step": выполняет шаг сборки мусора. Размер шага контролируется значением
arg(большие значения означают больше шагов) непредсказуемым образом. Если вы хотите контролировать размер шага, вам необходимо экспериментально подобрать значениеarg. Возвращает true, если шаг завершил цикл сборки. -
"setpause": устанавливает
argкак новое значение для pause сборщика (см. §2.10). Возвращает предыдущее значение для pause. -
"setstepmul": устанавливает
argкак новое значение для step multiplier сборщика (см. §2.10). Возвращает предыдущее значение для step.
dofile ([filename])
Открывает указанный файл и выполняет его содержимое как Lua фрагмент. При вызове без аргументов, dofile выполняет содержимое стандартного ввода (stdin). Возвращает все значения, возвращённые фрагментом. В случае ошибок, dofile распространяет ошибку своему вызывающему объекту (то есть, dofile не выполняется в защищённом режиме).
error (message [, level])
Прерывает последнюю защищённую функцию, которая была вызвана, и возвращает message в качестве сообщения об ошибке. Функция error никогда не возвращается. Обычно, error добавляет некоторую информацию о позиции ошибки в начале сообщения. Аргумент level определяет, как получить позицию ошибки. При уровне 1 (по умолчанию) позиция ошибки находится в месте вызова функции error. Уровень 2 указывает на ошибку в месте вызова функции, которая вызвала error; и так далее. Передача уровня 0 предотвращает добавление информации о позиции ошибки в сообщение.
_G
Переменная глобального уровня (не функция), которая хранит глобальную среду (то есть, _G._G = _G). Сам Lua не использует эту переменную; изменение её значения не влияет на любую среду, и наоборот. (Используйте setfenv для изменения сред.)
getfenv ([f])
Возвращает текущую среду, используемую функцией. f может быть функцией Lua или числом, которое указывает функцию на данном уровне стека: Уровень 1 — это функция, вызывающая getfenv. Если заданная функция не является функцией Lua или если f равно 0, getfenv возвращает глобальную среду. По умолчанию для f является значение 1.
getmetatable (object)
Если у object нет метатаблицы, возвращает nil. В противном случае, если метатаблица объекта имеет поле "__metatable", возвращает связанное значение. В противном случае возвращает метатаблицу данного объекта.
ipairs (t)
Возвращает три значения: функцию-итератор, таблицу t, и 0, так что конструкция
for i,v in ipairs(t) do body end
будет итерироваться по парам (1,t[1]), (2,t[2]), ···, до первой целочисленной ключа, отсутствующей в таблице.
load (func [, chunkname])
Загружает фрагмент, используя функцию func для получения его частей. Каждый вызов func должен вернуть строку, которая конкатенируется с предыдущими результатами. Возврат пустой строки, nil или отсутствие значения сигнализирует об окончании фрагмента.
Если ошибок нет, возвращает скомпилированный фрагмент как функцию; в противном случае возвращает nil и сообщение об ошибке. Среда возвращённой функции — это глобальная среда.
chunkname используется в качестве имени фрагмента для сообщений об ошибках и отладочной информации. Если отсутствует, по умолчанию используется "=(load)".
loadfile ([filename])
Аналогично load, но получает фрагмент из файла filename или со стандартного ввода, если имя файла не указано.
loadstring (string [, chunkname])
Аналогично load, но получает фрагмент из указанной строки.
Для загрузки и выполнения заданной строки используйте идиому
assert(loadstring(s))()
Если отсутствует, chunkname по умолчанию задаётся указанной строкой.
next (table [, index])
Позволяет программе пройти по всем полям таблицы. Её первым аргументом является таблица, а вторым — индекс в этой таблице. next возвращает следующий индекс таблицы и его соответствующее значение. При вызове с nil в качестве второго аргумента, next возвращает начальный индекс и его соответствующее значение. При вызове с последним индексом или с nil в пустой таблице, next возвращает nil. Если второй аргумент отсутствует, он интерпретируется как nil. В частности, вы можете использовать next(t) для проверки, пуста ли таблица.
Порядок перечисления индексов не определён, даже для числовых индексов. (Для обхода таблицы в числовом порядке используйте цикл for или функцию ipairs.)
Поведение next является неопределённым, если во время обхода вы присваиваете любое значение несуществующему полю в таблице. Однако вы можете изменять существующие поля. В частности, вы можете очищать существующие поля.
pairs (t)
Возвращает три значения: функцию next, таблицу t, и nil, так что конструкция
for k,v in pairs(t) do body end
будет итерироваться по всем парам ключ–значение таблицы t.
См. функцию next для замечаний о модификации таблицы во время итерации.
pcall (f, arg1, ···)
Вызывает функцию f с заданными аргументами в защищённом режиме. Это означает, что любая ошибка внутри f не распространяется; вместо этого pcall перехватывает ошибку и возвращает код состояния. Первый результат — это код состояния (булево значение), которое равно true, если вызов выполняется без ошибок. В таком случае pcall также возвращает все результаты вызова, после этого первого результата. В случае любой ошибки pcall возвращает false плюс сообщение об ошибке.
print (···)
Принимает любое количество аргументов и выводит их значения в stdout, используя функцию tostring для преобразования их в строки. print предназначен не для форматированного вывода, а только как быстрый способ показать значение, обычно для отладки. Для форматированного вывода используйте string.format.
rawequal (v1, v2)
Проверяет, равны ли v1 и v2, не вызывая никаких метаметодов. Возвращает булево значение.
rawget (table, index)
Получает реальное значение table[index], не вызывая никаких метаметодов. table должна быть таблицей; index может быть любым значением.
rawset (table, index, value)
Устанавливает реальное значение table[index] на value, не вызывая никаких метаметодов. table должна быть таблицей, index — любым значением, отличным от nil, и value — любым значением Lua. Эта функция возвращает table.
select (index, ···)
Если index является числом, возвращает все аргументы после аргумента с номером index. В противном случае, index должен быть строкой "#", и select возвращает общее количество дополнительных аргументов, полученных им.
setfenv (f, table)
Устанавливает среду, которая будет использоваться данной функцией. f может быть функцией Lua или числом, которое указывает функцию на данном уровне стека: Уровень 1 — это функция, вызывающая setfenv. setfenv возвращает заданную функцию.
В качестве специального случая, когда f равно 0, setfenv изменяет среду работающей нити. В этом случае setfenv не возвращает значений.
setmetatable (table, metatable)
Устанавливает метатаблицу для данной таблицы. (Вы не можете изменить метатаблицу других типов из Lua, только из C.) Если metatable равно nil, удаляет метатаблицу данной таблицы. Если у исходной метатаблицы есть поле "__metatable", вызывается ошибка.
Эта функция возвращает table.
tonumber (e [, base])
Пытается преобразовать свой аргумент в число. Если аргумент уже является числом или строкой, преобразуемой в число, то tonumber возвращает это число; в противном случае возвращает nil. Необязательный аргумент определяет базу для интерпретации числа. Основание может быть любым целым числом от 2 до 36 включительно. В основаниях выше 10 буква 'A' (в верхнем или нижнем регистре) представляет 10, 'B' представляет 11, и так далее, при этом 'Z' представляет 35. В основании 10 (по умолчанию) число может иметь десятичную часть, а также необязательную экспоненциальную часть (см. §2.1). В других основаниях принимаются только целые неотрицательные числа.
tostring (e)
Принимает аргумент любого типа и преобразует его в строку в подходящем формате. Для полного контроля над тем, как преобразуются числа, используйте string.format. Если у метатаблицы e есть поле "__tostring", то tostring вызывает соответствующее значение с e в качестве аргумента и использует результат вызова как свой результат.
type (v)
Возвращает тип своего единственного аргумента, закодированный как строка. Возможные результаты этой функции — "nil" (строка, а не значение nil), "number", "string", "boolean", "table", "function", "thread", и "userdata".
unpack (list [, i [, j]])
Возвращает элементы из заданной таблицы. Эта функция эквивалентна return list[i], list[i+1], ···, list[j]
за исключением того, что вышеприведённый код может быть записан только для фиксированного числа элементов. По умолчанию i равно 1, а j — длине списка, как определено оператором длины (см. §2.5.5).
_VERSION
Глобальная переменная (не функция), хранящая строку с текущей версией интерпретатора. Текущее содержимое этой переменной — "Lua 5.1".
xpcall (f, err)
Эта функция аналогична pcall, за исключением того, что вы можете установить новый обработчик ошибок.
xpcall вызывает функцию f в защищённом режиме, используя err в качестве обработчика ошибок. Любая ошибка внутри f не распространяется; вместо этого xpcall перехватывает ошибку, вызывает функцию err с оригинальным объектом ошибки и возвращает код состояния. Первый результат — это код состояния (булево значение), равное true, если вызов выполняется без ошибок. В этом случае xpcall также возвращает все результаты вызова, после этого первого результата. В случае любой ошибки xpcall возвращает false плюс результат от err.
5.2 – Управление сопрограммами
Операции, связанные с сопрограммами, представляют собой подбиблиотеку основной библиотеки и находятся внутри таблицы coroutine. См. §2.11 для общего описания сопрограмм.
coroutine.create (f)
Создаёт новую сопрограмму с телом f. f должна быть функцией Lua. Возвращает эту новую сопрограмму, объект типа "thread".
coroutine.resume (co [, val1, ···])
Запускает или продолжает выполнение сопрограммы co. В первый раз, когда вы возобновляете сопрограмму, она начинает выполнение своего тела. Значения val1, ··· передаются в качестве аргументов функции тела. Если сопрограмма передала управление, resume перезапускает её; значения val1, ··· передаются в качестве результатов от передачи управления.
Если сопрограмма выполняется без ошибок, resume возвращает true плюс любые значения, переданные yield (если сопрограмма передала управление), или любые значения, возвращённые функцией тела (если сопрограмма завершилась). Если есть ошибка, resume возвращает false плюс сообщение об ошибке.
coroutine.running ()
Возвращает запущенную корутину, или nil, когда вызывается из основного потока.
coroutine.status (co)
Возвращает состояние корутины co, как строку: "running", если корутина запущена (то есть, она вызвала status); "suspended", если корутина приостановлена в вызове yield, или если она ещё не начала выполняться; "normal" если корутина активна, но не выполняется (то есть, она возобновила другую корутину); и "dead" если корутина завершила свою функцию тела, или если она остановилась с ошибкой.
coroutine.wrap (f)
Создаёт новую корутину с телом f. f должна быть функцией Lua. Возвращает функцию, которая возобновляет корутину каждый раз, когда она вызывается. Любые аргументы, передаваемые функции, ведут себя как дополнительные аргументы для resume. Возвращает те же значения, что и resume, за исключением первого булевого значения. В случае ошибки, распространяет ошибку.
coroutine.yield (···)
Приостанавливает выполнение вызывающей корутины. Корутина не может выполнять функцию C, метаметод или итератор. Любые аргументы для yield передаются как дополнительные результаты для resume.
5.3 – Модули
Библиотека пакетов предоставляет базовые средства для загрузки и построения модулей в Lua. Она экспортирует две свои функции напрямую в глобальную среду: require и module. Всё остальное экспортируется в таблицу package.
module (name [, ···])
Создаёт модуль. Если в package.loaded[name] есть таблица, эта таблица является модулем. В противном случае, если существует глобальная таблица t с данным именем, эта таблица является модулем. В противном случае создаёт новую таблицу t и устанавливает её в качестве значения глобальной name и значения package.loaded[name]. Эта функция также инициализирует t._NAME заданным именем, t._M с модулем (t сам по себе), и t._PACKAGE с именем пакета (полное имя модуля минус последняя составляющая; см. ниже). Наконец, module устанавливает t в качестве новой среды текущей функции и нового значения package.loaded[name], так что require возвращает t.
Если name является составным именем (то есть, с компонентами, разделенными точками), module создаёт (или повторно использует, если они уже существуют) таблицы для каждого компонента. Например, если name это a.b.c, то module хранит таблицу модуля в поле c поля b глобальной a.
Эта функция может принимать необязательные опции после имени модуля, где каждая опция — это функция, которая будет применена к модулю.
require (modname)
Загружает данный модуль. Функция начинает с просмотра таблицы package.loaded для определения, загружен ли уже модуль modname. Если он загружен, то require возвращает значение, хранящееся в package.loaded[modname]. В противном случае, она пытается найти загрузчик для модуля.
Для поиска загрузчика require руководствуется массивом package.loaders. Изменяя этот массив, мы можем изменить способ поиска модуля require. Следующее объяснение основано на значения по умолчанию для package.loaders.
Сначала require проверяет package.preload[modname]. Если оно имеет значение, это значение (которое должно быть функцией) — загрузчик. В противном случае require ищет загрузчик Lua с использованием пути, хранящегося в package.path. Если это также не удаётся, он ищет загрузчик C с использованием пути, хранящегося в package.cpath. Если это также не удаётся, он пробует общей загрузчик (см. package.loaders).
После того, как загрузчик найден, require вызывает загрузчик с одним аргументом, modname. Если загрузчик возвращает какое-либо значение, require присваивает возвращаемое значение package.loaded[modname]. Если загрузчик не возвращает значение и не присвоил значение package.loaded[modname], то require присваивает true этому элементу. В любом случае, require возвращает конечное значение package.loaded[modname].
Если при загрузке или выполнении модуля возникнет ошибка, или если не будет найден загрузчик для модуля, то require генерирует ошибку.
package.cpath
Путь, используемый require для поиска загрузчика C.
Lua инициализирует путь C package.cpath так же, как и путь Lua package.path, используя переменную среды LUA_CPATH или путь по умолчанию, определённый в luaconf.h.
package.loaded
Таблица, используемая require для управления уже загруженными модулями. Когда вы загружаете модуль modname и package.loaded[modname] не ложно, require просто возвращает значение, хранящееся там.
package.loaders
Таблица, используемая require для управления загрузкой модулей.
Каждый элемент этой таблицы — это функция поиска. При поиске модуля require вызывает каждый из этих поисковиков в восходящем порядке, с именем модуля (аргумент, переданный require) в качестве единственного параметра. Функция может вернуть другую функцию (загрузчик модуля) или строку, объясняющую, почему она не нашла этот модуль (или nil, если ей нечего сказать). Lua инициализирует эту таблицу четырьмя функциями.
Первый поиск просто ищет загрузчик в таблице package.preload.
Второй поиск ищет загрузчик как Lua-библиотеку, используя путь, хранящийся в package.path. Путь — это последовательность шаблонов, разделенных точкой с запятой. Для каждого шаблона поиск заменит каждый знак вопроса в шаблоне на filename, которое является именем модуля с каждой точкой, заменённой разделителем каталогов (например, "/" в Unix); затем он попытается открыть полученное имя файла. Например, если путь Lua — строка
"./?.lua;./?.lc;/usr/local/?/init.lua"
поиск файла Lua для модуля foo попытается открыть файлы ./foo.lua, ./foo.lc, и /usr/local/foo/init.lua, в этом порядке.
Третий поиск ищет загрузчик как C-библиотеку, используя путь, заданный переменной package.cpath. Например, если путь C — строка
"./?.so;./?.dll;/usr/local/?/init.so"
поиск загрузчика для модуля foo попытается открыть файлы ./foo.so, ./foo.dll, и /usr/local/foo/init.so, в этом порядке. Найдя C-библиотеку, этот поиск сначала использует средство динамической компоновки для связывания приложения с библиотекой. Затем он пытается найти функцию C внутри библиотеки, которая будет использоваться в качестве загрузчика. Имя этой функции C — строка "luaopen_", соединённая с копией имени модуля, где каждая точка заменяется подчёркиванием. Кроме того, если в имени модуля есть дефис, его префикс до (включительно) первого дефиса удаляется. Например, если имя модуля — a.v1-b.c, имя функции будет luaopen_b_c.
Четвёртый поиск пробует общей загрузчик. Он ищет в пути C библиотеку для имени корневого модуля. Например, при загрузке a.b.c, он будет искать C-библиотеку для a. Если найдена, он ищет в ней открытую функцию для подмодуля; в нашем примере, это будет luaopen_a_b_c. С этой возможностью пакет может объединить несколько C-подмодулей в одну библиотеку, при этом каждый подмодуль сохраняет свою оригинальную открытую функцию.
package.loadlib (libname, funcname)
Динамически связывает программу-хост с C-библиотекой libname. Внутри этой библиотеки ищет функцию funcname и возвращает эту функцию как функцию C. (Таким образом, funcname должен следовать протоколу (см. lua_CFunction)).
Это функция низкого уровня. Она полностью обходит систему пакетов и модулей. В отличие от require, она не выполняет поиск по пути и не добавляет расширения автоматически. libname должно быть полным именем C-библиотеки, включая, при необходимости, путь и расширение. funcname должно быть точным именем, экспортированным C-библиотекой (что может зависеть от используемого C-компилятора и компоновщика).
Эта функция не поддерживается ANSI C. Таким образом, она доступна только на некоторых платформах (Windows, Linux, Mac OS X, Solaris, BSD, плюс другие Unix-системы, поддерживающие стандарт dlfcn).
package.path
Путь, используемый require для поиска загрузчика Lua.
При запуске Lua инициализирует эту переменную значением переменной среды LUA_PATH или путём по умолчанию, определённым в luaconf.h, если переменная среды не определена. Любой ";;" в значении переменной среды заменяется на путь по умолчанию.
package.preload
Таблица для хранения загрузчиков для определенных модулей (см. require).
package.seeall (module)
Устанавливает метатаблицу для module с полем __index, ссылающимся на глобальную среду, так что этот модуль наследует значения из глобальной среды. Используется в качестве опции для функции module.
5.4 – Обработка строк
Эта библиотека предоставляет универсальные функции для обработки строк, такие как поиск и извлечение подстрок и сопоставление с образцами. При индексировании строки в Lua, первый символ находится в позиции 1 (а не в 0, как в C). Индексы могут быть отрицательными и интерпретируются как обратный индексирование, с конца строки. Таким образом, последний символ находится в позиции -1 и так далее.
Библиотека строк предоставляет все свои функции внутри таблицы string. Она также устанавливает метатаблицу для строк, где поле __index указывает на таблицу string. Таким образом, вы можете использовать функции строк в объектно-ориентированном стиле. Например, string.byte(s, i) может быть записано как s:byte(i).
Библиотека строк предполагает кодировки символов с одним байтом.
string.byte (s [, i [, j]])
Возвращает внутренние числовые коды символов s[i], s[i+1], ···, s[j]. Значение по умолчанию для i — 1; значение по умолчанию для j — i. Обратите внимание, что числовые коды не обязательно являются переносимыми между платформами.
string.char (···)
Принимает ноль или более целых чисел. Возвращает строку длиной, равной количеству аргументов, в которой каждый символ имеет внутренний числовой код, равный соответствующему аргументу. Обратите внимание, что числовые коды не обязательно являются переносимыми между платформами.
string.dump (function)
Возвращает строку, содержащую двоичное представление данной функции, так что последующее применение loadstring к этой строке возвращает копию функции. function должна быть функцией Lua без upvalues.
string.find (s, pattern [, init [, plain]])
Ищет первое вхождение pattern в строке s. Если совпадение найдено, то find возвращает индексы s, где это вхождение начинается и заканчивается; в противном случае возвращает nil. Третий, необязательный числовой аргумент init определяет, где начинать поиск; его значение по умолчанию — 1, и оно может быть отрицательным. Значение true в качестве четвёртого, необязательного аргумента plain отключает средства сопоставления с образцом, поэтому функция выполняет простое поиск подстроки без учёта "магических" символов в pattern. Обратите внимание, что если plain указан, то init также должен быть указан. Если шаблон содержит группы захвата, то при успешном совпадении захваченные значения также возвращаются после двух индексов.
string.format (formatstring, ···)
Возвращает отформатированную версию своих аргументов в соответствии с описанием, заданным в первом аргументе (который должен быть строкой). Строка формата следует тем же правилам, что и функция printf семейства стандартных C-функций. Единственные различия заключаются в том, что опции/модификаторы *, l, L, n, p, и h не поддерживаются, и есть дополнительная опция q. Опция q форматирует строку в виде, пригодном для безопасного повторного чтения интерпретатором Lua: строка записывается между двойными кавычками, а все двойные кавычки, символы новой строки, вставленные нули и обратные косые черты в строке правильно экранируются при записи. Например, вызов string.format('%q', 'a string with "quotes" and \n new line')
произведёт строку:
"a string with \"quotes\" and \ new line"
Опции c, d, E, e, f, g, G, i, o, u, X, и x все ожидают числовой аргумент, тогда как q и s ожидают строку.
Эта функция не принимает строковые значения, содержащие вставленные нули, за исключением аргументов к опции q.
string.gmatch (s, pattern)
Возвращает функцию-итератор, которая каждый раз при вызове возвращает следующие захваченные группы из pattern по строке s. Если pattern не указывает захватов, то всё совпадение генерируется в каждом вызове. Например, следующий цикл
s = "hello world from Lua" for w in string.gmatch(s, "%a+") do print(w) end
будет итерировать по всем словам из строки s, выводив по одному на строку. Следующий пример собирает все пары key=value из данной строки в таблицу:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end Для этой функции символ '^' в начале шаблона не работает как якорь, так как это помешало бы итерации.
string.gsub (s, pattern, repl [, n])
Возвращает копию s, в которой все (или первые n, если указано) вхождения pattern были заменены строкой-заменой, указанной repl, которая может быть строкой, таблицей или функцией. gsub также возвращает в качестве второго значения общее количество произошедших совпадений. Если repl является строкой, то её значение используется для замены. Символ % работает как символ экранирования: любая последовательность в repl вида %n, где n от 1 до 9, обозначает значение n-й захваченной подстроки (см. ниже). Последовательность %0 обозначает всё совпадение. Последовательность %% обозначает отдельный символ %.
Если repl является таблицей, то таблица запрашивается для каждого совпадения, используя первую захваченную подстроку в качестве ключа; если шаблон не указывает захватов, то всё совпадение используется в качестве ключа.
Если repl является функцией, то эта функция вызывается каждый раз при совпадении, со всеми захваченными подстроками, передаваемыми в качестве аргументов в порядке их следования; если шаблон не указывает захватов, то всё совпадение передаётся в качестве единственного аргумента.
Если значение, возвращаемое запросом к таблице или вызовом функции, является строкой или числом, то оно используется в качестве строки замены; в противном случае, если это false или nil, то замены не происходит (то есть, исходное совпадение сохраняется в строке).
Вот несколько примеров:
x = string.gsub("hello world", "(%w+)", "%1 %1")
--> x="hello hello world world"
x = string.gsub("hello world", "%w+", "%0 %0", 1)
--> x="hello hello world"
x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
--> x="world hello Lua from"
x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
--> x="home = /home/roberto, user = roberto"
x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
return loadstring(s)()
end)
--> x="4+5 = 9"
local t = {name="lua", version="5.1"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
--> x="lua-5.1.tar.gz"
string.len (s)
Принимает строку и возвращает её длину. Пустая строка "" имеет длину 0. Вставленные нули считаются, поэтому "a\000bc\000" имеет длину 5.
string.lower (s)
Принимает строку и возвращает копию этой строки, в которой все заглавные буквы заменены на строчные. Все остальные символы остаются неизменными. Определение того, что такое заглавная буква, зависит от текущего региональных настроек.
string.match (s, pattern [, init])
Ищет первое совпадение pattern в строке s. Если оно найдено, то match возвращает захваты из шаблона; в противном случае возвращает nil. Если pattern не указывает захватов, то возвращается всё совпадение. Третий, необязательный числовой аргумент init определяет, где начинать поиск; его значение по умолчанию — 1, и оно может быть отрицательным.
string.rep (s, n)
Возвращает строку, которая является конкатенацией n копий строки s.
string.reverse (s)
Возвращает строку, которая является перевёрнутой строкой s.
string.sub (s, i [, j])
Возвращает подстроку s, которая начинается с i и продолжается до j; i и j могут быть отрицательными. Если j отсутствует, предполагается, что он равен -1 (что эквивалентно длине строки). В частности, вызов string.sub(s,1,j) возвращает префикс s длиной j, а string.sub(s, -i) возвращает суффикс s длиной i.
string.upper (s)
Принимает строку и возвращает копию этой строки, в которой все строчные буквы заменены на заглавные. Все остальные символы остаются неизменными. Определение того, что такое строчная буква, зависит от текущих региональных настроек. 5.4.1 – Шаблоны
Класс символов:
Класс символов используется для представления набора символов. В описании класса символов разрешены следующие комбинации:
-
x: (где x не является одним из магических символов
^$()%.[]*+-?) представляет собой сам символ x. -
.: (точка) представляет все символы. -
%a: представляет все буквы. -
%c: представляет все управляющие символы. -
%d: представляет все цифры. -
%l: представляет все строчные буквы. -
%p: представляет все знаки препинания. -
%s: представляет все пробельные символы. -
%u: представляет все заглавные буквы. -
%w: представляет все буквенно-цифровые символы. -
%x: представляет все шестнадцатеричные цифры. -
%z: представляет символ с представлением 0. -
%x: (где x — любой небуквенно-цифровой символ) представляет символ x. Это стандартный способ экранирования магических символов. Любой знак препинания (даже не магический) может предваряться '%' при использовании для представления себя в шаблоне. -
[set]: представляет класс, который является объединением всех символов в множестве. Диапазон символов может быть задан, разделив конечные символы диапазона символом '-'. Все классы%x, описанные выше, также могут быть использованы как компоненты в множестве. Все остальные символы в множестве представляют сами себя. Например,[%w_](или[_%w]) представляет все буквенно-цифровые символы плюс символ нижнего подчеркивания,[0-7]представляет восьмеричные цифры, а[0-7%l%-]представляет восьмеричные цифры плюс строчные буквы плюс символ '-'.Взаимодействие между диапазонами и классами не определено. Следовательно, шаблоны, такие как
[%a-z]или[a-%%]не имеют смысла. -
[^set]: представляет дополнение к множеству, где множество интерпретируется как описано выше.
Для всех классов, представленных одиночными буквами (%a, %c, и т. д.), соответствующая заглавная буква представляет дополнение к классу. Например, %S представляет все символы, не являющиеся пробельными.
Определения букв, пробельных и других групп символов зависят от текущих региональных настроек. В частности, класс [a-z] может не быть эквивалентен %l.
Элемент шаблона:
Элемент шаблона может быть
- класс символов из одного символа, который соответствует любому одиночному символу в классе;
- класс символов из одного символа, за которым следует '
*', который соответствует 0 или более повторениям символов в классе. Эти элементы повторения всегда будут соответствовать самой длинной возможной последовательности; - класс символов из одного символа, за которым следует '
+', который соответствует 1 или более повторениям символов в классе. Эти элементы повторения всегда будут соответствовать самой длинной возможной последовательности; - класс символов из одного символа, за которым следует '
-', который также соответствует 0 или более повторениям символов в классе. В отличие от '*', эти элементы повторения всегда будут соответствовать наименьшей возможной последовательности; - класс символов из одного символа, за которым следует '
?', который соответствует 0 или 1 вхождению символа в классе; -
%n, для n от 1 до 9; такой элемент соответствует подстроке, равной n-й захваченной строке (см. ниже); -
%bxy, где x и y — два различных символа; такой элемент соответствует строкам, начинающимся с x, заканчивающимся на y, и где x и y сбалансированы. Это означает, что, если читать строку слева направо, считая +1 для x и -1 для y, заключительное y — это первое y, где счёт достигает 0. Например, элемент%b()соответствует выражениям со сбалансированными скобками.
Шаблон:
Шаблон — это последовательность элементов шаблона. '^' в начале шаблона привязывает соответствие к началу строки-предмета. '$' в конце шаблона привязывает соответствие к концу строки-предмета. В других позициях '^' и '$' не имеют специального значения и представляют собой сами себя.
Захваты:
Шаблон может содержать подшаблоны, заключённые в скобки; они описывают захваты. Когда соответствие успешно, подстроки строки-предмета, которые соответствуют захватам, сохраняются (захватываются) для последующего использования. Захваты нумеруются по левым скобкам. Например, в шаблоне "(a*(.)%w(%s*))", часть строки, соответствующая "a*(.)%w(%s*)", сохраняется как первый захват (и поэтому имеет номер 1); символ, соответствующий ".", захватывается с номером 2, а часть, соответствующая "%s*", имеет номер 3.
В качестве специального случая пустой захват () захватывает текущую позицию строки (число). Например, если мы применим шаблон "()aa()" к строке "flaaap", будет два захвата: 3 и 5.
Шаблон не может содержать вложенные нули. Используйте %z вместо этого.
5.5 – Обработка таблиц
Эта библиотека предоставляет универсальные функции для обработки таблиц. Все свои функции она предоставляет внутри таблицы table.
Большинство функций библиотеки таблиц предполагают, что таблица представляет собой массив или список. Для этих функций, когда мы говорим о «длине» таблицы, мы имеем в виду результат оператора длины.
table.concat (table [, sep [, i [, j]]])
Учитывая массив, где все элементы являются строками или числами, возвращает table[i]..sep..table[i+1] ··· sep..table[j]. Значение по умолчанию для sep — это пустая строка, значение по умолчанию для i — 1, а значение по умолчанию для j — длина таблицы. Если i больше j, возвращает пустую строку.
table.insert (table, [pos,] value)
Вставляет элемент value в позицию pos в table, сдвигаясь вверх другими элементами, если это необходимо. Значение по умолчанию для pos — n+1, где n — длина таблицы (см. §2.5.5), так что вызов table.insert(t,x) вставляет x в конец таблицы t.
table.maxn (table)
Возвращает наибольший положительный числовой индекс данной таблицы или ноль, если в таблице нет положительных числовых индексов. (Для выполнения своей работы эта функция выполняет линейный обход всей таблицы.)
table.remove (table [, pos])
Удаляет из table элемент в позиции pos, сдвигаясь вниз другими элементами, если это необходимо. Возвращает значение удалённого элемента. Значение по умолчанию для pos — n, где n — длина таблицы, так что вызов table.remove(t) удаляет последний элемент таблицы t.
table.sort (table [, comp])
Сортирует элементы таблицы в заданном порядке, на месте, от table[1] до table[n], где n — длина таблицы. Если comp задано, то оно должно быть функцией, которая принимает два элемента таблицы и возвращает true, когда первый меньше второго (так что not comp(a[i+1],a[i]) будет true после сортировки). Если comp не задано, используется стандартный оператор Lua < вместо него. Алгоритм сортировки не является устойчивым; то есть элементы, считающиеся равными по заданному порядку, могут изменить своё относительное положение в результате сортировки.
5.6 – Математические функции
Эта библиотека — интерфейс к стандартной C-библиотеке математических функций. Она предоставляет все свои функции внутри таблицы math.
math.abs (x)
Возвращает абсолютное значение x.
math.acos (x)
Возвращает арккосинус x (в радианах).
math.asin (x)
Возвращает арксинус x (в радианах).
math.atan (x)
Возвращает арктангенс x (в радианах).
math.atan2 (y, x)
Возвращает арктангенс y/x (в радианах), но использует знаки обоих параметров, чтобы найти квадрант результата. (Он также правильно обрабатывает случай, когда x равно нулю.)
math.ceil (x)
Возвращает наименьшее целое число, большее или равное x.
math.cos (x)
Возвращает косинус x (предполагается, что в радианах).
math.cosh (x)
Возвращает гиперболический косинус x.
math.deg (x)
Возвращает угол x (в радианах) в градусах.
math.exp (x)
Возвращает значение ex.
math.floor (x)
Возвращает наибольшее целое число, меньшее или равное x.
math.fmod (x, y)
Возвращает остаток от деления x на y, который округляет частное к нулю.
math.frexp (x)
Возвращает m и e такие, что x = m2e, e — целое число, и абсолютное значение m находится в диапазоне [0.5, 1) (или равно нулю, когда x равно нулю).
math.huge
Значение HUGE_VAL, большее или равное любому другому численному значению.
math.ldexp (m, e)
Возвращает m2e (e должно быть целым числом).
math.log (x)
Возвращает натуральный логарифм x.
math.log10 (x)
Возвращает логарифм по основанию 10 x.
math.max (x, ···)
Возвращает максимальное значение среди своих аргументов.
math.min (x, ···)
Возвращает минимальное значение среди своих аргументов.
math.modf (x)
Возвращает две числа: целую часть x и дробную часть x.
math.pi
Значение pi.
math.pow (x, y)
Возвращает xy. (Вы также можете использовать выражение x^y для вычисления этого значения.)
math.rad (x)
Возвращает угол x (в градусах) в радианах.
math.random ([m [, n]])
Эта функция является интерфейсом к простой псевдослучайной функции генерации rand предоставляемой ANSI C. (Невозможно дать гарантии её статистическим свойствам.)
При вызове без аргументов возвращает равномерное псевдослучайное вещественное число в диапазоне [0,1). При вызове с целым числом m, math.random возвращает равномерное псевдослучайное целое число в диапазоне [1, m]. При вызове с двумя целыми числами m и n, math.random возвращает равномерное псевдослучайное целое число в диапазоне [m, n].
math.randomseed (x)
Устанавливает x в качестве «семени» для генератора псевдослучайных чисел: одинаковые семена порождают одинаковые последовательности чисел.
math.sin (x)
Возвращает синус x (предполагается, что в радианах).
math.sinh (x)
Возвращает гиперболический синус x.
math.sqrt (x)
Возвращает квадратный корень из x. (Вы также можете использовать выражение x^0.5 для вычисления этого значения.)
math.tan (x)
Возвращает тангенс x (предполагается, что в радианах).
math.tanh (x)
Возвращает гиперболический тангенс x.
5.7 – Утилиты ввода-вывода
Библиотека ввода-вывода предоставляет два разных стиля для обработки файлов. Первый использует неявные дескрипторы файлов; то есть, есть операции для установки файла-ввода по умолчанию и файла-вывода по умолчанию, и все операции ввода-вывода выполняются над этими файлами по умолчанию. Второй стиль использует явные дескрипторы файлов.
При использовании неявных дескрипторов файлов все операции предоставляются таблицей io. При использовании явных дескрипторов файлов операция io.open возвращает дескриптор файла, а затем все операции предоставляются как методы дескриптора файла.
Таблица io также предоставляет три предопределённых дескриптора файлов со своими обычными значениями из C: io.stdin, io.stdout и io.stderr. Библиотека ввода-вывода никогда не закрывает эти файлы.
Если не указано иное, все функции ввода-вывода возвращают nil при ошибке (плюс сообщение об ошибке в качестве второго результата и системно-зависимый код ошибки в качестве третьего результата) и какое-то значение, отличное от nil, при успехе.
io.close ([file])
Эквивалентно file:close(). Без file, закрывает стандартный выходной файл.
io.flush ()
Эквивалентно file:flush над стандартным выходным файлом.
io.input ([file])
При вызове с именем файла, открывает указанный файл (в текстовом режиме) и устанавливает его дескриптор как стандартный входной файл. При вызове с дескриптором файла, просто устанавливает этот дескриптор как стандартный входной файл. Без параметров, возвращает текущий стандартный входной файл.
В случае ошибок, эта функция поднимает ошибку вместо возврата кода ошибки.
io.lines ([filename])
Открывает указанный файл в режиме чтения и возвращает функцию-итератор, которая при каждом вызове возвращает новую строку из файла. Таким образом, конструкция
for line in io.lines(filename) do body end
будет перебирать все строки файла. Когда функция-итератор обнаруживает конец файла, она возвращает nil (для завершения цикла) и автоматически закрывает файл.
Вызов io.lines() (без имени файла) эквивалентен io.input():lines(); то есть, он перебирает строки стандартного входного файла. В этом случае файл не закрывается при окончании цикла.
io.open (filename [, mode])
Эта функция открывает файл в режиме, заданном строкой mode. Возвращает новый дескриптор файла или, в случае ошибок, nil плюс сообщение об ошибке.
Строка mode может быть любой из следующих:
- "r": режим чтения (по умолчанию);
- "w": режим записи;
- "a": режим добавления;
- "r+": режим обновления, все предыдущие данные сохраняются;
- "w+": режим обновления, все предыдущие данные удаляются;
- "a+": режим добавления с обновлением, предыдущие данные сохраняются, запись разрешена только в конце файла.
Строка mode также может содержать 'b' в конце, что необходимо в некоторых системах для открытия файла в двоичном режиме. Эта строка точно соответствует тому, что используется в стандартной C функции fopen.
io.output ([file])
Аналогично io.input, но работает со стандартным выходным файлом.
io.popen (prog [, mode])
Запускает программу prog в отдельном процессе и возвращает дескриптор файла, который можно использовать для чтения данных из этой программы (если mode равно "r", по умолчанию) или для записи данных в эту программу (если mode равно "w").
Эта функция зависит от системы и не доступна на всех платформах.
io.read (···)
Эквивалентно io.input():read.
io.tmpfile ()
Возвращает дескриптор временного файла. Этот файл открывается в режиме обновления и автоматически удаляется при завершении программы.
io.type (obj)
Проверяет, является ли obj допустимым дескриптором файла. Возвращает строку "file" если obj — открытый дескриптор файла, "closed file" если obj — закрытый дескриптор файла или nil если obj не является дескриптором файла.
io.write (···)
Эквивалентно io.output():write.
file:close ()
Закрывает file. Обратите внимание, что файлы автоматически закрываются, когда их дескрипторы собираются сборщиком мусора, но это занимает непредсказуемое время.
file:flush ()
Сохраняет все записанные данные в file.
file:lines ()
Возвращает функцию-итератор, которая при каждом вызове возвращает новую строку из файла. Таким образом, конструкция
for line in file:lines() do body end
будет перебирать все строки файла. (В отличие от io.lines, эта функция не закрывает файл при окончании цикла.)
file:read (···)
Читает файл file, в соответствии с заданными форматами, которые определяют, что читать. Для каждого формата функция возвращает строку (или число) с прочитанными символами или nil, если не может прочитать данные с указанным форматом. Без форматов используется формат по умолчанию, который читает всю следующую строку (см. ниже).
Доступные форматы
- "*n": читает число; это единственный формат, возвращающий число вместо строки.
- "*a": читает весь файл, начиная с текущей позиции. При достижении конца файла возвращает пустую строку.
- "*l": читает следующую строку (пропуская символ конца строки), возвращает nil при достижении конца файла. Это формат по умолчанию.
- число: читает строку длиной не более указанного числа символов, возвращает nil при достижении конца файла. Если число равно нулю, ничего не читает и возвращает пустую строку, или nil при достижении конца файла.
file:seek ([whence] [, offset])
Устанавливает и получает позицию файла, измеряемую с начала файла, в позицию, заданную offset плюс базу, указанную строкой whence, следующим образом:
- "set": база — позиция 0 (начало файла);
- "cur": база — текущая позиция;
- "end": база — конец файла;
В случае успеха функция seek возвращает конечную позицию файла, измеренную в байтах с начала файла. Если функция завершается неудачно, она возвращает nil плюс строку, описывающую ошибку.
Значение по умолчанию для whence — "cur", а для offset — 0. Таким образом, вызов file:seek() возвращает текущую позицию файла без изменения; вызов file:seek("set") устанавливает позицию в начало файла (и возвращает 0); а вызов file:seek("end") устанавливает позицию в конец файла и возвращает его размер.
file:setvbuf (mode [, size])
Устанавливает режим буферизации для выходного файла. Доступны три режима:
- "no": без буферизации; результат любой операции вывода появляется немедленно.
-
"full": полная буферизация; операция вывода выполняется только при заполнении буфера (или при явном
flushфайла (см.io.flush)). - "line": строчная буферизация; вывод буферизуется до вывода новой строки или до получения любого ввода от специальных файлов (например, терминала).
Для последних двух случаев size указывает размер буфера в байтах. По умолчанию — соответствующий размер.
file:write (···)
Записывает значения каждого из своих аргументов в file. Аргументы должны быть строками или числами. Для записи других значений используйте tostring или string.format перед write.
5.8 – Функции операционной системы
Эта библиотека реализована через таблицу os.
os.clock ()
Возвращает приблизительное значение процессорного времени, затраченного программой в секундах.
os.date ([format [, time]])
Возвращает строку или таблицу, содержащую дату и время, отформатированные в соответствии с заданной строкой format.
Если аргумент time присутствует, это время для форматирования (см. функцию os.time для описания этого значения). В противном случае date форматирует текущее время.
Если format начинается с '!', дата форматируется в координированном универсальном времени. После этого необязательного символа, если format равна строке "*t", date возвращает таблицу со следующими полями: year (четыре цифры), month (1--12), day (1--31), hour (0--23), min (0--59), sec (0--61), wday (день недели, воскресенье — 1), yday (день в году) и isdst (флаг летнего времени, булево значение).
Если format не равна "*t", date возвращает дату как строку, отформатированную по тем же правилам, что и C функция strftime.
При вызове без аргументов date возвращает разумное представление даты и времени, которое зависит от системы и текущего региональных настроек (то есть os.date() эквивалентно os.date("%c")).
os.difftime (t2, t1)
Возвращает количество секунд от времени t1 до времени t2. В POSIX, Windows и некоторых других системах это значение равно точно t2-t1.
os.execute ([command])
Эта функция эквивалентна C функции system. Она передает command для выполнения оболочкой операционной системы. Возвращает код состояния, который зависит от системы. Если command отсутствует, возвращает ненулевое значение, если оболочка доступна, и нуль в противном случае.
os.exit ([code])
Вызывает C функцию exit, с необязательным code, для завершения программы-хоста. Значение по умолчанию для code — код успеха.
os.getenv (varname)
Возвращает значение переменной окружения процесса varname, или nil, если переменная не определена.
os.remove (filename)
Удаляет файл или директорию с указанным именем. Директории должны быть пустыми для удаления. Если функция завершается неудачно, возвращает nil плюс строку, описывающую ошибку.
os.rename (oldname, newname)
Переименовывает файл или директорию с именем oldname в newname. Если функция завершается неудачно, возвращает nil плюс строку, описывающую ошибку.
os.setlocale (locale [, category])
Устанавливает текущий регион программы. locale — строка, определяющая регион; category — необязательная строка, описывающая категорию для изменения: "all", "collate", "ctype", "monetary", "numeric", или "time"; категория по умолчанию — "all". Функция возвращает имя нового региона или nil, если запрос не может быть выполнен.
Если locale — пустая строка, текущий регион устанавливается на определённый реализацией системный регион. Если locale — строка "C", текущий регион устанавливается на стандартный C регион.
При вызове с nil в качестве первого аргумента, эта функция только возвращает имя текущего региона для заданной категории.
os.time ([table])
Возвращает текущее время при вызове без аргументов или время, представляющее дату и время, указанные в заданной таблице. Эта таблица должна содержать поля year, month, и day, а также может содержать поля hour, min, sec, и isdst (для описания этих полей см. функцию os.date).
Возвращаемое значение — число, смысл которого зависит от вашей системы. В POSIX, Windows и некоторых других системах это число представляет количество секунд, прошедших с момента некоторого начального времени («эпохи»). В других системах смысл не определён, и число, возвращаемое time, может быть использовано только в качестве аргумента для date и difftime.
os.tmpname ()
Возвращает строку с именем файла, которое можно использовать для временного файла. Файл необходимо явно открыть перед использованием и явно удалить, когда он больше не нужен.
В некоторых системах (POSIX) эта функция также создаёт файл с этим именем, чтобы избежать рисков безопасности. (Кто-то другой может создать файл с неправильными правами в промежуток времени между получением имени и созданием файла.) Вам всё равно нужно открыть файл для использования и удалить его (даже если вы его не используете).
Если возможно, вы можете предпочесть использовать io.tmpfile, который автоматически удаляет файл при завершении программы.
5.9 – Библиотека отладки
Эта библиотека предоставляет функциональность интерфейса отладки для программ Lua. Следует проявлять осторожность при использовании этой библиотеки. Функции, предоставляемые здесь, должны использоваться исключительно для отладки и подобных задач, таких как профилирование. Пожалуйста, воздержитесь от использования их как обычного инструмента программирования: они могут быть очень медленными. Более того, несколько из этих функций нарушают некоторые предположения о коде Lua (например, что переменные, локальные для функции, недоступны извне или что метатаблицы userdata не могут быть изменены кодом Lua) и поэтому могут нанести ущерб в противном случае безопасному коду.
Все функции этой библиотеки предоставлены внутри таблицы debug. Все функции, которые работают с потоком, имеют необязательный первый аргумент, который является потоком, над которым они работают. По умолчанию всегда используется текущий поток.
debug.debug ()
Входит в интерактивный режим с пользователем, выполняя каждую строку, вводимую пользователем. Используя простые команды и другие средства отладки, пользователь может просматривать глобальные и локальные переменные, изменять их значения, вычислять выражения и так далее. Строка, содержащая только слово cont, завершает эту функцию, так что вызывающая функция продолжает своё выполнение.
Обратите внимание, что команды для debug.debug не являются лексически вложенными в какую-либо функцию и поэтому не имеют прямого доступа к локальным переменным.
debug.getfenv (o)
Возвращает окружение объекта o.
debug.gethook ([thread])
Возвращает текущие настройки хука потока в виде трёх значений: текущую функцию хука, текущую маску хука и текущее число вызовов хука (как установлено функцией debug.sethook).
debug.getinfo ([thread,] function [, what])
Возвращает таблицу с информацией о функции. Вы можете указать функцию напрямую или число в качестве значения function, что означает функцию, выполняющуюся на уровне function стека вызовов заданного потока: уровень 0 — текущая функция (getinfo сама); уровень 1 — функция, которая вызвала getinfo; и так далее. Если function — число, большее, чем количество активных функций, то getinfo возвращает nil.
Возвращаемая таблица может содержать все поля, возвращаемые функцией lua_getinfo, причём строка what описывает, какие поля заполнить. По умолчанию для what — получить всю доступную информацию, кроме таблицы допустимых строк. При наличии опции 'f' добавляется поле с именем func со значением самой функции. При наличии опции 'L' добавляется поле с именем activelines с таблицей допустимых строк.
Например, выражение debug.getinfo(1,"n").name возвращает таблицу с именем текущей функции, если такое имя можно найти, а выражение debug.getinfo(print) возвращает таблицу со всей доступной информацией о функции print.
debug.getlocal ([thread,] level, local)
Эта функция возвращает имя и значение локальной переменной с индексом local функции на уровне level стека. (Первая переменная или локальная переменная имеет индекс 1 и так далее, до последней активной локальной переменной.) Функция возвращает nil, если локальной переменной с заданным индексом не существует, и генерирует ошибку при вызове с level вне допустимого диапазона. (Вы можете вызвать debug.getinfo, чтобы проверить, является ли уровень допустимым.)
Имена переменных, начинающиеся с '(' (открывающая скобка), представляют внутренние переменные (переменные управления циклом, временные переменные и локальные переменные функций C).
debug.getmetatable (object)
Возвращает метатаблицу заданного object или nil, если у него нет метатаблицы.
debug.getregistry ()
Возвращает таблицу реестра (см. §3.5).
debug.getupvalue (func, up)
Эта функция возвращает имя и значение вспомогательной переменной с индексом up функции func. Функция возвращает nil, если вспомогательной переменной с заданным индексом не существует.
debug.setfenv (object, table)
Устанавливает окружение заданного object в заданное table. Возвращает object.
debug.sethook ([thread,] hook, mask [, count])
Устанавливает заданную функцию в качестве хука. Строка mask и число count описывают, когда будет вызван хук. Строка маски может содержать следующие символы с указанным значением:
-
"c": хук вызывается каждый раз, когда Lua вызывает функцию; -
"r": хук вызывается каждый раз, когда Lua возвращается из функции; -
"l": хук вызывается каждый раз, когда Lua входит в новую строку кода.
При значении count отличном от нуля хук вызывается после каждых count инструкций.
При вызове без аргументов debug.sethook отключает хук.
Когда хук вызывается, его первый параметр — строка, описывающая событие, которое его вызвало: "call", "return" (или "tail return", при моделировании возврата из хвостового вызова), "line", и "count". Для событий строк хук также получает новый номер строки как второй параметр. Внутри хука вы можете вызвать getinfo с уровнем 2, чтобы получить больше информации о выполняемой функции (уровень 0 — функция getinfo, и уровень 1 — функция хука), если событие не "tail return". В этом случае Lua только моделирует возврат, и вызов getinfo вернёт неверные данные.
debug.setlocal ([thread,] level, local, value)
Эта функция присваивает значение value локальной переменной с индексом local функции на уровне level стека. Функция возвращает nil, если локальной переменной с заданным индексом не существует, и генерирует ошибку при вызове с level вне допустимого диапазона. (Вы можете вызвать getinfo для проверки, является ли уровень допустимым.) В противном случае она возвращает имя локальной переменной.
debug.setmetatable (object, table)
Устанавливает метатаблицу для данного object в заданное значение table (которое может быть nil).
debug.setupvalue (func, up, value)
Эта функция присваивает значение value вспомогательной переменной с индексом up функции func. Функция возвращает nil, если вспомогательной переменной с заданным индексом не существует. В противном случае она возвращает имя вспомогательной переменной.
debug.traceback ([thread,] [message [, level]])
Возвращает строку со стеком вызовов. Необязательная строка message добавляется в начало стека вызовов. Необязательное число level указывает, на каком уровне начать стек вызовов (по умолчанию 1, функция, вызвавшая traceback).
6 – Lua автономно
Хотя Lua был разработан как язык расширения, который должен быть встроен в программу на языке C, он часто используется и как автономный язык. Интерпретатор для Lua как автономного языка, называемый просто lua, предоставляется в стандартном дистрибутиве. Автономный интерпретатор включает все стандартные библиотеки, включая библиотеку отладки. Его использование:
lua [options] [script [args]]
Опции:
-
-e stat: выполняет строку stat; -
-l mod: "требует" mod; -
-i: входит в интерактивный режим после выполнения script; -
-v: выводит информацию о версии; -
--: останавливает обработку опций; -
-: выполняетstdinкак файл и останавливает обработку опций.
После обработки своих опций lua выполняет указанный script, передавая ему указанные args в качестве строковых аргументов. При вызове без аргументов lua ведёт себя как lua -v -i при стандартном вводе (stdin) — терминале и как lua - в противном случае.
Перед выполнением любого аргумента интерпретатор проверяет переменную среды LUA_INIT. Если её формат @filename, то lua выполняет файл. В противном случае lua выполняет саму строку.
Все опции обрабатываются по порядку, кроме -i. Например, вызов
$ lua -e'a=1' -e 'print(a)' script.lua
сначала установит a в 1, затем выведет значение a (которое является '1') и, наконец, выполнит файл script.lua без аргументов. (Здесь $ — приглашение оболочки. Ваше приглашение может отличаться.)
Перед началом выполнения скрипта lua собирает все аргументы командной строки в глобальную таблицу под названием arg. Имя скрипта хранится под индексом 0, первый аргумент после имени скрипта — под индексом 1 и так далее. Любые аргументы перед именем скрипта (то есть имя интерпретатора плюс опции) помещаются в отрицательные индексы. Например, в вызове
$ lua -la b.lua t1 t2
интерпретатор сначала выполняет файл a.lua, затем создаёт таблицу
arg = { [-2] = "lua", [-1] = "-la",
[0] = "b.lua",
[1] = "t1", [2] = "t2" }
и, наконец, выполняет файл b.lua. Скрипт вызывается с arg[1], arg[2], ··· в качестве аргументов; он также может получить доступ к этим аргументам с помощью выражения vararg '...'.
В интерактивном режиме, если вы вводите неполное выражение, интерпретатор ожидает его завершения, выведя другой пригласительный символ.
Если глобальная переменная _PROMPT содержит строку, то её значение используется в качестве пригласительного символа. Аналогично, если глобальная переменная _PROMPT2 содержит строку, её значение используется в качестве дополнительного пригласительного символа (выводимого при неполных выражениях). Поэтому оба пригласительных символа могут быть изменены непосредственно в командной строке или в любом Lua-программе, присваивая значение переменной _PROMPT. Посмотрите пример ниже:
$ lua -e"_PROMPT='myprompt> '" -i
(Внешняя пара кавычек предназначена для оболочки, внутренняя — для Lua.) Обратите внимание на использование -i для входа в интерактивный режим; в противном случае программа просто завершится после присваивания значения переменной _PROMPT.
Для использования Lua как интерпретатора скриптов в системах Unix, автономный интерпретатор пропускает первую строку блока, если она начинается с #. Таким образом, Lua-скрипты могут быть преобразованы в исполняемые программы, используя chmod +x и #! формы, как показано ниже:
#!/usr/local/bin/lua
(Конечно, расположение Lua-интерпретатора может отличаться на вашем компьютере. Если lua находится в вашей PATH, то
#!/usr/bin/env lua
является более переносимым решением.)
7 – Несовместимости с предыдущей версией
Здесь мы перечисляем несовместимости, которые могут возникнуть при переносе программы из Lua 5.0 в Lua 5.1. Вы можете избежать большинства несовместимостей, скомпилировав Lua с соответствующими опциями (см. файл luaconf.h). Однако все эти опции совместимости будут удалены в следующей версии Lua.
7.1 – Изменения в языке
- Система vararg изменилась с псевдоаргумента
argс таблицей дополнительных аргументов на выражение vararg. (См. опцию времени компиляцииLUA_COMPAT_VARARGвluaconf.h.) - Произошло небольшое изменение области действия неявных переменных в операторе for и операторе repeat.
- Синтаксис длинных строк/длинных комментариев (
[[string]]) не позволяет вложенность. Вы можете использовать новый синтаксис ([=[string]=]) в этих случаях. (См. опцию времени компиляцииLUA_COMPAT_LSTRвluaconf.h.)
7.2 – Изменения в библиотеках
- Функция
string.gfindбыла переименована вstring.gmatch. (См. опцию времени компиляцииLUA_COMPAT_GFINDвluaconf.h.) - Когда
string.gsubвызывается с функцией в качестве третьего аргумента, каждый раз, когда эта функция возвращает nil или false, строка замены становится всей найденной строкой, а не пустой строкой. - Функция
table.setnустарела. Функцияtable.getnсоответствует новому оператору длины (#); используйте оператор вместо функции. (См. опцию времени компиляцииLUA_COMPAT_GETNвluaconf.h.) - Функция
loadlibбыла переименована вpackage.loadlib. (См. опцию времени компиляцииLUA_COMPAT_LOADLIBвluaconf.h.) - Функция
math.modбыла переименована вmath.fmod. (См. опцию времени компиляцииLUA_COMPAT_MODвluaconf.h.) - Функции
table.foreachиtable.foreachiустарели. Вы можете использовать цикл for сpairsилиipairsвместо них. - Произошли существенные изменения в функции
requireиз-за новой системы модулей. Однако новое поведение в основном совместимо со старым, ноrequireполучает путь изpackage.path, а не изLUA_PATH. - Функция
collectgarbageимеет разные аргументы. Функцияgcinfoустарела; используйтеcollectgarbage("count")вместо неё.
7.3 – Изменения в API
- Функции
luaopen_*(для открытия библиотек) не могут быть вызваны напрямую, как обычная C-функция. Они должны вызываться через Lua, как Lua-функция. - Функция
lua_openбыла заменена наlua_newstate, чтобы пользователи могли установить функцию распределения памяти. Вы можете использоватьluaL_newstateиз стандартной библиотеки для создания состояния с стандартной функцией распределения (на основеrealloc). - Функции
luaL_getnиluaL_setn(из вспомогательной библиотеки) устарели. Используйтеlua_objlenвместоluaL_getnи ничего вместоluaL_setn. - Функция
luaL_openlibбыла заменена наluaL_register. - Функция
luaL_checkudataтеперь генерирует ошибку, если переданное значение не является userdata ожидаемого типа. (В Lua 5.0 она возвращалаNULL.)
8 – Полный синтаксис Lua
Вот полный синтаксис Lua в расширенном BNF. (Он не описывает приоритеты операторов.)
chunk ::= {stat [`;´]} [laststat [`;´]]
block ::= chunk
stat ::= varlist `=´ explist |
functioncall |
do block end |
while exp do block end |
repeat block until exp |
if exp then block {elseif exp then block} [else block] end |
for Name `=´ exp `,´ exp [`,´ exp] do block end |
for namelist in explist do block end |
function funcname funcbody |
local function Name funcbody |
local namelist [`=´ explist]
laststat ::= return [explist] | break
funcname ::= Name {`.´ Name} [`:´ Name]
varlist ::= var {`,´ var}
var ::= Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name
namelist ::= Name {`,´ Name}
explist ::= {exp `,´} exp
exp ::= nil | false | true | Number | String | `...´ | function |
prefixexp | tableconstructor | exp binop exp | unop exp
prefixexp ::= var | functioncall | `(´ exp `)´
functioncall ::= prefixexp args | prefixexp `:´ Name args
args ::= `(´ [explist] `)´ | tableconstructor | String
function ::= function funcbody
funcbody ::= `(´ [parlist] `)´ block end
parlist ::= namelist [`,´ `...´] | `...´
tableconstructor ::= `{´ [fieldlist] `}´
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
fieldsep ::= `,´ | `;´
binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ |
`<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ |
and | or
unop ::= `-´ | not | `#´
© 1994–2017 Lua.org, PUC-Rio.
Licensed under the MIT License.
https://www.lua.org/manual/5.1/manual.html