Язык программирования LUA
Lua — это бесплатное программное обеспечение, распространяемое в исходном коде. Его можно использовать для любых целей, включая коммерческие, совершенно бесплатно.
Все версии доступны для загрузки. Эта документация пишется для текущей версии — Lua 5.4, а текущий релиз — Lua 5.4.8.
Lua
Lua — это бесплатное программное обеспечение, распространяемое в исходном коде. Его можно использовать для любых целей, включая коммерческие, совершенно бесплатно.
Все версии доступны для загрузки. Текущая версия — Lua 5.4, а текущий релиз — Lua 5.4.8.
Инструменты
Основной репозиторий модулей Lua — это LuaRocks. Также смотрите Awesome Lua. Предварительно скомпилированные библиотеки и исполняемые файлы Lua доступны на LuaBinaries. Вики lua-users содержит множество пользовательских дополнений для Lua.
Сборка
Lua реализован на чистом ANSI C и компилируется без изменений на всех платформах, где есть компилятор ANSI C. Lua также компилируется без проблем как C++.
Lua очень легко собрать и установить. В пакете есть подробные инструкции, но вот простой пример терминальной сессии, которая загружает текущий релиз Lua и собирает его на распространенных платформах:
curl -L -R -O https://www.lua.org/ftp/lua-5.4.8.tar.gz
tar zxf lua-5.4.8.tar.gz
cd lua-5.4.8
make all test
Введение
Lua — это мощный, эффективный, легковесный и встраиваемый язык сценариев. Он поддерживает процедурное программирование, объектно-ориентированное программирование, функциональное программирование, программирование на основе данных и описание данных.
Lua сочетает в себе простую процедурную синтаксис с мощными конструкциями описания данных, основанными на ассоциативных массивах и расширяемой семантике. Lua является динамически типизированным языком, работает путем интерпретации байт-кода с помощью виртуальной машины на основе регистров и имеет автоматическое управление памятью с помощью генерационного сборщика мусора, что делает его идеальным для конфигурации, сценариев и быстрого прототипирования.
Lua реализован как библиотека, написанная на чистом C, общепринятом подмножестве стандартного C и C++. Распределение Lua включает в себя хост-программу под названием lua, которая использует библиотеку Lua для предоставления полного, автономного интерпретатора Lua, как для интерактивного, так и для пакетного использования. Lua предназначен как мощный, легковесный, встраиваемый язык сценариев для любой программы, которая в этом нуждается, а также как мощный, но легковесный и эффективный автономный язык.
Как язык расширения, Lua не имеет понятия “главной” программы: он работает встраиваемым в хост-клиент, называемым программой встраивания или просто хостом. (Часто этот хост — это автономная программа lua.) Хост-программа может вызывать функции для выполнения фрагмента кода Lua, может записывать и считывать переменные Lua, а также может регистрировать функции C, которые будут вызываться кодом Lua. С помощью функций C Lua может быть расширен для работы с широким спектром различных областей, создавая таким образом настраиваемые языки программирования, которые разделяют синтаксическую основу.
Lua является бесплатным программным обеспечением и предоставляется, как обычно, без каких-либо гарантий, как указано в его лицензии. Реализация, описанная в этом руководстве, доступна на официальном сайте Lua, www.lua.org.
Как и любой другой справочный мануал, этот документ в некоторых местах может быть сухим. Для обсуждения решений, стоящих за дизайном Lua, смотрите технические статьи, доступные на сайте Lua. Для подробного введения в программирование на Lua смотрите книгу Роберто, “Программирование на Lua”.
1 - 2. Базовые концепции языка LUA
Этот раздел описывает основные концепции языка.
2.1 – Значения и типы
Lua — это динамически типизированный язык. Это означает, что переменные не имеют типов; только значения имеют типы. В языке отсутствуют определения типов. Все значения имеют свой собственный тип.
Все значения в Lua являются значениями первого класса. Это означает, что все значения могут храниться в переменных, передаваться в качестве аргументов другим функциям и возвращаться в качестве результатов.
В Lua есть восемь основных типов: nil, boolean, number, string, function, userdata, thread и table.
- Тип
nil имеет одно единственное значение — nil, основное свойство которого заключается в том, что оно отличается от любого другого значения; оно часто представляет отсутствие полезного значения. - Тип
boolean имеет два значения: false и true. Оба nil и false делают условие ложным; их вместе называют ложными значениями. Любое другое значение делает условие истинным. Несмотря на свое название, false часто используется как альтернатива nil, с ключевым отличием в том, что false ведет себя как обычное значение в таблице, в то время как nil в таблице представляет отсутствующий ключ. - Тип
number представляет как целые числа, так и вещественные (числа с плавающей запятой), используя два подтипа: integer и float. Стандартный Lua использует 64-битные целые числа и числа с двойной точностью (64 бита), но вы также можете скомпилировать Lua так, чтобы он использовал 32-битные целые числа и/или числа с одинарной точностью (32 бита). Опция с 32 битами как для целых чисел, так и для чисел с плавающей запятой особенно привлекательна для малых машин и встроенных систем. (Смотрите макрос LUA_32BITS в файле luaconf.h.)
Если не указано иное, любое переполнение при манипуляциях с целыми значениями оборачивается, согласно обычным правилам арифметики с дополнительным кодом. (Другими словами, фактический результат — это уникальное представимое целое число, которое равно математическому результату по модулю 2n, где n — это количество битов целого типа.)
Lua имеет явные правила о том, когда используется каждый подтип, но также автоматически выполняет преобразования между ними по мере необходимости (см. §3.4.3). Поэтому программист может в основном игнорировать разницу между целыми числами и числами с плавающей запятой или полностью контролировать представление каждого числа.
- Тип
string представляет собой неизменяемые последовательности байтов. Lua является 8-битным чистым языком: строки могут содержать любое 8-битное значение, включая встроенные нули (’\0’). Lua также не зависит от кодировки; он не делает предположений о содержимом строки. Длина любой строки в Lua должна помещаться в целое число Lua.
Lua может вызывать (и манипулировать) функциями, написанными как на Lua, так и на C (см. §3.4.10). Обе они представлены типом function.
Тип userdata предоставляется для хранения произвольных данных C в переменных Lua. Значение userdata представляет собой блок необработанной памяти. Существует два вида userdata: полное userdata, которое является объектом с блоком памяти, управляемым Lua, и легкое userdata, которое просто представляет собой значение указателя C. У userdata нет предопределенных операций в Lua, кроме присваивания и теста идентичности. С помощью метатаблиц программист может определить операции для значений полного userdata (см. §2.4). Значения userdata не могут быть созданы или изменены в Lua, только через C API. Это гарантирует целостность данных, принадлежащих хост-программе и библиотекам C.
Тип thread представляет собой независимые потоки выполнения и используется для реализации корутин (см. §2.6). Потоки Lua не связаны с потоками операционной системы. Lua поддерживает корутины на всех системах, даже на тех, которые не поддерживают потоки нативно.
Тип table реализует ассоциативные массивы, то есть массивы, которые могут иметь в качестве индексов не только числа, но и любое значение Lua, кроме nil и NaN. (Not a Number — это специальное значение с плавающей запятой, используемое стандартом IEEE 754 для представления неопределенных числовых результатов, таких как 0/0.) Таблицы могут быть гетерогенными; то есть они могут содержать значения всех типов (кроме nil). Любой ключ, связанный со значением nil, не считается частью таблицы. Напротив, любой ключ, который не является частью таблицы, имеет связанное значение nil.
Таблицы являются единственным механизмом структурирования данных в Lua; их можно использовать для представления обычных массивов, списков, символических таблиц, множеств, записей, графов, деревьев и т. д. Для представления записей Lua использует имя поля в качестве индекса. Язык поддерживает это представление, предоставляя a.name как синтаксический сахар для a[“name”]. В Lua есть несколько удобных способов создания таблиц (см. §3.4.9).
Как и индексы, значения полей таблицы могут быть любого типа. В частности, поскольку функции являются значениями первого класса, поля таблицы могут содержать функции. Таким образом, таблицы также могут содержать методы (см. §3.4.11).
Индексирование таблиц следует определению сырого равенства (raw equality) в языке. Выражения a[i] и a[j] обозначают один и тот же элемент таблицы тогда и только тогда, когда i и j сыро равны (то есть равны без учёта метаметодов).
В частности:
- Числа с плавающей точкой, имеющие целочисленные значения, считаются равными соответствующим целым числам (например,
1.0 == 1). - Чтобы избежать неоднозначностей, любое число с плавающей точкой, используемое в качестве ключа и равное целому числу, преобразуется в это целое число.
Пример:
Если написать a[2.0] = true, то фактически в таблицу будет вставлен ключ 2 (целое число), а не 2.0.
Ключевые моменты:
- Сырое равенство (
raw equality) — сравнение без метаметодов. - Целые и дробные числа —
1.0 и 1 считаются одинаковыми ключами. - Автоматическое преобразование —
a[2.0] превращается в a[2].
Это важно учитывать при работе с таблицами, чтобы избежать неожиданного поведения.
Таблицы, функции, потоки и значения (полного) userdata являются объектами: переменные на самом деле не содержат эти значения, а только ссылки на них. Присваивание, передача параметров и возвращение функций всегда манипулируют ссылками на такие значения; эти операции не подразумевают никакого рода копирования.
Функция библиотеки type возвращает строку, описывающую тип данного значения (см. type).
2.2 – Окружения и глобальное окружение
Имена переменных, области их видимости, правила лексического скрытия (shadowing) и работа с окружениями _ENV в языке Lua.
Имя переменной ссылается на глобальную или локальную переменную в соответствии с объявлением, которое находится в контексте в данной точке кода. (Для целей данного обсуждения формальный параметр функции эквивалентен локальной переменной.)
Все чанки (блоки кода) начинаются с неявного объявления global *, которое объявляет все свободные имена как глобальные переменные; это вводное объявление становится недействительным (void) внутри области видимости любого другого объявления global, как показано в следующем примере:
X = 1 -- Ok, глобальная по умолчанию
do
global Y -- отменяет неявное начальное объявление
Y = 1 -- Ok, Y объявлена как глобальная
X = 1 -- ОШИБКА, X не объявлена
end
X = 2 -- Ok, снова глобальная по умолчанию
Таким образом, вне любого объявления global Lua работает по принципу “глобальные по умолчанию”. Внутри любого объявления global Lua работает без умолчания: все переменные должны быть объявлены.
Lua — это язык с лексической областью видимости. Область видимости объявления переменной начинается с первого оператора после объявления и длится до последнего не-пустого (non-void) оператора самого внутреннего блока, включающего это объявление. (Пустыми операторами считаются метки и пустые инструкции.)
Объявление скрывает (shadowing) любое другое объявление с тем же именем, находящееся в контексте в точке объявления. Внутри этой тени любое внешнее объявление для этого имени становится недействительным. Смотрите следующий пример:
global print, x
x = 10 -- глобальная переменная
do -- новый блок
local x = x -- новая 'x' со значением 10
print(x) --> 10
x = x+1
do -- еще один блок
local x = x+1 -- еще одна 'x'
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (глобальная)
Обратите внимание, что в объявлении вроде local x = x новая объявляемая x еще не находится в области видимости, поэтому x в правой части ссылается на внешнюю переменную.
Благодаря правилам лексической области видимости, локальные переменные могут свободно использоваться функциями, определенными внутри их области видимости. Локальная переменная, используемая внутренней функцией, называется upvalue (или внешней локальной переменной, или просто внешней переменной) внутри этой внутренней функции.
Обратите внимание, что каждое выполнение оператора 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.
Как будет более подробно обсуждаться в §3.2 и §3.3.3, любая ссылка на глобальную переменную var синтаксически транслируется в _ENV.var. Более того, каждый чанк компилируется в области видимости внешней локальной переменной с именем _ENV (см. §3.3.2), поэтому само имя _ENV никогда не является свободным именем в чанке.
Несмотря на существование этой внешней переменной _ENV и трансляцию свободных имен, _ENV является обычным именем. В частности, вы можете определять новые переменные и параметры с этим именем. (Однако не следует определять _ENV как глобальную переменную, иначе _ENV.var транслировалось бы в _ENV._ENV.var и так далее, в бесконечном цикле.) Каждая ссылка на имя глобальной переменной использует ту _ENV, которая видна в данной точке программы.
Любая таблица, используемая в качестве значения _ENV, называется окружением (environment).
Lua поддерживает выделенное окружение, называемое глобальным окружением (global environment). Это значение хранится по специальному индексу в реестре C (см. §4.3). В Lua глобальная переменная _G инициализируется этим же значением. (_G никогда не используется внутри самого Lua, поэтому изменение ее значения повлияет только на ваш собственный код.)
Когда Lua загружает чанк, значением по умолчанию для его переменной _ENV является глобальное окружение (см. функцию load). Следовательно, по умолчанию глобальные переменные в коде Lua ссылаются на записи в глобальном окружении и, таким образом, ведут себя как обычные глобальные переменные. Более того, все стандартные библиотеки загружены в глобальное окружение, и некоторые функции там работают именно с этим окружением. Вы можете использовать load (или loadfile) для загрузки чанка с другим окружением. (В языке C для этого необходимо загрузить чанк, а затем изменить значение его первого upvalue; см. lua_setupvalue.)
2.3 – Обработка ошибок
Несколько операций в Lua могут вызывать ошибку. Ошибка прерывает нормальный поток выполнения программы, который может продолжиться, поймав ошибку.
Lua-код может явно вызвать ошибку, вызвав функцию error. (Эта функция никогда не возвращает значение.)
Чтобы поймать ошибки в Lua, вы можете выполнить защищенный вызов, используя pcall (или xpcall). Функция pcall вызывает заданную функцию в защищенном режиме. Любая ошибка во время выполнения функции останавливает ее выполнение, и управление немедленно возвращается в pcall, который возвращает код состояния.
Поскольку Lua является встроенным языком расширения, код Lua начинает выполняться по вызову из C-кода в хост-программе. (Когда вы используете Lua в автономном режиме, приложение lua является хост-программой.) Обычно этот вызов защищен; поэтому, когда происходит незащищенная ошибка во время компиляции или выполнения блока Lua, управление возвращается в хост, который может предпринять соответствующие меры, такие как вывод сообщения об ошибке.
Каждый раз, когда возникает ошибка, объект ошибки передается с информацией об ошибке. Сам Lua генерирует только ошибки, объект ошибки которых является строкой, но программы могут генерировать ошибки с любым значением в качестве объекта ошибки. Обработка таких объектов ошибок зависит от программы Lua или ее хоста. По историческим причинам объект ошибки часто называется сообщением об ошибке, даже если он не обязательно должен быть строкой.
Когда вы используете xpcall (или lua_pcall в C), вы можете передать обработчик сообщений, который будет вызван в случае ошибок. Эта функция вызывается с оригинальным объектом ошибки и возвращает новый объект ошибки. Она вызывается до того, как ошибка развернет стек, чтобы собрать больше информации об ошибке, например, проверяя стек и создавая трассировку стека. Этот обработчик сообщений также защищен защищенным вызовом; поэтому ошибка внутри обработчика сообщений снова вызовет обработчик сообщений. Если этот цикл продолжается слишком долго, Lua прерывает его и возвращает соответствующее сообщение. Обработчик сообщений вызывается только для обычных ошибок времени выполнения. Он не вызывается для ошибок выделения памяти и для ошибок при выполнении финализаторов или других обработчиков сообщений.
Lua также предлагает систему предупреждений (см. warn). В отличие от ошибок, предупреждения никоим образом не мешают выполнению программы. Обычно они просто генерируют сообщение для пользователя, хотя это поведение можно адаптировать из C (см. lua_setwarnf).
2.4 – Метатаблицы и метаметоды
Каждое значение в Lua может иметь метатаблицу. Эта метатаблица — это обычная таблица Lua, которая определяет поведение оригинального значения при определенных событиях. Вы можете изменить несколько аспектов поведения значения, установив конкретные поля в его метатаблице. Например, когда нечисловое значение является операндом сложения, Lua проверяет наличие функции в поле __add метатаблицы значения. Если она находит такую функцию, Lua вызывает ее для выполнения сложения.
Ключом для каждого события в метатаблице является строка с именем события, предшествующая двумя подчеркиваниями; соответствующее значение называется метазначением. Для большинства событий метазначение должно быть функцией, которая затем называется метаметодом. В предыдущем примере ключом является строка “__add”, а метаметодом — функция, выполняющая сложение. Если не указано иное, метаметодом может быть любое вызываемое значение, которое является либо функцией, либо значением с метаметодом __call.
Вы можете запросить метатаблицу любого значения, используя функцию getmetatable. Lua запрашивает метаметоды в метатаблицах, используя сырой доступ (см. rawget).
Вы можете заменить метатаблицу таблиц, используя функцию setmetatable. Вы не можете изменить метатаблицу других типов из кода Lua, кроме как с помощью библиотеки debug (§6.10).
Таблицы и полное userdata имеют индивидуальные метатаблицы, хотя несколько таблиц и userdata могут делить свои метатаблицы. Значения всех других типов делят одну единственную метатаблицу на тип; то есть, существует одна единственная метатаблица для всех чисел, одна для всех строк и т. д. По умолчанию значение не имеет метатаблицы, но библиотека строк устанавливает метатаблицу для типа строк (см. §6.4).
Подробный список операций, контролируемых метатаблицами, приведен ниже. Каждое событие идентифицируется своим соответствующим ключом. По соглашению, все ключи метатаблиц, используемые Lua, состоят из двух подчеркиваний, за которыми следуют строчные латинские буквы.
__add: операция сложения (+). Если любой операнд для сложения не является числом, Lua попытается вызвать метаметод. Он начинает с проверки первого операнда (даже если это число); если этот операнд не определяет метаметод для __add, то Lua проверит второй операнд. Если Lua находит метаметод, он вызывает этот метаметод с двумя операндами в качестве аргументов, и результат вызова (приведенный к одному значению) является результатом операции. В противном случае, если метаметод не найден, Lua вызывает ошибку.
__sub: операция вычитания (-). Поведение аналогично операции сложения.
__mul: операция умножения (*). Поведение аналогично операции сложения.
__div: операция деления (/). Поведение аналогично операции сложения.
__mod: операция взятия остатка (%) . Поведение аналогично операции сложения.
__pow: операция возведения в степень (^). Поведение аналогично операции сложения.
__unm: операция отрицания (унарный -). Поведение аналогично операции сложения.
__idiv: операция целочисленного деления (//). Поведение аналогично операции сложения.
__band: побитовая операция И (&). Поведение аналогично операции сложения, за исключением того, что Lua попытается вызвать метаметод, если любой операнд не является ни целым числом, ни числом с плавающей запятой, приводимым к целому (см. §3.4.3).
__bor: побитовая операция ИЛИ (|). Поведение аналогично побитовой операции И.
__bxor: побитовая операция исключающего ИЛИ (двойной ~). Поведение аналогично побитовой операции И.
__bnot: побитовая операция НЕ (унарный ~). Поведение аналогично побитовой операции И.
__shl: побитовый сдвиг влево («). Поведение аналогично побитовой операции И.
__shr: побитовый сдвиг вправо (»). Поведение аналогично побитовой операции И.
__concat: операция конкатенации (..). Поведение аналогично операции сложения, за исключением того, что Lua попытается вызвать метаметод, если любой операнд не является ни строкой, ни числом (которое всегда приводимо к строке).
__len: операция длины (#). Если объект не является строкой, Lua попытается вызвать его метаметод. Если метаметод существует, Lua вызывает его с объектом в качестве аргумента, и результат вызова (всегда приведенный к одному значению) является результатом операции. Если метаметода нет, но объект является таблицей, то Lua использует операцию длины таблицы (см. §3.4.7). В противном случае Lua вызывает ошибку.
__eq: операция равенства (==). Поведение аналогично операции сложения, за исключением того, что Lua попытается вызвать метаметод только тогда, когда сравниваемые значения являются либо обеими таблицами, либо обоими полными userdata и они не равны по примитивному сравнению. Результат вызова всегда преобразуется в логическое значение.
__lt: операция “меньше чем” (<). Поведение аналогично операции сложения, за исключением того, что Lua попытается вызвать метаметод только тогда, когда сравниваемые значения не являются ни обоими числами, ни обеими строками. Более того, результат вызова всегда преобразуется в логическое значение.
__le: операция “меньше или равно” (<=). Поведение аналогично операции “меньше чем”.
__index: операция доступа по индексу table[key]. Это событие происходит, когда table не является таблицей или когда ключ отсутствует в таблице. Метазначение ищется в метатаблице таблицы. Метазначение для этого события может быть либо функцией, либо таблицей, либо любым значением с метазначением __index. Если это функция, она вызывается с таблицей и ключом в качестве аргументов, и результат вызова (приведенный к одному значению) является результатом операции. В противном случае окончательный результат — это результат индексации этого метазначения с ключом. Эта индексация является обычной, а не сырой, и, следовательно, может вызвать другой метаметод __index.
__newindex: операция присваивания по индексу table[key] = value. Как и событие индексации, это событие происходит, когда table не является таблицей или когда ключ отсутствует в таблице. Метазначение ищется в метатаблице таблицы. Как и в случае с индексацией, метазначение для этого события может быть либо функцией, либо таблицей, либо любым значением с метазначением __newindex. Если это функция, она вызывается с таблицей, ключом и значением в качестве аргументов. В противном случае Lua повторяет присваивание индексации для этого метазначения с тем же ключом и значением. Это присваивание является обычным, а не сырым, и, следовательно, может вызвать другой метаметод __newindex.
Каждый раз, когда вызывается метазначение __newindex, Lua не выполняет примитивное присваивание. Если это необходимо, сам метаметод может вызвать rawset для выполнения присваивания.
__call: операция вызова func(args). Это событие происходит, когда Lua пытается вызвать значение, не являющееся функцией (то есть func не является функцией). Метаметод ищется в func. Если он присутствует, метаметод вызывается с func в качестве первого аргумента, за которым следуют аргументы оригинального вызова (args). Все результаты вызова являются результатами операции. Это единственный метаметод, который позволяет возвращать несколько результатов.
2.5 – Сборка мусора
Lua осуществляет автоматическое управление памятью. Это означает, что вам не нужно беспокоиться о выделении памяти для новых объектов или ее освобождении, когда объекты больше не нужны. Lua управляет памятью автоматически, запуская сборщик мусора для сбора всех мертвых объектов. Вся память, используемая Lua, подлежит автоматическому управлению: строки, таблицы, пользовательские данные (userdata), функции, потоки, внутренние структуры и т.д.
Объект считается мертвым, как только сборщик может быть уверен, что к объекту больше не будет обращений при нормальном выполнении программы. («Нормальное выполнение» здесь исключает финализаторы, которые воскрешают мертвые объекты (см. §2.5.3), а также исключает некоторые операции с использованием библиотеки отладки.) Обратите внимание, что момент, когда сборщик может быть уверен в том, что объект мертв, может не совпадать с ожиданиями программиста. Единственными гарантиями являются то, что Lua не будет собирать объект, к которому все еще можно обратиться при нормальном выполнении программы, и что в конечном итоге он соберет объект, который недоступен из Lua. (Здесь «недоступен из Lua» означает, что ни переменная, ни другой живой объект не ссылаются на данный объект.) Поскольку Lua ничего не знает о коде C, он никогда не собирает объекты, доступные через реестр (см. §4.3), который включает глобальное окружение (см. §2.2) и главный поток.
Сборщик мусора (GC) в Lua может работать в двух режимах: инкрементальном и поколенческом (generational).
Режим GC по умолчанию с параметрами по умолчанию подходит для большинства случаев использования. Однако программы, которые тратят большую часть своего времени на выделение и освобождение памяти, могут выиграть от других настроек. Имейте в виду, что поведение GC непереносимо как между платформами, так и между разными версиями Lua; следовательно, оптимальные настройки также непереносимы.
Вы можете изменить режим и параметры GC, вызвав lua_gc в C или collectgarbage в Lua. Вы также можете использовать эти функции для прямого управления сборщиком, например, для его остановки или перезапуска.
2.5.1 – Инкрементальная сборка мусора
В инкрементальном режиме каждый цикл GC выполняет сборку с пометкой и очисткой (mark-and-sweep) небольшими шагами, чередующимися с выполнением программы. В этом режиме сборщик использует три числа для управления своими циклами сборки мусора: паузу сборщика мусора, множитель шага сборщика мусора и размер шага сборщика мусора.
Пауза сборщика мусора управляет тем, как долго сборщик ждет перед началом нового цикла. Сборщик начинает новый цикл, когда количество байтов достигает n% от общего количества после предыдущей сборки. Большие значения делают сборщик менее агрессивным. Значения, равные или меньшие 100, означают, что сборщик не будет ждать начала нового цикла. Значение 200 означает, что сборщик ждет, пока общее количество байтов удвоится, прежде чем начать новый цикл.
Размер шага сборщика мусора управляет размером каждого инкрементального шага, а именно тем, сколько байтов выделяет интерпретатор перед выполнением шага: Значение n означает, что интерпретатор выделит примерно n байтов между шагами.
Множитель шага сборщика мусора управляет тем, сколько работы выполняет каждый инкрементальный шаг. Значение n означает, что интерпретатор выполнит n% единиц работы на каждое выделенное слово. Единица работы примерно соответствует обходу одного слота или очистке одного объекта. Большие значения делают сборщик более агрессивным. Остерегайтесь слишком малых значений, так как они могут сделать сборщик слишком медленным, чтобы вообще когда-либо завершить цикл. В качестве особого случая, нулевое значение означает неограниченную работу, фактически создавая неинкрементальный сборщик, останавливающий весь мир (stop-the-world).
2.5.2 – Поколенческая сборка мусора
В поколенческом режиме сборщик выполняет частые малые сборки, которые обходят только недавно созданные объекты. Если после малой сборки количество байтов превышает лимит, сборщик переключается на большую сборку, которая обходит все объекты. Затем сборщик продолжает выполнять большие сборки до тех пор, пока не обнаружит, что программа генерирует достаточно мусора, чтобы оправдать возврат к малым сборкам.
Поколенческий режим использует три параметра: множитель малой сборки (minor multiplier), множитель перехода от малой к большой сборке (minor-major multiplier) и множитель перехода от большой к малой сборке (major-minor multiplier).
Множитель малой сборки управляет частотой малых сборок. Для множителя x новая малая сборка будет выполнена, когда количество байтов станет на x% больше, чем количество используемых байтов сразу после последней большой сборки. Например, при множителе 20 сборщик выполнит малую сборку, когда количество байтов станет на 20% больше, чем общее количество после последней большой сборки.
Множитель перехода от малой к большой сборке управляет переходом к большим сборкам. Для множителя x сборщик переключится на большую сборку, когда количество байтов от старых объектов станет на x% больше, чем общее количество после предыдущей большой сборки. Например, при множителе 100 сборщик выполнит большую сборку, когда количество старых байтов превысит удвоенное общее количество после предыдущей большой сборки. В качестве особого случая, значение 0 останавливает выполнение сборщиком больших сборок.
Множитель перехода от большой к малой сборке управляет возвратом к малым сборкам. Для множителя x сборщик вернется к малым сборкам после того, как большая сборка соберет не менее x% байтов, выделенных во время последнего цикла. В частности, при множителе 0 сборщик немедленно вернется к малым сборкам после выполнения одной большой сборки.
2.5.3 – Метаметоды сборки мусора
Вы можете установить метаметоды сборщика мусора для таблиц и, используя C API, для полных пользовательских данных (userdata) (см. §2.4). Эти метаметоды, называемые финализаторами, вызываются, когда сборщик мусора обнаруживает, что соответствующая таблица или userdata мертвы. Финализаторы позволяют вам координировать сборку мусора Lua с управлением внешними ресурсами, такими как закрытие файлов, сетевых соединений или соединений с базами данных, или освобождение вашей собственной памяти.
Чтобы объект (таблица или userdata) был финализирован при сборе, вы должны пометить его для финализации. Вы помечаете объект для финализации, когда устанавливаете его метатаблицу, и эта метатаблица имеет метаметод __gc. Обратите внимание, что если вы установите метатаблицу без поля __gc и позже создадите это поле в метатаблице, объект не будет помечен для финализации.
Когда помеченный объект становится мертвым, он не собирается сборщиком мусора немедленно. Вместо этого Lua помещает его в список. После сборки Lua проходит по этому списку. Для каждого объекта в списке он проверяет метаметод __gc объекта: Если он присутствует, Lua вызывает его, передавая объект в качестве единственного аргумента.
В конце каждого цикла сборки мусора финализаторы вызываются в порядке, обратном тому, в котором объекты были помечены для финализации, среди тех, что были собраны в этом цикле; то есть первым вызывается финализатор, связанный с объектом, помеченным последним в программе. Выполнение каждого финализатора может произойти в любой момент во время выполнения обычного кода.
Поскольку собираемый объект все еще должен использоваться финализатором, этот объект (и другие объекты, доступные только через него) должны быть воскрешены Lua. Обычно это воскрешение является временным, и память объекта освобождается в следующем цикле сборки мусора. Однако, если финализатор сохраняет объект в каком-либо глобальном месте (например, в глобальной переменной), то воскрешение становится постоянным. Более того, если финализатор снова помечает финализируемый объект для финализации, его финализатор будет вызван снова в следующем цикле, когда объект будет мертв. В любом случае память объекта освобождается только в том цикле GC, когда объект мертв и не помечен для финализации.
Когда вы закрываете состояние (см. lua_close), Lua вызывает финализаторы всех объектов, помеченных для финализации, следуя обратному порядку их пометки. Если какой-либо финализатор помечает объекты для сбора на этом этапе, эти пометки не имеют эффекта.
Финализаторы не могут прерываться (yield) и не могут запускать сборщик мусора. Поскольку они могут выполняться в непредсказуемые моменты времени, хорошей практикой является ограничение каждого финализатора минимумом, необходимым для надлежащего освобождения связанного с ним ресурса.
Любая ошибка во время выполнения финализатора генерирует предупреждение; ошибка не распространяется дальше.
2.5.4 – Слабые таблицы
Слабая таблица — это таблица, элементы которой являются слабыми ссылками. Слабая ссылка игнорируется сборщиком мусора. Другими словами, если единственными ссылками на объект являются слабые ссылки, то сборщик мусора соберет этот объект.
Слабая таблица может иметь слабые ключи, слабые значения или и то, и другое. Таблица со слабыми значениями позволяет собирать свои значения, но предотвращает сбор своих ключей. Таблица со слабыми и ключами, и значениями позволяет собирать как ключи, так и значения. В любом случае, если либо ключ, либо значение собраны, вся пара удаляется из таблицы. Слабость таблицы контролируется полем __mode ее метатаблицы. Это метазначение, если присутствует, должно быть одной из следующих строк: "k" для таблицы со слабыми ключами; "v" для таблицы со слабыми значениями; или "kv" для таблицы со слабыми и ключами, и значениями.
Таблица со слабыми ключами и сильными значениями также называется эфемеронной таблицей (ephemeron table). В эфемеронной таблице значение считается достижимым, только если достижим его ключ. В частности, если единственная ссылка на ключ исходит из его значения, пара удаляется.
Любое изменение слабости таблицы может вступить в силу только на следующем цикле сбора. В частности, если вы меняете слабость на более сильный режим, Lua все еще может собрать некоторые элементы из этой таблицы до того, как изменение вступит в силу.
Только объекты, имеющие явное построение, удаляются из слабых таблиц. Значения, такие как числа и легкие C-функции, не подлежат сборке мусора и, следовательно, не удаляются из слабых таблиц (если только не собраны связанные с ними значения). Хотя строки подлежат сборке мусора, они не имеют явного построения, и их равенство определяется по значению; они ведут себя скорее как значения, чем как объекты. Поэтому они не удаляются из слабых таблиц.
Воскрешенные объекты (то есть объекты, находящиеся в процессе финализации, и объекты, доступные только через финализируемые объекты) имеют особое поведение в слабых таблицах. Они удаляются из слабых значений перед запуском их финализаторов, но удаляются из слабых ключей только при следующей сборке после запуска финализаторов, когда такие объекты фактически освобождаются. Это поведение позволяет финализатору получать доступ к свойствам, связанным с объектом, через слабые таблицы.
Если слабая таблица находится среди воскрешенных объектов в цикле сборки, она может быть не очищена должным образом до следующего цикла.
2.6 – Сопрограммы
Lua поддерживает сопрограммы (coroutines), также называемые совместной многопоточностью. Сопрограмма в Lua представляет собой независимый поток выполнения. Однако, в отличие от потоков в многопоточных системах, сопрограмма приостанавливает свое выполнение только путем явного вызова функции прерывания (yield).
Вы создаете сопрограмму, вызывая coroutine.create. Ее единственным аргументом является функция, которая является главной функцией сопрограммы. Функция create только создает новую сопрограмму и возвращает дескриптор на нее (объект типа thread); она не запускает сопрограмму.
Вы выполняете сопрограмму, вызывая coroutine.resume. Когда вы впервые вызываете coroutine.resume, передавая в качестве первого аргумента поток, возвращенный coroutine.create, сопрограмма начинает свое выполнение с вызова своей главной функции. Дополнительные аргументы, переданные в coroutine.resume, передаются в качестве аргументов этой функции. После того как сопрограмма начинает работать, она выполняется до тех пор, пока не завершится или не прервется (yield).
Сопрограмма может завершить свое выполнение двумя способами: нормально, когда ее главная функция возвращает управление (явно или неявно, после последней инструкции); и аварийно, если происходит незащищенная ошибка. В случае нормального завершения coroutine.resume возвращает true плюс любые значения, возвращенные главной функцией сопрограммы. В случае ошибок coroutine.resume возвращает false плюс объект ошибки. В этом случае сопрограмма не разворачивает свой стек, так что после ошибки его можно проверить с помощью API отладки.
Сопрограмма прерывается (yield) вызовом 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, распространяет любую ошибку вызывающей стороне. В этом случае функция также закрывает сопрограмму (см. coroutine.close).
В качестве примера того, как работают сопрограммы, рассмотрим следующий код:
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
Вы также можете создавать сопрограммы и управлять ими через C API: см. функции lua_newthread, lua_resume и lua_yield.
2 - 3 – Язык Lua: Лексика и синтаксис
Полное описание лексических соглашений, ключевых слов, литералов, переменных и операторов языка Lua.
Оглавление
- Лексические соглашения
- Переменные
- Инструкции (Statements)
- Выражения
3 – Язык
В этом разделе описываются лексика, синтаксис и семантика Lua. Другими словами, здесь описывается, какие лексемы допустимы, как их можно комбинировать и что означают их комбинации.
Языковые конструкции будут объясняться с использованием обычной расширенной формы Бэкуса-Наура (РБНФ), в которой {a} означает 0 или более a, а [a] означает необязательное a. Нетерминалы показаны как нетерминал, ключевые слова показаны как kword, а другие терминальные символы показаны как ‘=’. Полный синтаксис Lua можно найти в §9 в конце этого руководства.
3.1 – Лексические соглашения
Lua — это язык со свободной формой записи. Он игнорирует пробелы и комментарии между лексическими элементами (токенами), за исключением случаев, когда они выступают в роли разделителей между двумя токенами. В исходном коде Lua распознает как пробелы стандартные пробельные символы ASCII: пробел, перевод страницы, перевод строки, возврат каретки, горизонтальную табуляцию и вертикальную табуляцию.
Имена (также называемые идентификаторами) в Lua могут быть любой строкой, состоящей из латинских букв, арабско-индийских цифр и символов подчеркивания, не начинающейся с цифры и не являющейся зарезервированным словом. Идентификаторы используются для именования переменных, полей таблиц и меток.
Следующие ключевые слова зарезервированы и не могут использоваться в качестве имен:
and break do else elseif end
false for function global goto if
in local nil not or repeat
return then true until while
Lua — регистрозависимый язык: and — зарезервированное слово, но And и AND — два разных допустимых имени. В соответствии с соглашением, в программах следует избегать создания имен, начинающихся с подчеркивания, за которым следует одна или несколько заглавных букв (например, _VERSION).
Следующие строки обозначают другие токены:
+ - * / % ^ #
& ~ | << >> //
== ~= <= >= < > =
( ) { } [ ] ::
; : , . .. ...
Короткая литеральная строка может быть ограничена парными одинарными или двойными кавычками и может содержать следующие C-подобные escape-последовательности: \a (звонок), \b (забой), \f (перевод страницы), \n (перевод строки), \r (возврат каретки), \t (горизонтальная табуляция), \v (вертикальная табуляция), \\ (обратная косая черта), \" (кавычка [двойная]) и \' (апостроф [одинарная кавычка]). Обратная косая черта, за которой следует разрыв строки, приводит к появлению символа новой строки в строке. Escape-последовательность \z пропускает следующий за ней диапазон пробельных символов, включая разрывы строк; это особенно полезно для разбиения и отступа длинной литеральной строки на несколько строк без добавления символов новой строки и пробелов в содержимое строки. Короткая литеральная строка не может содержать неэкранированные разрывы строк или escape-последовательности, не образующие допустимую управляющую последовательность.
Мы можем указать любой байт в короткой литеральной строке, включая встроенные нули, по его числовому значению. Это можно сделать с помощью escape-последовательности \xXX, где XX — это последовательность ровно из двух шестнадцатеричных цифр, или с помощью escape-последовательности \ddd, где ddd — последовательность до трех десятичных цифр. (Обратите внимание, что если за десятичной escape-последовательностью должна следовать цифра, она должна быть выражена ровно тремя цифрами).
Кодировка UTF-8 символа Unicode может быть вставлена в литеральную строку с помощью escape-последовательности \u{XXX} (с обязательными фигурными скобками), где XXX — это последовательность из одной или более шестнадцатеричных цифр, представляющих кодовую точку символа. Эта кодовая точка может быть любым значением меньше 231. (Здесь Lua использует оригинальную спецификацию UTF-8, которая не ограничена допустимыми кодовыми точками Unicode).
Литеральные строки также могут быть определены с использованием длинного формата, заключенного в длинные скобки. Мы определяем открывающую длинную скобку уровня 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 открывает файлы для разбора в текстовом режиме, и файловые функции системы могут иметь проблемы с некоторыми управляющими символами. Поэтому безопаснее представлять двоичные данные в виде закавыченного литерала с явными escape-последовательностями для нетекстовых символов.
Числовая константа (или число) может быть записана с необязательной дробной частью и необязательным десятичным порядком, обозначаемым буквой ’e’ или ‘E’. Lua также принимает шестнадцатеричные константы, начинающиеся с 0x или 0X. Шестнадцатеричные константы также могут иметь необязательную дробную часть плюс необязательный двоичный порядок, обозначаемый буквой ‘p’ или ‘P’ и записываемый в десятичном виде. (Например, 0x1.fp10 обозначает 1984, то есть 0x1f / 16, умноженное на 210).
Числовая константа с десятичной точкой или порядком обозначает число с плавающей запятой (float); в противном случае, если ее значение помещается в целое число или она является шестнадцатеричной константой, она обозначает целое число (integer); в противном случае (то есть десятичное целое число, вызывающее переполнение) она обозначает float. Шестнадцатеричные числа без точки и порядка всегда обозначают целое значение; если значение переполняется, оно “сворачивается” (wrap around), чтобы соответствовать допустимому целому числу.
Примеры допустимых целочисленных констант:
Примеры допустимых констант с плавающей запятой:
3.0 3.1416 314.16e-2 0.31416E1 34e1
0x0.1E 0xA23p-4 0X1.921FB54442D18P+1
Комментарий начинается с двойного дефиса (--) в любом месте вне строки. Если текст сразу после -- не является открывающей длинной скобкой, комментарий является коротким комментарием, который длится до конца строки. В противном случае это длинный комментарий, который длится до соответствующей закрывающей длинной скобки.
3.2 – Переменные
Переменные — это места, хранящие значения. В Lua существует три вида переменных: глобальные переменные, локальные переменные и поля таблиц.
Одиночное имя может обозначать глобальную переменную или локальную переменную (или формальный параметр функции, который является особым видом локальной переменной) (см. §2.2):
var ::= Name
Name обозначает идентификаторы (см. §3.1).
Поскольку переменные имеют лексическую область видимости, локальные переменные могут свободно использоваться функциями, определенными внутри их области видимости (см. §2.2).
До первого присваивания переменной ее значение равно nil.
Квадратные скобки используются для индексации таблицы:
var ::= prefixexp ‘[’ exp ‘]’
Значение доступов к полям таблицы может быть изменено через метатаблицы (см. §2.4).
Синтаксис var.Name — это просто синтаксический сахар для var["Name"]:
var ::= prefixexp ‘.’ Name
Доступ к глобальной переменной x эквивалентен _ENV.x.
3.3 – Инструкции (Statements)
Lua поддерживает почти общепринятый набор инструкций, похожий на те, что есть в других обычных языках. Этот набор включает блоки, присваивания, управляющие структуры, вызовы функций и объявления переменных.
3.3.1 – Блоки
Блок — это список инструкций, которые выполняются последовательно:
block ::= {stat}
В Lua есть пустые инструкции, которые позволяют разделять инструкции точкой с запятой, начинать блок с точки с запятой или писать две точки с запятой подряд:
stat ::= ‘;’
Как вызовы функций, так и присваивания могут начинаться с открывающей скобки. Эта возможность приводит к неоднозначности в грамматике Lua. Рассмотрим следующий фрагмент:
a = b + c
(print or io.write)('done')
Грамматика может интерпретировать этот фрагмент двумя способами:
a = b + c(print or io.write)('done')
a = b + c; (print or io.write)('done')
Текущий парсер всегда интерпретирует такие конструкции первым способом, рассматривая открывающую скобку как начало аргументов вызова. Чтобы избежать этой неоднозначности, рекомендуется всегда предварять точкой с запятой инструкции, начинающиеся со скобки:
;(print or io.write)('done')
Блок может быть явно выделен для создания одиночной инструкции:
stat ::= do block end
Явные блоки полезны для управления областью видимости объявлений переменных. Явные блоки также иногда используются для добавления инструкции return в середине другого блока (см. §3.3.4).
3.3.2 – Чанки
Единица компиляции Lua называется чанком (chunk). Синтаксически чанк — это просто блок:
chunk ::= block
Lua обрабатывает чанк как тело анонимной функции с переменным числом аргументов (см. §3.4.11). Таким образом, чанки могут определять локальные переменные, получать аргументы и возвращать значения. Более того, такая анонимная функция компилируется как находящаяся в области видимости внешней локальной переменной с именем _ENV (см. §2.2). Результирующая функция всегда имеет _ENV в качестве своей единственной внешней переменной, даже если она не использует эту переменную.
Чанк может храниться в файле или в строке внутри программы-хоста. Чтобы выполнить чанк, Lua сначала загружает его, предварительно компилируя код чанка в инструкции для виртуальной машины, а затем Lua выполняет скомпилированный код с помощью интерпретатора виртуальной машины.
Чанки также могут быть предварительно скомпилированы в двоичную форму; подробности см. в программе luac и функции string.dump. Программы в исходной и скомпилированной формах взаимозаменяемы; Lua автоматически определяет тип файла и действует соответственно (см. load). Имейте в виду, что, в отличие от исходного кода, злонамеренно созданные двоичные чанки могут вызвать крах интерпретатора.
3.3.3 – Присваивание
Lua допускает множественное присваивание. Поэтому синтаксис присваивания определяет список переменных слева и список выражений справа. Элементы в обоих списках разделяются запятыми:
stat ::= varlist ‘=’ explist
varlist ::= var {‘,’ var}
explist ::= exp {‘,’ exp}
Выражения обсуждаются в §3.4.
Перед присваиванием список значений выравнивается по длине списка переменных (см. §3.4.12).
Если переменная одновременно присваивается и читается внутри множественного присваивания, Lua гарантирует, что все чтения получат значение переменной до присваивания. Таким образом, код
устанавливает a[3] в 20, не затрагивая a[4], потому что i в a[i] вычисляется (в 3) до того, как ей присваивается 4. Аналогично, строка
обменивает значения x и y, а
циклически переставляет значения x, y и z.
Обратите внимание, что эта гарантия распространяется только на доступы, синтаксически находящиеся внутри инструкции присваивания. Если функция или метаметод, вызванные во время присваивания, изменяют значение переменной, Lua не дает никаких гарантий относительно порядка этого доступа.
Присваивание глобальному имени x = val эквивалентно присваиванию _ENV.x = val (см. §2.2).
Значение присваиваний полям таблиц и глобальным переменным (которые на самом деле тоже являются полями таблиц) может быть изменено через метатаблицы (см. §2.4).
3.3.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 в двух вариантах (см. §3.3.5).
Выражение-условие управляющей структуры может возвращать любое значение. И false, и nil проверяются как ложь. Все значения, отличные от nil и false, проверяются как истина. В частности, число 0 и пустая строка также проверяются как истина.
В цикле repeat–until внутренний блок не заканчивается на ключевом слове until, а только после условия. Таким образом, условие может ссылаться на локальные переменные, объявленные внутри блока цикла.
Инструкция goto передает управление программой на метку. По синтаксическим причинам метки в Lua также считаются инструкциями:
stat ::= goto Name
stat ::= label
label ::= ‘::’ Name ‘::’
Метка видна во всем блоке, где она определена, за исключением вложенных функций. goto может переходить на любую видимую метку, если при этом не происходит входа в область видимости объявления переменной. Метка не должна быть объявлена там, где видна предыдущая метка с тем же именем, даже если эта другая метка была объявлена в охватывающем блоке.
Инструкция break завершает выполнение цикла while, repeat или for, переходя к следующей инструкции после цикла:
stat ::= break
break завершает самый внутренний объемлющий цикл.
Инструкция return используется для возврата значений из функции или чанка (который обрабатывается как анонимная функция). Функции могут возвращать более одного значения, поэтому синтаксис инструкции return таков:
stat ::= return [explist] [‘;’]
Инструкция return может быть записана только как последняя инструкция блока. Если необходимо выполнить возврат в середине блока, можно использовать явный внутренний блок, как в идиоме do return end, потому что теперь return является последней инструкцией в своем (внутреннем) блоке.
3.3.5 – Инструкция For
Инструкция for имеет две формы: числовую и обобщенную.
Числовой цикл for
Числовой цикл for повторяет блок кода, пока управляющая переменная проходит через арифметическую прогрессию. Он имеет следующий синтаксис:
stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end
Заданный идентификатор (Name) определяет управляющую переменную, которая является новой переменной только для чтения (const), локальной для тела цикла (block).
Цикл начинается с однократного вычисления трех управляющих выражений. Их значения называются соответственно начальным значением, пределом и шагом. Если шаг отсутствует, по умолчанию он равен 1.
Если и начальное значение, и шаг являются целыми числами, цикл выполняется с целыми числами; обратите внимание, что предел может не быть целым числом. В противном случае три значения преобразуются в числа с плавающей запятой, и цикл выполняется с плавающей запятой. В этом случае следует опасаться точности чисел с плавающей запятой.
После этой инициализации тело цикла повторяется, при этом значение управляющей переменной проходит через арифметическую прогрессию, начиная с начального значения, с разностью, заданной шагом. Отрицательный шаг создает убывающую последовательность; шаг, равный нулю, вызывает ошибку. Цикл продолжается, пока значение меньше или равно пределу (больше или равно для отрицательного шага). Если начальное значение уже больше предела (или меньше, если шаг отрицательный), тело не выполняется.
Для целочисленных циклов управляющая переменная никогда не “сворачивается” (wrap around); вместо этого цикл заканчивается в случае переполнения.
Обобщенный цикл for
Обобщенная инструкция for работает с функциями, называемыми итераторами. На каждой итерации функция-итератор вызывается для получения нового значения, останавливаясь, когда это новое значение равно nil. Обобщенный цикл for имеет следующий синтаксис:
stat ::= for namelist in explist do block end
namelist ::= Name {‘,’ Name}
Инструкция for, такая как
for var_1, ···, var_n in explist do body end
работает следующим образом.
Имена var_i объявляют переменные цикла, локальные для тела цикла. Первая из этих переменных является управляющей переменной, которая является переменной только для чтения (const).
Цикл начинается с вычисления explist для получения четырех значений: функции-итератора, состояния, начального значения для управляющей переменной и закрывающего значения.
Затем, на каждой итерации, Lua вызывает функцию-итератор с двумя аргументами: состоянием и управляющей переменной. Результаты этого вызова затем присваиваются переменным цикла в соответствии с правилами множественного присваивания (см. §3.3.3). Если управляющая переменная становится nil, цикл завершается. В противном случае выполняется тело, и цикл переходит к следующей итерации.
Закрывающее значение ведет себя как закрываемая переменная (to-be-closed variable) (см. §3.3.8), которая может использоваться для освобождения ресурсов при завершении цикла. В остальном оно не влияет на цикл.
3.3.6 – Вызовы функций как инструкции
Для обеспечения возможных побочных эффектов вызовы функций могут выполняться как инструкции:
stat ::= functioncall
В этом случае все возвращаемые значения отбрасываются. Вызовы функций объясняются в §3.4.10.
3.3.7 – Объявления переменных
Локальные и глобальные переменные могут быть объявлены в любом месте внутри блока. Объявление может включать инициализацию:
stat ::= local attnamelist [‘=’ explist]
stat ::= global attnamelist [‘=’ explist]
Если инициализация отсутствует, локальные переменные инициализируются значением nil; глобальные переменные остаются без изменений. В противном случае инициализация подвергается тому же выравниванию, что и множественное присваивание (см. §3.3.3). Более того, для глобальных переменных инициализация вызовет ошибку времени выполнения, если переменная уже определена, то есть имеет значение, отличное от nil.
Список имен может иметь префиксный атрибут (имя в угловых скобках), и каждое имя переменной может иметь постфиксный атрибут:
attnamelist ::= [attrib] Name [attrib] {‘,’ Name [attrib]}
attrib ::= ‘<’ Name ‘>’
Префиксный атрибут применяется ко всем именам в списке; постфиксный атрибут применяется к конкретному имени. Существует два возможных атрибута: const, который объявляет константу или переменную только для чтения, то есть переменную, которая не может использоваться в левой части присваивания, и close, который объявляет закрываемую переменную (to-be-closed variable) (см. §3.3.8). Только локальные переменные могут иметь атрибут close. Список переменных может содержать не более одной закрываемой переменной.
Lua предлагает также коллективное объявление для глобальных переменных:
stat ::= global [attrib] ‘*’
Эта специальная форма неявно объявляет как глобальные все имена, которые ранее не были объявлены явно. В частности, global<const> * неявно объявляет как глобальные только для чтения все имена, не объявленные ранее явно; см. следующий пример:
global X
global<const> *
print(math.pi) -- Ok, 'print' и 'math' только для чтения
X = 1 -- Ok, объявлена как для чтения-записи
Y = 1 -- Ошибка, Y только для чтения
Как отмечено в §2.2, все чанки начинаются с неявного объявления global *, но это вводное объявление становится недействительным внутри области видимости любого другого объявления global. Следовательно, программа, которая не использует объявления global или начинается с global *, имеет свободный доступ на чтение и запись к любой глобальной переменной; программа, которая начинается с global<const> *, имеет свободный доступ только для чтения к любой глобальной переменной; а программа, которая начинается с любого другого объявления global (например, global none), может ссылаться только на объявленные переменные.
Обратите внимание, что для глобальных переменных эффект любого объявления является чисто синтаксическим (за исключением необязательного присваивания):
global X <const>, _G
X = 1 -- ОШИБКА
_ENV.X = 1 -- Ok
_G.print(X) -- Ok
foo() -- 'foo' может свободно изменять любую глобальную переменную
Чанк также является блоком (см. §3.3.2), поэтому переменные могут быть объявлены в чанке вне любого явного блока.
Правила видимости для объявлений переменных объясняются в §2.2.
3.3.8 – Закрываемые переменные (To-be-closed Variables)
Закрываемая переменная ведет себя как константная локальная переменная, за исключением того, что ее значение закрывается всякий раз, когда переменная выходит из области видимости, включая нормальное завершение блока, выход из блока по break/goto/return или выход из-за ошибки.
Здесь закрыть значение означает вызвать его метаметод __close. При вызове метаметода само значение передается в качестве первого аргумента. Если произошла ошибка, объект ошибки, вызвавший выход, передается в качестве второго аргумента; в противном случае второй аргумент отсутствует.
Значение, присваиваемое закрываемой переменной, должно иметь метаметод __close или быть ложным значением. (nil и false игнорируются как закрываемые значения).
Если несколько закрываемых переменных выходят из области видимости при одном и том же событии, они закрываются в порядке, обратном порядку их объявления.
Если во время выполнения метода закрытия возникает ошибка, эта ошибка обрабатывается как ошибка в обычном коде, где была определена переменная. После ошибки остальные ожидающие методы закрытия все равно будут вызваны.
Если сопрограмма (coroutine) выполняет yield и никогда не возобновляется, некоторые переменные могут никогда не выйти из области видимости и, следовательно, никогда не будут закрыты. (Эти переменные — те, которые созданы внутри сопрограммы и находятся в области видимости в точке, где сопрограмма выполнила yield). Аналогично, если сопрограмма завершается с ошибкой, она не разворачивает свой стек, поэтому не закрывает никакие переменные. В обоих случаях вы можете либо использовать финализаторы, либо вызвать coroutine.close для закрытия переменных. Однако если сопрограмма была создана через coroutine.wrap, то соответствующая функция закроет сопрограмму в случае ошибок.
3.4 – Выражения
Базовыми выражениями в Lua являются следующие:
exp ::= prefixexp
exp ::= nil | false | true
exp ::= Numeral
exp ::= LiteralString
exp ::= functiondef
exp ::= tableconstructor
exp ::= ‘...’
exp ::= exp binop exp
exp ::= unop exp
prefixexp ::= var | functioncall | ‘(’ exp ‘)’
Числа и литеральные строки объясняются в §3.1; переменные — в §3.2; определения функций — в §3.4.11; вызовы функций — в §3.4.10; конструкторы таблиц — в §3.4.9. Выражения vararg, обозначаемые тремя точками ('...'), могут использоваться только непосредственно внутри вариадической функции; они объясняются в §3.4.11.
Бинарные операторы включают арифметические операторы (см. §3.4.1), побитовые операторы (см. §3.4.2), операторы отношения (см. §3.4.4), логические операторы (см. §3.4.5) и оператор конкатенации (см. §3.4.6). Унарные операторы включают унарный минус (см. §3.4.1), унарное побитовое НЕ (см. §3.4.2), унарное логическое not (см. §3.4.5) и унарный оператор длины (см. §3.4.7).
3.4.1 – Арифметические операторы
Lua поддерживает следующие арифметические операторы:
+: сложение-: вычитание*: умножение/: деление с плавающей запятой (float division)//: деление нацело вниз (floor division)%: остаток от деления (modulo)^: возведение в степень-: унарный минус
За исключением возведения в степень и деления с плавающей запятой, арифметические операторы работают следующим образом: Если оба операнда являются целыми числами, операция выполняется над целыми числами, и результат является целым числом. В противном случае, если оба операнда — числа, они преобразуются в числа с плавающей запятой, операция выполняется в соответствии с машинными правилами арифметики с плавающей запятой (обычно стандарт IEEE 754), и результатом является число с плавающей запятой. (Библиотека string приводит строки к числам в арифметических операциях; подробности см. в §3.4.3).
Возведение в степень и деление с плавающей запятой (/) всегда преобразуют свои операнды в числа с плавающей запятой, и результатом всегда является число с плавающей запятой. Возведение в степень использует функцию pow стандарта ISO C, поэтому оно работает и для нецелочисленных показателей.
Деление нацело вниз (//) — это деление, которое округляет частное в сторону минус бесконечности, в результате чего получается пол (floor) от деления операндов.
Остаток от деления (%) определяется как остаток от деления, которое округляет частное в сторону минус бесконечности (деление нацело вниз).
В случае переполнения в целочисленной арифметике все операции “сворачиваются” (wrap around).
3.4.2 – Побитовые операторы
Lua поддерживает следующие побитовые операторы:
&: побитовое И (AND)|: побитовое ИЛИ (OR)~: побитовое исключающее ИЛИ (XOR)>>: сдвиг вправо<<: сдвиг влево~: унарное побитовое НЕ (NOT)
Все побитовые операции преобразуют свои операнды в целые числа (см. §3.4.3), работают со всеми битами этих целых чисел и дают в результате целое число.
Как правый, так и левый сдвиги заполняют освобождающиеся биты нулями. Отрицательные сдвиги смещают в противоположном направлении; сдвиги с абсолютными значениями, равными или превышающими количество бит в целом числе, дают в результате ноль (поскольку все биты сдвигаются за пределы).
3.4.3 – Приведения и преобразования
Lua предоставляет некоторые автоматические преобразования между типами и представлениями во время выполнения. Побитовые операторы всегда преобразуют операнды с плавающей запятой в целые числа. Возведение в степень и деление с плавающей запятой всегда преобразуют целочисленные операнды в числа с плавающей запятой. Все другие арифметические операции, применяемые к смешанным числам (целым и с плавающей запятой), преобразуют целочисленный операнд в число с плавающей запятой. C API также преобразует целые числа в числа с плавающей запятой и наоборот по мере необходимости. Более того, конкатенация строк принимает числа в качестве аргументов, помимо строк.
При преобразовании из целого числа в число с плавающей запятой, если целое значение имеет точное представление в виде числа с плавающей запятой, то оно и является результатом. В противном случае преобразование дает ближайшее большее или ближайшее меньшее представимое значение. Такой вид преобразования никогда не завершается неудачей.
Преобразование из числа с плавающей запятой в целое проверяет, имеет ли число с плавающей запятой точное представление в виде целого числа (то есть число с плавающей запятой имеет целое значение и находится в диапазоне целочисленного представления). Если да, то это представление является результатом. В противном случае преобразование завершается неудачей.
В нескольких местах Lua приводит строки к числам, когда это необходимо. В частности, библиотека string устанавливает метаметоды, которые пытаются привести строки к числам во всех арифметических операциях. Если преобразование не удается, библиотека вызывает метаметод другого операнда (если он присутствует) или вызывает ошибку. Обратите внимание, что побитовые операторы не выполняют этого приведения.
Всегда рекомендуется не полагаться на неявные приведения строк к числам, поскольку они применяются не всегда; в частности, "1"==1 ложно, а "1"<1 вызывает ошибку (см. §3.4.4). Эти приведения существуют в основном для совместимости и могут быть удалены в будущих версиях языка.
Строка преобразуется в целое число или число с плавающей запятой в соответствии со своим синтаксисом и правилами лексера Lua. Строка также может иметь начальные и конечные пробелы и знак. Все преобразования строк в числа принимают как точку, так и текущий локальный разделитель целой и дробной части в качестве символа десятичной точки. (Однако лексер Lua принимает только точку). Если строка не является допустимым числом, преобразование завершается неудачей. При необходимости результат этого первого шага затем преобразуется в конкретный числовой подтип в соответствии с предыдущими правилами для преобразований между числами с плавающей запятой и целыми числами.
Преобразование чисел в строки использует неуказанный человекочитаемый формат. Для преобразования чисел в строки каким-либо определенным способом используйте функцию string.format.
3.4.4 – Операторы отношения
Lua поддерживает следующие операторы отношения:
==: равенство~=: неравенство<: меньше>: больше<=: меньше или равно>=: больше или равно
Эти операторы всегда дают результат false или true.
Равенство (==) сначала сравнивает типы своих операндов. Если типы различны, то результатом является false. В противном случае сравниваются значения операндов. Строки равны, если они имеют одинаковое байтовое содержимое. Числа равны, если они обозначают одно и то же математическое значение.
Таблицы, пользовательские данные (userdata) и потоки (threads) сравниваются по ссылке: два объекта считаются равными, только если это один и тот же объект. Каждый раз, когда вы создаете новый объект (таблицу, userdata или поток), этот новый объект отличается от любого ранее существовавшего объекта. Функция всегда равна самой себе. Функции с любым обнаруживаемым различием (разное поведение, разное определение) всегда различны. Функции, созданные в разное время, но без обнаруживаемых различий, могут быть классифицированы как равные или нет (в зависимости от деталей внутреннего кэширования).
Вы можете изменить способ сравнения таблиц и userdata в Lua, используя метаметод __eq (см. §2.4).
Сравнения на равенство не преобразуют строки в числа или наоборот. Таким образом, "0"==0 дает false, а t[0] и t["0"] обозначают разные записи в таблице.
Оператор ~= является точным отрицанием равенства (==).
Операторы порядка работают следующим образом. Если оба аргумента — числа, то они сравниваются в соответствии с их математическими значениями, независимо от их подтипов. В противном случае, если оба аргумента — строки, то их значения сравниваются в соответствии с текущей локалью. В противном случае Lua пытается вызвать метаметод __lt или __le (см. §2.4). Сравнение a > b транслируется в b < a, а a >= b транслируется в b <= a.
В соответствии со стандартом IEEE 754, специальное значение NaN не считается ни меньше, ни равным, ни больше какого-либо значения, включая само себя.
3.4.5 – Логические операторы
Логическими операторами в Lua являются and, or и not. Как и управляющие структуры (см. §3.3.4), все логические операторы считают false и nil ложью, а все остальное — истиной.
Оператор отрицания not всегда возвращает false или true. Оператор конъюнкции and возвращает свой первый аргумент, если это значение ложно (false или nil); в противном случае and возвращает свой второй аргумент. Оператор дизъюнкции or возвращает свой первый аргумент, если это значение отличается от nil и false; в противном случае or возвращает свой второй аргумент. И and, и or используют сокращенное вычисление (short-circuit evaluation); то есть второй операнд вычисляется, только если это необходимо. Вот несколько примеров:
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
3.4.6 – Конкатенация
Оператор конкатенации строк в Lua обозначается двумя точками ('..'). Если оба операнда являются строками или числами, то числа преобразуются в строки в неуказанном формате (см. §3.4.3). В противном случае вызывается метаметод __concat (см. §2.4).
3.4.7 – Оператор длины
Оператор длины обозначается унарным префиксным оператором #.
Длина строки — это количество ее байтов. (Это обычный смысл длины строки, когда каждый символ занимает один байт).
Оператор длины, примененный к таблице, возвращает границу (border) в этой таблице. Граница в таблице t — это любое неотрицательное целое число, которое удовлетворяет следующему условию:
(border == 0 or t[border] ~= nil) and
(t[border + 1] == nil or border == math.maxinteger)
Другими словами, граница — это любой положительный целочисленный индекс, присутствующий в таблице, за которым следует отсутствующий индекс, плюс два предельных случая: ноль, когда индекс 1 отсутствует; и максимальное значение для целого числа, когда этот индекс присутствует. Обратите внимание, что ключи, не являющиеся положительными целыми числами, не влияют на границы.
Таблица ровно с одной границей называется последовательностью (sequence). Например, таблица {10,20,30,40,50} является последовательностью, так как у нее только одна граница (5). Таблица {10,20,30,nil,50} имеет две границы (3 и 5) и, следовательно, не является последовательностью. (nil по индексу 4 называется дырой). Таблица {nil,20,30,nil,nil,60,nil} имеет три границы (0, 3 и 6), поэтому она тоже не является последовательностью. Таблица {} является последовательностью с границей 0.
Когда t — последовательность, #t возвращает ее единственную границу, что соответствует интуитивному понятию длины последовательности. Когда t не является последовательностью, #t может вернуть любую из ее границ. (Конкретная граница зависит от деталей внутреннего представления таблицы, которые, в свою очередь, могут зависеть от того, как таблица была заполнена, и от адресов памяти ее нечисловых ключей).
Вычисление длины таблицы имеет гарантированное наихудшее время O(log n), где n — наибольший целочисленный ключ в таблице.
Программа может изменить поведение оператора длины для любого значения, кроме строк, через метаметод __len (см. §2.4).
3.4.8 – Приоритет операторов
Приоритет операторов в Lua соответствует таблице ниже, от низшего к высшему:
or
and
< > <= >= ~= ==
|
~
&
<< >>
..
+ -
* / // %
унарные операторы (not # - ~)
^
Как обычно, вы можете использовать скобки для изменения приоритетов в выражении. Операторы конкатенации ('..') и возведения в степень ('^') правоассоциативны. Все остальные бинарные операторы левоассоциативны.
3.4.9 – Конструкторы таблиц
Конструкторы таблиц — это выражения, которые создают таблицы. Каждый раз, когда конструктор вычисляется, создается новая таблица. Конструктор можно использовать для создания пустой таблицы или для создания таблицы и инициализации некоторых ее полей. Общий синтаксис конструкторов таков:
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" -- 1-е exp
t[2] = "y" -- 2-е exp
t.x = 1 -- t["x"] = 1
t[3] = f(x) -- 3-е exp
t[30] = 23
t[4] = 45 -- 4-е exp
a = t
end
Порядок присваиваний в конструкторе не определен. (Этот порядок имел бы значение только при наличии повторяющихся ключей).
Если последнее поле в списке имеет вид exp и выражение является выражением с множественными результатами (multires expression), то все значения, возвращаемые этим выражением, последовательно входят в список (см. §3.4.12).
Список полей может иметь необязательный завершающий разделитель для удобства машинно-генерируемого кода.
3.4.10 – Вызовы функций
Вызов функции в Lua имеет следующий синтаксис:
functioncall ::= prefixexp args
При вызове функции сначала вычисляются prefixexp и args. Если значение prefixexp имеет тип function, то эта функция вызывается с заданными аргументами. В противном случае, если присутствует метаметод __call у prefixexp, он вызывается: его первым аргументом является значение prefixexp, за которым следуют исходные аргументы вызова (см. §2.4).
Форма
functioncall ::= prefixexp ‘:’ Name args
может использоваться для эмуляции методов. Вызов v:name(args) является синтаксическим сахаром для v.name(v, args), за исключением того, что v вычисляется только один раз.
Аргументы имеют следующий синтаксис:
args ::= ‘(’ [explist] ‘)’
args ::= tableconstructor
args ::= LiteralString
Все выражения-аргументы вычисляются перед вызовом. Вызов формы f{fields} является синтаксическим сахаром для f({fields}); то есть список аргументов — это единственная новая таблица. Вызов формы f'string' (или f"string", или f[[string]]) является синтаксическим сахаром для f('string'); то есть список аргументов — это единственная литеральная строка.
Вызов формы return functioncall, не находящийся в области видимости закрываемой переменной, называется хвостовым вызовом (tail call). Lua реализует правильные хвостовые вызовы (proper tail calls или proper tail recursion): при хвостовом вызове вызываемая функция повторно использует стековый фрейм вызывающей функции. Следовательно, нет ограничения на количество вложенных хвостовых вызовов, которые может выполнить программа. Однако хвостовой вызов стирает любую отладочную информацию о вызывающей функции. Обратите внимание, что хвостовой вызов происходит только при определенном синтаксисе, когда return имеет один-единственный вызов функции в качестве аргумента, и это происходит вне области видимости любой закрываемой переменной. Этот синтаксис заставляет вызывающую функцию возвращать в точности то, что возвращает вызываемая функция, без каких-либо промежуточных действий. Таким образом, ни один из следующих примеров не является хвостовым вызовом:
return (f(x)) -- результаты выравниваются до 1
return 2 * f(x) -- результат умножается на 2
return x, f(x) -- дополнительные результаты
f(x); return -- результаты отбрасываются
return x or f(x) -- результаты выравниваются до 1
3.4.11 – Определения функций
Синтаксис определения функции следующий:
functiondef ::= function funcbody
funcbody ::= ‘(’ [parlist] ‘)’ block end
Следующий синтаксический сахар упрощает определения функций:
stat ::= function funcname funcbody
stat ::= local function Name funcbody
stat ::= global function Name funcbody
funcname ::= Name {‘.’ Name} [‘:’ Name]
Инструкция
транслируется в
Инструкция
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). Аналогично, инструкция
global function f () body end
транслируется в
global f; global f = function () body end
Второе global делает присваивание инициализацией, которая вызовет ошибку, если эта глобальная переменная уже определена.
Синтаксис с двоеточием используется для эмуляции методов, добавляя неявный дополнительный параметр self в функцию. Таким образом, инструкция
function t.a.b.c:f (params) body end
является синтаксическим сахаром для
t.a.b.c.f = function (self, params) body end
Определение функции — это выполняемое выражение, значением которого является значение типа function. Когда Lua предкомпилирует чанк, все тела его функций также предкомпилируются, но они еще не создаются. Затем, когда Lua выполняет определение функции, функция инстанцируется (или замыкается). Этот экземпляр функции, или замыкание (closure), является окончательным значением выражения.
Результаты возвращаются с помощью инструкции return (см. §3.3.4). Если управление достигает конца функции без встречи инструкции return, то функция возвращается без результатов.
Существует системно-зависимое ограничение на количество значений, которые может вернуть функция. Гарантируется, что этот предел составляет не менее 1000.
Параметры
Параметры действуют как локальные переменные, которые инициализируются значениями аргументов:
parlist ::= namelist [‘,’ varargparam] | varargparam
varargparam ::= ‘...’ [Name]
Когда функция Lua вызывается, она выравнивает свой список аргументов по длине списка параметров (см. §3.4.12), если только функция не является вариадической, что указывается тремя точками ('...') в конце ее списка параметров. Вариадическая функция не выравнивает свой список аргументов; вместо этого она собирает все дополнительные аргументы и предоставляет их функции через vararg-таблицу. В этой таблице значения с индексами 1, 2 и т. д. являются дополнительными аргументами, а значение с индексом "n" — это количество дополнительных аргументов.
В качестве примера рассмотрим следующие определения:
function f(a, b) end
function g(a, b, ...) end
function r() return 1,2,3 end
Тогда мы имеем следующее отображение аргументов в параметры и в vararg-таблицу:
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, va. table -> {n = 0}
g(3, 4) a=3, b=4, va. table -> {n = 0}
g(3, 4, 5, 8) a=3, b=4, va. table -> {5, 8, n = 2}
g(5, r()) a=5, b=1, va. table -> {2, 3, n = 2}
Vararg-таблица в вариадической функции может иметь необязательное имя, указанное после трех точек. Если оно присутствует, это имя обозначает локальную переменную только для чтения, которая ссылается на vararg-таблицу. Если у vararg-таблицы нет имени, доступ к ней можно получить только через vararg-выражение.
Vararg-выражение также записывается как три точки, и его значением является список значений в vararg-таблице от 1 до целочисленного значения по индексу "n". (Следовательно, если код не изменяет vararg-таблицу, этот список соответствует дополнительным аргументам в вызове функции). Этот список ведет себя как результаты функции с множественными результатами (см. §3.4.12).
В качестве оптимизации, если vararg-таблица удовлетворяет некоторым условиям, код не создает фактическую таблицу, а вместо этого транслирует индексные выражения и vararg-выражения в доступы к внутренним данным vararg. Условия следующие: если у vararg-таблицы есть имя, это имя не является upvalue во вложенной функции, и оно используется только как базовая таблица в синтаксических конструкциях t[exp] или t.id. Обратите внимание, что анонимная vararg-таблица всегда удовлетворяет этим условиям.
3.4.12 – Списки выражений, множественные результаты и выравнивание
Как вызовы функций, так и vararg-выражения могут давать множественные значения. Эти выражения называются выражениями с множественными результатами (multires expressions).
Когда выражение с множественными результатами используется как последний элемент списка выражений, все результаты выражения добавляются к списку значений, создаваемому списком выражений. Обратите внимание, что одиночное выражение в месте, где ожидается список выражений, является последним выражением в этом (одноэлементном) списке.
Вот места, где Lua ожидает список выражений:
- Инструкция
return, например return e1,e2,e3 (см. §3.3.4). - Конструктор таблицы, например
{e1,e2,e3} (см. §3.4.9). - Аргументы вызова функции, например
foo(e1,e2,e3) (см. §3.4.10). - Множественное присваивание, например
a,b,c = e1,e2,e3 (см. §3.3.3). - Объявление
local или global, которое аналогично множественному присваиванию. - Начальные значения в обобщенном цикле
for, например for k in e1,e2,e3 do ... end (см. §3.3.5).
В последних четырех случаях список значений из списка выражений должен быть выровнен до определенной длины: количество параметров при вызове невариадической функции (см. §3.4.11), количество переменных в множественном присваивании или объявлении и ровно четыре значения для обобщенного цикла for. Выравнивание следует этим правилам: если значений больше, чем нужно, лишние значения отбрасываются; если значений меньше, чем нужно, список дополняется значениями nil. Когда список выражений заканчивается выражением с множественными результатами, все результаты этого выражения входят в список значений до выравнивания.
Когда выражение с множественными результатами используется в списке выражений, не будучи последним элементом, или в месте, где синтаксис ожидает одиночное выражение, Lua выравнивает список результатов этого выражения до одного элемента. Как частный случай, синтаксис ожидает одиночное выражение внутри выражения в скобках; следовательно, добавление скобок вокруг выражения с множественными результатами заставляет его выдавать ровно один результат.
Нам редко нужно использовать vararg-выражение в месте, где синтаксис ожидает одиночное выражение. (Обычно проще добавить обычный параметр перед вариадической частью и использовать этот параметр). Когда такая необходимость возникает, мы рекомендуем присвоить vararg-выражение одиночной переменной и использовать эту переменную вместо него.
Вот несколько примеров использования выражений с множественными результатами. Во всех случаях, когда конструкции нужен “n-й результат”, а такого результата нет, используется nil.
print(x, f()) -- печатает x и все результаты из f().
print(x, (f())) -- печатает x и первый результат из f().
print(f(), x) -- печатает первый результат из f() и x.
print(1 + f()) -- печатает 1, сложенную с первым результатом из f().
local x = ... -- x получает первый vararg-аргумент.
x,y = ... -- x получает первый vararg-аргумент,
-- y получает второй vararg-аргумент.
x,y,z = w, f() -- x получает w, y получает первый результат из f(),
-- z получает второй результат из f().
x,y,z = f() -- x получает первый результат из f(),
-- y получает второй результат из f(),
-- z получает третий результат из f().
x,y,z = f(), g() -- x получает первый результат из f(),
-- y получает первый результат из g(),
-- z получает второй результат из g().
x,y,z = (f()) -- x получает первый результат из f(), y и z получают nil.
return f() -- возвращает все результаты из f().
return x, ... -- возвращает x и все полученные vararg-аргументы.
return x,y,f() -- возвращает x, y и все результаты из f().
{f()} -- создает список со всеми результатами из f().
{...} -- создает список со всеми vararg-аргументами.
{f(), 5} -- создает список с первым результатом из f() и 5.
3 - 4 – Интерфейс прикладного программирования (API)
Полное описание C API для Lua: стек, функции, типы, обработка ошибок и отладочный интерфейс.
Оглавление
- Стек
- Замыкания C
- Реестр
- Обработка ошибок в C
- Обработка yield в C
- Функции и типы
- Отладочный интерфейс
4 – Интерфейс прикладного программирования
В этом разделе описывается C API для Lua, то есть набор функций C, доступных программе-хосту для взаимодействия с Lua. Все функции API и связанные с ними типы и константы объявлены в заголовочном файле lua.h.
Даже когда мы используем термин “функция”, любое средство в API может быть предоставлено в виде макроса. За исключением случаев, где указано иное, все такие макросы используют каждый из своих аргументов ровно один раз (кроме первого аргумента, который всегда является состоянием Lua), и поэтому не генерируют никаких скрытых побочных эффектов.
Как и в большинстве библиотек C, функции Lua API не проверяют свои аргументы на допустимость или согласованность. Однако вы можете изменить это поведение, скомпилировав Lua с определенным макросом LUA_USE_APICHECK.
Библиотека Lua полностью реентерабельна: у нее нет глобальных переменных. Она хранит всю необходимую информацию в динамической структуре, называемой состоянием Lua (Lua state).
Каждое состояние Lua имеет один или несколько потоков (threads), которые соответствуют независимым, кооперативным линиям выполнения. Тип lua_State (несмотря на свое имя) ссылается на поток. (Косвенно, через поток, он также ссылается на состояние Lua, связанное с потоком.)
Указатель на поток должен передаваться в качестве первого аргумента каждой функции в библиотеке, кроме lua_newstate, которая создает состояние Lua с нуля и возвращает указатель на главный поток в новом состоянии.
4.1 – Стек
Lua использует виртуальный стек для передачи значений в C и из C. Каждый элемент в этом стеке представляет значение Lua (nil, число, строка и т. д.). Функции в API могут обращаться к этому стеку через параметр состояния Lua, который они получают.
Всякий раз, когда Lua вызывает C, вызываемая функция получает новый стек, который независим от предыдущих стеков и от стеков функций C, которые все еще активны. Этот стек изначально содержит любые аргументы для функции C, и именно в нем функция C может хранить временные значения Lua и должна помещать свои результаты для возврата вызывающей стороне (см. lua_CFunction).
Для удобства большинство операций запроса в API не следуют строгой стековой дисциплине. Вместо этого они могут ссылаться на любой элемент в стеке, используя индекс: Положительный индекс представляет абсолютную позицию в стеке, начиная с 1 как дна стека; отрицательный индекс представляет смещение относительно вершины стека. Более конкретно, если в стеке n элементов, то индекс 1 представляет первый элемент (то есть элемент, который был помещен в стек первым), а индекс n представляет последний элемент; индекс -1 также представляет последний элемент (то есть элемент на вершине), а индекс -n представляет первый элемент.
4.1.1 – Размер стека
При взаимодействии с Lua API вы несете ответственность за обеспечение согласованности. В частности, вы отвечаете за контроль переполнения стека. При вызове любой функции API вы должны убедиться, что в стеке достаточно места для размещения результатов.
Из вышеуказанного правила есть одно исключение: когда вы вызываете функцию Lua без фиксированного количества результатов (см. lua_call), Lua гарантирует, что в стеке достаточно места для всех результатов. Однако она не гарантирует никакого дополнительного места. Поэтому перед тем, как помещать что-либо в стек после такого вызова, следует использовать lua_checkstack.
Всякий раз, когда Lua вызывает C, он гарантирует, что в стеке есть место как минимум для LUA_MINSTACK дополнительных элементов; то есть вы можете безопасно поместить в него до LUA_MINSTACK значений. LUA_MINSTACK определено как 20, так что обычно вам не нужно беспокоиться о пространстве стека, если только ваш код не содержит циклов, помещающих элементы в стек. При необходимости вы можете использовать функцию lua_checkstack, чтобы убедиться, что в стеке достаточно места для размещения новых элементов.
4.1.2 – Допустимые и приемлемые индексы
Любая функция в API, которая получает индексы стека, работает только с допустимыми индексами (valid indices) или приемлемыми индексами (acceptable indices).
Допустимый индекс — это индекс, который ссылается на позицию, хранящую изменяемое значение Lua. Он включает индексы стека между 1 и вершиной стека (1 ≤ abs(index) ≤ top) плюс псевдоиндексы, которые представляют некоторые позиции, доступные коду C, но не находящиеся в стеке. Псевдоиндексы используются для доступа к реестру (см. §4.3) и к upvalue функции C (см. §4.2).
Функции, которым не нужна конкретная изменяемая позиция, а только значение (например, функции запроса), могут вызываться с приемлемыми индексами. Приемлемый индекс может быть любым допустимым индексом, но также может быть любым положительным индексом после вершины стека в пределах пространства, выделенного для стека, то есть индексами вплоть до размера стека. (Обратите внимание, что 0 никогда не является приемлемым индексом.) Индексы к upvalue (см. §4.2), превышающие реальное количество upvalue в текущей функции C, также являются приемлемыми (но недопустимыми). За исключением случаев, когда указано иное, функции в API работают с приемлемыми индексами.
Приемлемые индексы служат для избежания дополнительных проверок вершины стека при запросе стека. Например, функция C может запросить свой третий аргумент без необходимости проверять, существует ли третий аргумент, то есть без необходимости проверять, является ли 3 допустимым индексом.
Для функций, которые могут вызываться с приемлемыми индексами, любой недопустимый индекс обрабатывается так, как если бы он содержал значение виртуального типа LUA_TNONE, которое ведет себя как значение nil.
4.1.3 – Указатели на строки
Несколько функций в API возвращают указатели (const char*) на строки Lua в стеке. (См. lua_pushfstring, lua_pushlstring, lua_pushstring и lua_tolstring. См. также luaL_checklstring, luaL_checkstring и luaL_tolstring во вспомогательной библиотеке.)
В общем случае сборщик мусора Lua может освобождать или перемещать память и, таким образом, делать недействительными указатели на строки, обрабатываемые состоянием Lua. Чтобы обеспечить безопасное использование этих указателей, API гарантирует, что любой указатель на строку в индексе стека действителен, пока строковое значение по этому индексу не удалено из стека. (Однако оно может быть перемещено на другой индекс). Когда индекс является псевдоиндексом (ссылающимся на upvalue), указатель действителен, пока активен соответствующий вызов и соответствующее upvalue не изменено.
Некоторые функции в отладочном интерфейсе также возвращают указатели на строки, а именно lua_getlocal, lua_getupvalue, lua_setlocal и lua_setupvalue. Для этих функций гарантируется, что указатель действителен, пока активна функция-вызыватель и данное замыкание (если оно было дано) находится в стеке.
За исключением этих гарантий, сборщик мусора может свободно делать недействительным любой указатель на внутренние строки.
4.2 – Замыкания C
При создании функции C с ней можно связать некоторые значения, создавая таким образом замыкание C (C closure) (см. lua_pushcclosure); эти значения называются upvalue и доступны функции при каждом ее вызове.
Всякий раз, когда вызывается функция C, ее upvalue располагаются по определенным псевдоиндексам. Эти псевдоиндексы создаются макросом lua_upvalueindex. Первое upvalue, связанное с функцией, находится по индексу lua_upvalueindex(1), и так далее. Любой доступ к lua_upvalueindex(n), где n больше количества upvalue текущей функции (но не больше 256, что на единицу больше максимального количества upvalue в замыкании), дает приемлемый, но недопустимый индекс.
Замыкание C также может изменять значения своих соответствующих upvalue.
4.3 – Реестр
Lua предоставляет реестр (registry) — предопределенную таблицу, которая может использоваться любым кодом C для хранения любых значений Lua, которые ему необходимо сохранить. Таблица реестра всегда доступна по псевдоиндексу LUA_REGISTRYINDEX. Любая библиотека C может хранить данные в этой таблице, но она должна позаботиться о выборе ключей, отличных от тех, что используются другими библиотеками, чтобы избежать коллизий. Обычно в качестве ключа следует использовать строку, содержащую имя вашей библиотеки, или легкий userdata с адресом объекта C в вашем коде, или любой объект Lua, созданный вашим кодом. Как и в случае с именами переменных, строковые ключи, начинающиеся с подчеркивания, за которым следуют заглавные буквы, зарезервированы для Lua.
Целочисленные ключи в реестре используются механизмом ссылок (см. luaL_ref) и имеют некоторые предопределенные значения. Поэтому целочисленные ключи в реестре не должны использоваться для других целей.
При создании нового состояния Lua его реестр содержит некоторые предопределенные значения. Эти предопределенные значения индексируются целочисленными ключами, определенными как константы в lua.h. Определены следующие константы:
LUA_RIDX_MAINTHREAD: По этому индексу в реестре находится главный поток состояния. (Главный поток — это тот, который создается вместе с состоянием).LUA_RIDX_GLOBALS: По этому индексу в реестре находится глобальное окружение.
4.4 – Обработка ошибок в C
Внутренне Lua использует средство C longjmp для обработки ошибок. (Lua будет использовать исключения, если вы компилируете его как C++; подробности ищите в исходном коде по LUAI_THROW). Когда Lua сталкивается с какой-либо ошибкой, такой как ошибка выделения памяти или ошибка типа, он возбуждает ошибку (raises an error); то есть выполняет длинный переход (long jump). Защищенное окружение использует setjmp для установки точки восстановления; любая ошибка переходит к самой последней активной точке восстановления.
Внутри функции C вы можете явно возбудить ошибку, вызвав lua_error.
Большинство функций в API могут возбуждать ошибки, например, из-за ошибки выделения памяти. Документация для каждой функции указывает, может ли она возбуждать ошибки.
Если ошибка происходит вне любого защищенного окружения, Lua вызывает функцию паники (panic function) (см. lua_atpanic), а затем вызывает abort, завершая таким образом хостовое приложение. Ваша функция паники может избежать этого завершения, никогда не возвращаясь (например, выполняя длинный переход к вашей собственной точке восстановления вне Lua).
Функция паники, как следует из ее названия, является механизмом “последней надежды”. Программы должны избегать ее. Как общее правило, когда функция C вызывается из Lua с состоянием Lua, она может делать с этим состоянием все, что угодно, так как оно уже должно быть защищено. Однако когда код C работает с другими состояниями Lua (например, аргумент-состояние Lua для функции, состояние Lua, сохраненное в реестре, или результат lua_newthread), он должен использовать их только в вызовах API, которые не могут возбуждать ошибки.
Функция паники работает так, как если бы она была обработчиком сообщений (см. §2.3); в частности, объект ошибки находится на вершине стека. Однако нет никаких гарантий относительно пространства стека. Чтобы поместить что-либо в стек, функция паники должна сначала проверить доступное пространство (см. §4.1.1).
4.4.1 – Коды состояния
Некоторые функции, сообщающие об ошибках в API, используют следующие коды состояния для указания различных видов ошибок или других условий:
LUA_OK (0): нет ошибок.LUA_ERRRUN: ошибка времени выполнения.LUA_ERRMEM: ошибка выделения памяти. Для таких ошибок Lua не вызывает обработчик сообщений.LUA_ERRERR: переполнение стека при выполнении обработчика сообщений из-за другого переполнения стека. Чаще всего эта ошибка является результатом какой-либо другой ошибки во время выполнения обработчика сообщений. Ошибка в обработчике сообщений вызовет обработчик снова, что снова сгенерирует ошибку, и так далее, пока этот цикл не исчерпает стек и не вызовет эту ошибку.LUA_ERRSYNTAX: синтаксическая ошибка во время предкомпиляции или ошибка формата в двоичном чанке.LUA_YIELD: поток (сопрограмма) выполняет yield.LUA_ERRFILE: ошибка, связанная с файлом; например, невозможно открыть или прочитать файл.
Эти константы определены в заголовочном файле lua.h.
4.5 – Обработка yield в C
Внутренне Lua использует средство C longjmp для выполнения yield в сопрограмме. Следовательно, если функция C foo вызывает функцию API, и эта функция API выполняет yield (прямо или косвенно, вызывая другую функцию, которая выполняет yield), Lua больше не может вернуться в foo, потому что longjmp удаляет ее фрейм из стека C.
Чтобы избежать подобной проблемы, Lua возбуждает ошибку всякий раз, когда пытается выполнить yield через вызов API, за исключением трех функций: lua_yieldk, lua_callk и lua_pcallk. Все эти функции получают функцию продолжения (continuation function) (в качестве параметра с именем k) для продолжения выполнения после yield.
Нам необходимо установить некоторую терминологию для объяснения продолжений. У нас есть функция C, вызванная из Lua, которую мы будем называть исходной функцией (original function). Эта исходная функция затем вызывает одну из этих трех функций в C API, которую мы будем называть вызываемой функцией (callee function), которая затем выполняет yield текущего потока. Это может произойти, когда вызываемая функция — lua_yieldk, или когда вызываемая функция — lua_callk либо lua_pcallk, и функция, вызываемая ими, выполняет yield.
Предположим, что выполняющийся поток делает yield во время выполнения вызываемой функции. После возобновления потока он в конечном итоге завершит выполнение вызываемой функции. Однако вызываемая функция не может вернуться в исходную функцию, потому что ее фрейм в стеке C был уничтожен при yield. Вместо этого Lua вызывает функцию продолжения, которая была передана в качестве аргумента вызываемой функции. Как следует из названия, функция продолжения должна продолжить задачу исходной функции.
В качестве иллюстрации рассмотрим следующую функцию:
int original_function (lua_State *L) {
... /* код 1 */
status = lua_pcall(L, n, m, h); /* вызывает Lua */
... /* код 2 */
}
Теперь мы хотим позволить коду Lua, выполняемому lua_pcall, делать yield. Во-первых, мы можем переписать нашу функцию следующим образом:
int k (lua_State *L, int status, lua_KContext ctx) {
... /* код 2 */
}
int original_function (lua_State *L) {
... /* код 1 */
return k(L, lua_pcall(L, n, m, h), ctx);
}
В приведенном выше коде новая функция k является функцией продолжения (с типом lua_KFunction), которая должна выполнять всю ту работу, которую исходная функция выполняла после вызова lua_pcall. Теперь мы должны сообщить Lua, что он должен вызвать k, если код Lua, выполняемый lua_pcall, будет прерван каким-либо образом (ошибки или yield), поэтому мы переписываем код следующим образом, заменяя lua_pcall на lua_pcallk:
int original_function (lua_State *L) {
... /* код 1 */
return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
}
Обратите внимание на внешний явный вызов продолжения: Lua вызовет продолжение только при необходимости, то есть в случае ошибок или возобновления после yield. Если вызываемая функция возвращается нормально, ни разу не выполнив yield, lua_pcallk (и lua_callk) также вернется нормально. (Конечно, вместо вызова продолжения в этом случае вы можете выполнить эквивалентную работу непосредственно внутри исходной функции).
Помимо состояния Lua, функция продолжения имеет два других параметра: окончательный статус вызова и значение контекста (ctx), которое было изначально передано в lua_pcallk. Lua не использует это значение контекста; он только передает это значение от исходной функции к функции продолжения. Для lua_pcallk статус — это то же значение, которое было бы возвращено lua_pcallk, за исключением того, что это LUA_YIELD при выполнении после yield (вместо LUA_OK). Для lua_yieldk и lua_callk статус всегда LUA_YIELD, когда Lua вызывает продолжение. (Для этих двух функций Lua не будет вызывать продолжение в случае ошибок, потому что они не обрабатывают ошибки). Аналогично, при использовании lua_callk вы должны вызвать функцию продолжения с LUA_OK в качестве статуса. (Для lua_yieldk нет особого смысла вызывать функцию продолжения напрямую, потому что lua_yieldk обычно не возвращается).
Lua обрабатывает функцию продолжения так, как если бы она была исходной функцией. Функция продолжения получает тот же стек Lua от исходной функции, в том же состоянии, в котором он был бы, если бы вызываемая функция вернулась. (Например, после lua_callk функция и ее аргументы удаляются из стека и заменяются результатами вызова). Она также имеет те же upvalue. Все, что она возвращает, обрабатывается Lua так, как если бы это был возврат исходной функции.
4.6 – Функции и типы
Здесь мы перечисляем все функции и типы из C API в алфавитном порядке. Каждая функция имеет индикатор вида: [-o, +p, x]
Первое поле, o, — сколько элементов функция извлекает из стека. Второе поле, p, — сколько элементов функция помещает в стек. (Любая функция всегда помещает свои результаты после извлечения своих аргументов.) Поле вида x|y означает, что функция может поместить (или извлечь) x или y элементов, в зависимости от ситуации; знак вопроса '?' означает, что мы не можем узнать, сколько элементов функция извлекает/помещает, глядя только на ее аргументы. (Например, это может зависеть от того, что находится в стеке). Третье поле, x, сообщает, может ли функция возбуждать ошибки: '-' означает, что функция никогда не возбуждает ошибок; 'm' означает, что функция может возбуждать только ошибки нехватки памяти; 'v' означает, что функция может возбуждать ошибки, объясненные в тексте; 'e' означает, что функция может выполнять произвольный код Lua, либо напрямую, либо через метаметоды, и поэтому может возбуждать любые ошибки.
lua_absindex
[-0, +0, –]
int lua_absindex (lua_State *L, int idx);
Преобразует приемлемый индекс idx в эквивалентный абсолютный индекс (то есть такой, который не зависит от размера стека).
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 — это размер блока, на который указывает ptr, то есть размер, указанный при его выделении или перераспределении.
Когда ptr равен NULL, osize кодирует тип объекта, который Lua выделяет. osize равен LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA или LUA_TTHREAD, когда (и только когда) Lua создает новый объект этого типа. Когда osize имеет какое-либо другое значение, Lua выделяет память для чего-то другого.
Lua предполагает следующее поведение от функции-аллокатора:
Когда nsize равно нулю, аллокатор должен вести себя как free и затем возвращать NULL.
Когда nsize не равно нулю, аллокатор должен вести себя как realloc. В частности, аллокатор возвращает NULL тогда и только тогда, когда он не может выполнить запрос.
Вот простая реализация функции-аллокатора, соответствующая функции luaL_alloc из вспомогательной библиотеки.
void *luaL_alloc (void *ud, void *ptr, size_t osize,
size_t nsize) {
(void)ud; (void)osize; /* не используется */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
Обратите внимание, что стандарт ISO C гарантирует, что free(NULL) не имеет эффекта, и что realloc(NULL,size) эквивалентно malloc(size).
lua_arith
[-(2|1), +1, e]
void lua_arith (lua_State *L, int op);
Выполняет арифметическую или побитовую операцию над двумя значениями (или одним, в случае отрицаний) на вершине стека, при этом значение на вершине является вторым операндом, извлекает эти значения и помещает результат операции в стек. Функция следует семантике соответствующего оператора Lua (то есть может вызывать метаметоды).
Значение op должно быть одной из следующих констант:
| Константа | Операция |
|---|
LUA_OPADD | сложение (+) |
LUA_OPSUB | вычитание (-) |
LUA_OPMUL | умножение (*) |
LUA_OPDIV | деление с плавающей запятой (/) |
LUA_OPIDIV | деление нацело вниз (//) |
LUA_OPMOD | остаток от деления (%) |
LUA_OPPOW | возведение в степень (^) |
LUA_OPUNM | унарный минус (унарный -) |
LUA_OPBNOT | побитовое НЕ (~) |
LUA_OPBAND | побитовое И (&) |
LUA_OPBOR | побитовое ИЛИ (|) |
LUA_OPBXOR | побитовое исключающее ИЛИ (~) |
LUA_OPSHL | сдвиг влево (<<) |
LUA_OPSHR | сдвиг вправо (>>) |
lua_atpanic
[-0, +0, –]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
Устанавливает новую функцию паники и возвращает старую (см. §4.4).
lua_call
[-(nargs+1), +nresults, e]
void lua_call (lua_State *L, int nargs, int nresults);
Вызывает функцию. Как и обычные вызовы Lua, lua_call учитывает метаметод __call. Таким образом, здесь слово “функция” означает любое вызываемое значение.
Для выполнения вызова необходимо использовать следующий протокол: сначала функция, которую нужно вызвать, помещается в стек; затем аргументы вызова помещаются в прямом порядке, то есть первый аргумент помещается первым. Наконец, вы вызываете lua_call; nargs — это количество аргументов, которое вы поместили в стек. Когда функция возвращается, все аргументы и значение функции извлекаются, а результаты вызова помещаются в стек. Количество результатов выравнивается до nresults, если только nresults не равно LUA_MULTRET, что приводит к помещению всех результатов функции. В первом случае (явное количество результатов) вызывающая сторона должна убедиться, что в стеке достаточно места для возвращаемых значений. Во втором случае (все результаты) Lua заботится о том, чтобы возвращаемые значения поместились в пространство стека, но не гарантирует никакого дополнительного места в стеке. Результаты функции помещаются в стек в прямом порядке (первый результат помещается первым), так что после вызова последний результат находится на вершине стека.
Максимальное значение для nresults — 250.
Любая ошибка при вызове и выполнении функции распространяется вверх (с помощью longjmp).
Следующий пример показывает, как программа-хост может выполнить эквивалент этого кода Lua:
Вот это на C:
lua_getglobal(L, "f"); /* функция для вызова */
lua_pushliteral(L, "how"); /* 1-й аргумент */
lua_getglobal(L, "t"); /* таблица для индексации */
lua_getfield(L, -1, "x"); /* поместить результат t.x (2-й аргумент) */
lua_remove(L, -2); /* удалить 't' из стека */
lua_pushinteger(L, 14); /* 3-й аргумент */
lua_call(L, 3, 1); /* вызвать 'f' с 3 аргументами и 1 результатом */
lua_setglobal(L, "a"); /* установить глобальную 'a' */
Обратите внимание, что приведенный выше код сбалансирован: в конце стек возвращается к своей исходной конфигурации. Это считается хорошей практикой программирования.
lua_callk
[-(nargs + 1), +nresults, e]
void lua_callk (lua_State *L,
int nargs,
int nresults,
lua_KContext ctx,
lua_KFunction k);
Эта функция ведет себя точно так же, как lua_call, но позволяет вызываемой функции выполнять yield (см. §4.5).
lua_CFunction
typedef int (*lua_CFunction) (lua_State *L);
Тип для функций C.
Чтобы правильно взаимодействовать с Lua, функция C должна использовать следующий протокол, который определяет способ передачи параметров и результатов: функция C получает свои аргументы от Lua в своем стеке в прямом порядке (первый аргумент помещается первым). Таким образом, когда функция запускается, lua_gettop(L) возвращает количество аргументов, полученных функцией. Первый аргумент (если есть) находится по индексу 1, а последний аргумент — по индексу lua_gettop(L). Чтобы вернуть значения в Lua, функция C просто помещает их в стек в прямом порядке (первый результат помещается первым) и возвращает в C количество результатов. Любые другие значения в стеке ниже результатов будут корректно отброшены Lua. Как и функция Lua, функция C, вызванная из Lua, также может возвращать много результатов.
В качестве примера, следующая функция получает переменное количество числовых аргументов и возвращает их среднее значение и сумму:
static int foo (lua_State *L) {
int n = lua_gettop(L); /* количество аргументов */
lua_Number sum = 0.0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushliteral(L, "неверный аргумент");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* первый результат */
lua_pushnumber(L, sum); /* второй результат */
return 2; /* количество результатов */
}
lua_checkstack
[-0, +0, –]
int lua_checkstack (lua_State *L, int n);
Гарантирует, что в стеке есть место как минимум для n дополнительных элементов, то есть что вы можете безопасно поместить в него до n значений. Возвращает false, если не может выполнить запрос, либо потому, что это привело бы к превышению фиксированного максимального размера стека (обычно не менее нескольких тысяч элементов), либо потому, что не может выделить память для дополнительного пространства. Эта функция никогда не уменьшает стек; если в стеке уже есть место для дополнительных элементов, он остается без изменений.
lua_close
[-0, +0, –]
void lua_close (lua_State *L);
Закрывает все активные закрываемые переменные (to-be-closed variables) в главном потоке, освобождает все объекты в данном состоянии Lua (вызывая соответствующие метаметоды сборки мусора, если таковые имеются) и освобождает всю динамическую память, используемую этим состоянием.
На некоторых платформах вам может не потребоваться вызывать эту функцию, потому что все ресурсы естественным образом освобождаются при завершении программы-хоста. С другой стороны, долго работающим программам, создающим несколько состояний, таким как демоны или веб-серверы, вероятно, потребуется закрывать состояния, как только они становятся ненужными.
lua_closeslot
[-0, +0, e]
void lua_closeslot (lua_State *L, int index);
Закрывает закрываемый слот (to-be-closed slot) по заданному индексу и устанавливает его значение в nil. Индекс должен быть последним индексом, ранее отмеченным для закрытия (см. lua_toclose), который все еще активен (то есть еще не закрыт).
Метаметод __close не может выполнять yield при вызове через эту функцию.
lua_closethread
[-0, +?, –]
int lua_closethread (lua_State *L, lua_State *from);
Сбрасывает поток, очищая его стек вызовов и закрывая все ожидающие закрываемые переменные. Параметр from представляет сопрограмму, которая сбрасывает L. Если такой сопрограммы нет, этот параметр может быть NULL.
Если L не равен from, вызов возвращает код состояния: LUA_OK при отсутствии ошибок в потоке (либо исходная ошибка, остановившая поток, либо ошибки в методах закрытия), или статус ошибки в противном случае. В случае ошибки объект ошибки помещается на вершину стека.
Если L равен from, это соответствует потоку, закрывающему сам себя. В этом случае вызов не возвращается; вместо этого возвращается resume, который (пере)запустил поток. Поток должен выполняться внутри resume.
lua_compare
[-0, +0, e]
int lua_compare (lua_State *L, int index1, int index2, int op);
Сравнивает два значения Lua. Возвращает 1, если значение по индексу index1 удовлетворяет условию op при сравнении со значением по индексу index2, следуя семантике соответствующего оператора Lua (то есть может вызывать метаметоды). В противном случае возвращает 0. Также возвращает 0, если какой-либо из индексов недействителен.
Значение op должно быть одной из следующих констант:
LUA_OPEQ: сравнение на равенство (==)LUA_OPLT: сравнение на меньше (<)LUA_OPLE: сравнение на меньше или равно (<=)
lua_concat
[-n, +1, e]
void lua_concat (lua_State *L, int n);
Конкатенирует n значений на вершине стека, извлекает их и оставляет результат на вершине. Если n равно 1, результатом является единственное значение в стеке (то есть функция ничего не делает); если n равно 0, результатом является пустая строка. Конкатенация выполняется в соответствии с обычной семантикой Lua (см. §3.4.6).
lua_copy
[-0, +0, –]
void lua_copy (lua_State *L, int fromidx, int toidx);
Копирует элемент по индексу fromidx в допустимый индекс toidx, заменяя значение в этой позиции. Значения в других позициях не затрагиваются.
lua_createtable
[-0, +1, m]
void lua_createtable (lua_State *L, int nseq, int nrec);
Создает новую пустую таблицу и помещает ее в стек. Параметр nseq — это подсказка о том, сколько элементов таблица будет иметь в качестве последовательности; параметр nrec — подсказка о том, сколько других элементов будет иметь таблица. Lua может использовать эти подсказки для предварительного выделения памяти для новой таблицы. Это предварительное выделение может помочь производительности, когда вы заранее знаете, сколько элементов будет в таблице. В противном случае следует использовать функцию lua_newtable.
lua_dump
[-0, +0, –]
int lua_dump (lua_State *L,
lua_Writer writer,
void *data,
int strip);
Дамп функции в виде двоичного чанка. Получает функцию Lua на вершине стека и создает двоичный чанк, который, будучи загруженным снова, дает функцию, эквивалентную дампнутой. По мере создания частей чанка lua_dump вызывает функцию writer (см. lua_Writer) с заданными data для их записи.
Функция lua_dump полностью сохраняет стек Lua при вызовах функции-писателя, за исключением того, что она может поместить некоторые значения для внутреннего использования перед первым вызовом и восстанавливает размер стека до исходного после последнего вызова.
Если strip истинно, двоичное представление может не включать всю отладочную информацию о функции для экономии места.
Возвращаемое значение — это код ошибки, возвращенный последним вызовом writer; 0 означает отсутствие ошибок.
lua_error
[-1, +0, v]
int lua_error (lua_State *L);
Возбуждает ошибку Lua, используя значение на вершине стека в качестве объекта ошибки. Эта функция выполняет длинный переход и, следовательно, никогда не возвращается (см. luaL_error).
lua_gc
[-0, +0, –]
int lua_gc (lua_State *L, int what, ...);
Управляет сборщиком мусора.
Эта функция выполняет несколько задач в зависимости от значения параметра what. Для опций, требующих дополнительных аргументов, они перечислены после опции.
LUA_GCCOLLECT: Выполняет полный цикл сборки мусора.LUA_GCSTOP: Останавливает сборщик мусора.LUA_GCRESTART: Перезапускает сборщик мусора.LUA_GCCOUNT: Возвращает текущий объем памяти (в Кбайтах), используемый Lua.LUA_GCCOUNTB: Возвращает остаток от деления текущего объема памяти в байтах, используемого Lua, на 1024.LUA_GCSTEP (size_t n): Выполняет шаг сборки мусора.LUA_GCISRUNNING: Возвращает булево значение, указывающее, работает ли сборщик (т.е. не остановлен).LUA_GCINC: Переключает сборщик в инкрементальный режим. Возвращает предыдущий режим (LUA_GCGEN или LUA_GCINC).LUA_GCGEN: Переключает сборщик в поколенческий режим. Возвращает предыдущий режим (LUA_GCGEN или LUA_GCINC).LUA_GCPARAM (int param, int val): Изменяет и/или возвращает значение параметра сборщика. Если val равно -1, вызов только возвращает текущее значение. Аргумент param должен иметь одно из следующих значений:LUA_GCPMINORMUL: Множитель minor.LUA_GCPMAJORMINOR: Множитель major-minor.LUA_GCPMINORMAJOR: Множитель minor-major.LUA_GCPPAUSE: Пауза сборщика мусора.LUA_GCPSTEPMUL: Множитель шага.LUA_GCPSTEPSIZE: Размер шага.
Для получения более подробной информации об этих опциях см. collectgarbage.
Эта функция не должна вызываться финализатором.
lua_getallocf
[-0, +0, –]
lua_Alloc lua_getallocf (lua_State *L, void **ud);
Возвращает функцию-аллокатор памяти для данного состояния. Если ud не NULL, Lua сохраняет в *ud непрозрачный указатель, переданный при установке функции-аллокатора.
lua_getfield
[-0, +1, e]
int lua_getfield (lua_State *L, int index, const char *k);
Помещает в стек значение t[k], где t — это значение по заданному индексу. Как и в Lua, эта функция может вызвать метаметод для события “index” (см. §2.4).
Возвращает тип помещенного значения.
[-0, +0, –]
void *lua_getextraspace (lua_State *L);
Возвращает указатель на область сырой памяти, связанную с данным состоянием Lua. Приложение может использовать эту область для любых целей; Lua не использует ее ни для чего.
Каждый новый поток имеет эту область, инициализированную копией области главного потока.
По умолчанию эта область имеет размер указателя на void, но вы можете перекомпилировать Lua с другим размером для этой области. (См. LUA_EXTRASPACE в luaconf.h).
lua_getglobal
[-0, +1, e]
int lua_getglobal (lua_State *L, const char *name);
Помещает в стек значение глобальной переменной name. Возвращает тип этого значения.
lua_geti
[-0, +1, e]
int lua_geti (lua_State *L, int index, lua_Integer i);
Помещает в стек значение t[i], где t — это значение по заданному индексу. Как и в Lua, эта функция может вызвать метаметод для события “index” (см. §2.4).
Возвращает тип помещенного значения.
[-0, +(0|1), –]
int lua_getmetatable (lua_State *L, int index);
Если значение по заданному индексу имеет метатаблицу, функция помещает эту метатаблицу в стек и возвращает 1. В противном случае функция возвращает 0 и ничего не помещает в стек.
lua_gettable
[-1, +1, e]
int lua_gettable (lua_State *L, int index);
Помещает в стек значение t[k], где t — это значение по заданному индексу, а k — значение на вершине стека.
Эта функция извлекает ключ из стека, помещая результирующее значение на его место. Как и в Lua, эта функция может вызвать метаметод для события “index” (см. §2.4).
Возвращает тип помещенного значения.
lua_gettop
[-0, +0, –]
int lua_gettop (lua_State *L);
Возвращает индекс верхнего элемента в стеке. Поскольку индексы начинаются с 1, этот результат равен количеству элементов в стеке; в частности, 0 означает пустой стек.
lua_getiuservalue
[-0, +1, –]
int lua_getiuservalue (lua_State *L, int index, int n);
Помещает в стек n-е пользовательское значение (user value), связанное с полным userdata по заданному индексу, и возвращает тип помещенного значения.
Если userdata не имеет такого значения, помещает nil и возвращает LUA_TNONE.
lua_insert
[-1, +1, –]
void lua_insert (lua_State *L, int index);
Перемещает верхний элемент в заданный допустимый индекс, сдвигая вверх элементы над этим индексом для освобождения места. Эта функция не может вызываться с псевдоиндексом, поскольку псевдоиндекс не является фактической позицией в стеке.
lua_Integer
Тип целых чисел в Lua.
По умолчанию этот тип — long long (обычно 64-битное целое число в дополнительном коде), но его можно изменить на long или int (обычно 32-битное целое число в дополнительном коде). (См. LUA_INT_TYPE в luaconf.h).
Lua также определяет константы LUA_MININTEGER и LUA_MAXINTEGER с минимальным и максимальным значениями, которые помещаются в этот тип.
lua_isboolean
[-0, +0, –]
int lua_isboolean (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является булевым, и 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_isinteger
[-0, +0, –]
int lua_isinteger (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является целым числом (то есть значение является числом и представлено как целое), и 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_isyieldable
[-0, +0, –]
int lua_isyieldable (lua_State *L);
Возвращает 1, если данная сопрограмма может выполнить yield, и 0 в противном случае.
lua_KContext
typedef ... lua_KContext;
Тип для контекстов функций продолжения. Должен быть числовым типом. Этот тип определен как intptr_t, когда intptr_t доступен, чтобы он мог хранить и указатели. В противном случае он определен как ptrdiff_t.
lua_KFunction
typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
Тип для функций продолжения (см. §4.5).
lua_len
[-0, +1, e]
void lua_len (lua_State *L, int index);
Возвращает длину значения по заданному индексу. Эквивалентно оператору # в Lua (см. §3.4.7) и может вызвать метаметод для события “length” (см. §2.4). Результат помещается в стек.
lua_load
[-0, +1, –]
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname,
const char *mode);
Загружает чанк Lua без его выполнения. Если ошибок нет, lua_load помещает скомпилированный чанк как функцию Lua на вершину стека. В противном случае она помещает сообщение об ошибке.
Функция lua_load использует предоставленную пользователем функцию-читатель (reader) для чтения чанка (см. lua_Reader). Аргумент data — это непрозрачное значение, передаваемое в функцию-читатель.
Аргумент chunkname дает имя чанку, которое используется для сообщений об ошибках и в отладочной информации (см. §4.7).
lua_load автоматически определяет, является ли чанк текстовым или двоичным, и загружает его соответствующим образом (см. программу luac). Строка mode работает как в функции load, с тем дополнением, что значение NULL эквивалентно строке "bt". Более того, она может содержать 'B' вместо 'b', что означает фиксированный буфер (fixed buffer) с двоичным дампом.
Фиксированный буфер означает, что адрес, возвращаемый функцией-читателем, будет содержать чанк до тех пор, пока все, созданное чанком, не будет собрано сборщиком мусора; таким образом, Lua может избежать копирования некоторых частей чанка во внутренние структуры. (В общем случае фиксированный буфер будет сохранять свое содержимое до конца программы, например, при чанке в ПЗУ). Более того, для фиксированного буфера функция-читатель должна вернуть весь чанк при первом чтении. (В качестве примера, luaL_loadbufferx делает это, что означает, что вы можете использовать ее для загрузки фиксированных буферов).
Функция lua_load полностью сохраняет стек Lua при вызовах функции-читателя, за исключением того, что она может поместить некоторые значения для внутреннего использования перед первым вызовом и восстанавливает размер стека до исходного размера плюс один (для помещенного результата) после последнего вызова.
lua_load может возвращать LUA_OK, LUA_ERRSYNTAX или LUA_ERRMEM. Функция также может возвращать другие значения, соответствующие ошибкам, возбужденным функцией чтения (см. §4.4.1).
Если результирующая функция имеет upvalue, ее первое upvalue устанавливается в значение глобального окружения, хранящееся по индексу LUA_RIDX_GLOBALS в реестре (см. §4.3). При загрузке главных чанков этим upvalue будет переменная _ENV (см. §2.2). Остальные upvalue инициализируются значением nil.
lua_newstate
[-0, +0, –]
lua_State *lua_newstate (lua_Alloc f, void *ud,
unsigned int seed);
Создает новое независимое состояние и возвращает его главный поток. Возвращает NULL, если не может создать состояние (из-за нехватки памяти). Аргумент f — это функция-аллокатор; Lua будет выполнять все выделение памяти для этого состояния через эту функцию (см. lua_Alloc). Второй аргумент, ud, — непрозрачный указатель, который Lua передает аллокатору при каждом вызове. Третий аргумент, seed, — это начальное значение для хеширования строк.
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_newuserdatauv
[-0, +1, m]
void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue);
Эта функция создает и помещает в стек новый полный userdata с nuvalue связанными значениями Lua, называемыми пользовательскими значениями (user values), плюс связанный блок сырой памяти размером size байт. (Пользовательские значения можно устанавливать и читать с помощью функций lua_setiuservalue и lua_getiuservalue).
Функция возвращает адрес блока памяти. Lua гарантирует, что этот адрес действителен, пока соответствующий userdata жив (см. §2.5). Более того, если userdata помечен для финализации (см. §2.5.3), его адрес действителен по крайней мере до вызова его финализатора.
lua_next
[-1, +(2|0), v]
int lua_next (lua_State *L, int index);
Извлекает ключ из стека и помещает пару ключ-значение из таблицы по заданному индексу — “следующую” пару после данного ключа. Если в таблице больше нет элементов, lua_next возвращает 0 и ничего не помещает.
Типичный обход таблицы выглядит так:
/* таблица находится в стеке по индексу 't' */
lua_pushnil(L); /* первый ключ */
while (lua_next(L, t) != 0) {
/* используем 'key' (по индексу -2) и 'value' (по индексу -1) */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* удаляем 'value'; сохраняем 'key' для следующей итерации */
lua_pop(L, 1);
}
При обходе таблицы избегайте вызова lua_tolstring непосредственно для ключа, если вы не уверены, что ключ действительно является строкой. Напомним, что lua_tolstring может изменить значение по заданному индексу; это собьет следующий вызов lua_next.
Эта функция может возбудить ошибку, если данный ключ не равен nil и не присутствует в таблице. См. функцию next для предостережений относительно модификации таблицы во время ее обхода.
lua_Number
Тип чисел с плавающей запятой в Lua.
По умолчанию этот тип — double, но его можно изменить на float или long double. (См. LUA_FLOAT_TYPE в luaconf.h).
lua_numbertointeger
int lua_numbertointeger (lua_Number n, lua_Integer *p);
Пытается преобразовать число Lua с плавающей запятой в целое число Lua; число n должно иметь целое значение. Если это значение находится в диапазоне целых чисел Lua, оно преобразуется в целое и присваивается *p. Макрос возвращает булево значение, указывающее, было ли преобразование успешным. (Обратите внимание, что эту проверку диапазона трудно выполнить корректно без этого макроса из-за округления).
Этот макрос может вычислять свои аргументы более одного раза.
lua_numbertocstring
[-0, +0, –]
unsigned lua_numbertocstring (lua_State *L, int idx,
char *buff);
Преобразует число по приемлемому индексу idx в строку и помещает результат в buff. Буфер должен иметь размер не менее LUA_N2SBUFFSZ байт. Преобразование следует неуказанному формату (см. §3.4.3). Функция возвращает количество байт, записанных в буфер (включая завершающий ноль), или ноль, если значение по idx не является числом.
lua_pcall
[-(nargs + 1), +(nresults|1), –]
int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
Вызывает функцию (или вызываемый объект) в защищенном режиме.
И nargs, и nresults имеют то же значение, что и в lua_call. Если во время вызова нет ошибок, lua_pcall ведет себя точно так же, как lua_call. Однако, если возникает какая-либо ошибка, lua_pcall перехватывает ее, помещает в стек единственное значение (объект ошибки) и возвращает код ошибки. Как и lua_call, lua_pcall всегда удаляет функцию и ее аргументы из стека.
Если msgh равно 0, то объект ошибки, возвращаемый в стеке, является в точности исходным объектом ошибки. В противном случае msgh — это индекс в стеке обработчика сообщений. (Этот индекс не может быть псевдоиндексом). В случае ошибок времени выполнения этот обработчик будет вызван с объектом ошибки, и его возвращаемое значение будет объектом, возвращенным в стеке функцией lua_pcall.
Обычно обработчик сообщений используется для добавления дополнительной отладочной информации к объекту ошибки, такой как трассировка стека. Такую информацию невозможно собрать после возврата lua_pcall, поскольку к тому времени стек уже свернут.
Функция lua_pcall возвращает один из следующих кодов состояния: LUA_OK, LUA_ERRRUN, LUA_ERRMEM или LUA_ERRERR.
lua_pcallk
[-(nargs + 1), +(nresults|1), –]
int lua_pcallk (lua_State *L,
int nargs,
int nresults,
int msgh,
lua_KContext ctx,
lua_KFunction k);
Эта функция ведет себя точно так же, как lua_pcall, за исключением того, что она позволяет вызываемой функции выполнять yield (см. §4.5).
lua_pop
[-n, +0, e]
void lua_pop (lua_State *L, int n);
Извлекает n элементов из стека. Реализован как макрос над lua_settop.
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 и помещает в стек значение Lua типа function, которое при вызове вызывает соответствующую функцию C. Параметр n сообщает, сколько upvalue будет у этой функции (см. §4.2).
Любая функция, вызываемая из Lua, должна следовать правильному протоколу для получения параметров и возврата результатов (см. lua_CFunction).
При создании функции C с ней можно связать некоторые значения, так называемые upvalue; эти upvalue затем доступны функции при каждом ее вызове. Эта связь называется замыканием C (см. §4.2). Чтобы создать замыкание C, сначала начальные значения для его upvalue должны быть помещены в стек. (Если upvalue несколько, первое значение помещается первым). Затем вызывается lua_pushcclosure для создания и помещения функции C в стек, при этом аргумент n сообщает, сколько значений будет связано с функцией. lua_pushcclosure также извлекает эти значения из стека.
Максимальное значение для n — 255.
Когда n равно нулю, эта функция создает легкую функцию C (light C function), которая является просто указателем на функцию C. В этом случае она никогда не вызывает ошибку памяти.
lua_pushcfunction
[-0, +1, –]
void lua_pushcfunction (lua_State *L, lua_CFunction f);
Помещает функцию C в стек. Эта функция эквивалентна lua_pushcclosure без upvalue.
lua_pushexternalstring
[-0, +1, m]
const char *lua_pushexternalstring (lua_State *L,
const char *s, size_t len, lua_Alloc falloc, void *ud);
Создает внешнюю строку (external string), то есть строку, использующую память, не управляемую Lua. Указатель s указывает на внешний буфер, содержащий содержимое строки, а len — это длина строки. Строка должна иметь ноль в конце, то есть должно выполняться условие s[len] == '\0'. Как и для любой строки в Lua, длина должна помещаться в целое число Lua.
Если falloc отличается от NULL, эта функция будет вызвана Lua, когда внешний буфер больше не нужен. Содержимое буфера не должно изменяться до этого вызова. Функция будет вызвана с заданным ud, строкой s в качестве блока, длиной плюс один (для учета завершающего нуля) в качестве старого размера и 0 в качестве нового размера.
Даже при использовании внешнего буфера Lua все равно должен выделить заголовок для строки. В случае ошибки выделения памяти Lua вызовет falloc перед возбуждением ошибки.
Функция возвращает указатель на строку (то есть s).
lua_pushfstring
[-0, +1, v]
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
Помещает в стек форматированную строку и возвращает указатель на эту строку (см. §4.1.3). Результат — это копия fmt, в которой каждый спецификатор преобразования заменен строковым представлением соответствующего дополнительного аргумента. Спецификатор преобразования (и соответствующий ему дополнительный аргумент) может быть: '%%' (вставляет символ '%'), '%s' (вставляет строку с завершающим нулем, без ограничений по размеру), '%f' (вставляет lua_Number), '%I' (вставляет lua_Integer), '%p' (вставляет указатель void*), '%d' (вставляет int), '%c' (вставляет int как однобайтовый символ) и '%U' (вставляет unsigned long как последовательность байт UTF-8).
Каждое вхождение '%' в строке fmt должно образовывать допустимый спецификатор преобразования.
Помимо ошибок выделения памяти, эта функция может возбудить ошибку, если результирующая строка слишком велика.
lua_pushglobaltable
[-0, +1, –]
void lua_pushglobaltable (lua_State *L);
Помещает глобальное окружение в стек.
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);
Помещает легкий userdata в стек.
Userdata представляют значения C в Lua. Легкий userdata представляет указатель, void*. Это значение (как число): вы его не создаете, у него нет индивидуальной метатаблицы, и оно не собирается сборщиком мусора (поскольку никогда не создавалось). Легкий userdata равен “любому” легкому userdata с тем же адресом C.
lua_pushliteral
[-0, +1, v]
const char *lua_pushliteral (lua_State *L, const char *s);
Этот макрос эквивалентен lua_pushstring, но должен использоваться только тогда, когда s является литеральной строкой. (Lua может оптимизировать этот случай).
lua_pushlstring
[-0, +1, v]
const char *lua_pushlstring (lua_State *L, const char *s, size_t len);
Помещает строку, на которую указывает s, размером len, в стек. Lua создаст или повторно использует внутреннюю копию данной строки, так что память по адресу s может быть освобождена или повторно использована сразу после возврата функции. Строка может содержать любые двоичные данные, включая встроенные нули.
Возвращает указатель на внутреннюю копию строки (см. §4.1.3).
Помимо ошибок выделения памяти, эта функция может возбудить ошибку, если строка слишком велика.
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]
const char *lua_pushstring (lua_State *L, const char *s);
Помещает строку с завершающим нулем, на которую указывает s, в стек. Lua создаст или повторно использует внутреннюю копию данной строки, так что память по адресу s может быть освобождена или повторно использована сразу после возврата функции.
Возвращает указатель на внутреннюю копию строки (см. §4.1.3).
Если s равен NULL, помещает nil и возвращает NULL.
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, –]
const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp);
Эквивалентно lua_pushfstring, за исключением того, что получает va_list вместо переменного количества аргументов и не возбуждает ошибок. Вместо этого в случае ошибок помещает сообщение об ошибке и возвращает NULL.
lua_rawequal
[-0, +0, –]
int lua_rawequal (lua_State *L, int index1, int index2);
Возвращает 1, если два значения по индексам index1 и index2 примитивно равны (то есть равны без вызова метаметода __eq). В противном случае возвращает 0. Также возвращает 0, если какой-либо из индексов недействителен.
lua_rawget
[-1, +1, –]
int lua_rawget (lua_State *L, int index);
Аналогично lua_gettable, но выполняет сырой доступ (т.е. без метаметодов). Значение по индексу index должно быть таблицей.
lua_rawgeti
[-0, +1, –]
int lua_rawgeti (lua_State *L, int index, lua_Integer n);
Помещает в стек значение t[n], где t — таблица по заданному индексу. Доступ сырой, то есть не использует метазначение __index.
Возвращает тип помещенного значения.
lua_rawgetp
[-0, +1, –]
int lua_rawgetp (lua_State *L, int index, const void *p);
Помещает в стек значение t[k], где t — таблица по заданному индексу, а k — указатель p, представленный как легкий userdata. Доступ сырой, то есть не использует метазначение __index.
Возвращает тип помещенного значения.
lua_rawlen
[-0, +0, –]
lua_Unsigned lua_rawlen (lua_State *L, int index);
Возвращает сырую “длину” значения по заданному индексу: для строк это длина строки; для таблиц это результат оператора длины (#) без метаметодов; для userdata это размер блока памяти, выделенного для userdata. Для других значений этот вызов возвращает 0.
lua_rawset
[-2, +0, m]
void lua_rawset (lua_State *L, int index);
Аналогично lua_settable, но выполняет сырое присваивание (т.е. без метаметодов). Значение по индексу index должно быть таблицей.
lua_rawseti
[-1, +0, m]
void lua_rawseti (lua_State *L, int index, lua_Integer i);
Выполняет эквивалент t[i] = v, где t — таблица по заданному индексу, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Присваивание сырое, то есть не использует метазначение __newindex.
lua_rawsetp
[-1, +0, m]
void lua_rawsetp (lua_State *L, int index, const void *p);
Выполняет эквивалент t[p] = v, где t — таблица по заданному индексу, p закодировано как легкий userdata, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Присваивание сырое, то есть не использует метазначение __newindex.
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, lua_State *from, int nargs,
int *nresults);
Запускает и возобновляет сопрограмму в заданном потоке L.
Чтобы запустить сопрограмму, вы помещаете главную функцию и все аргументы в пустой стек потока, затем вызываете lua_resume, где nargs — количество аргументов. Функция возвращается, когда сопрограмма приостанавливается, завершает свое выполнение или возбуждает незащищенную ошибку. Когда она возвращается без ошибок, *nresults обновляется, и вершина стека содержит *nresults значений, переданных в lua_yield или возвращенных функцией тела. lua_resume возвращает LUA_YIELD, если сопрограмма выполняет yield, LUA_OK, если сопрограмма завершает выполнение без ошибок, или код ошибки в случае ошибок (см. §4.4.1). В случае ошибок объект ошибки помещается на вершину стека. (В этом случае nresults не обновляется, так как его значение должно было бы быть 1 для единственного объекта ошибки).
Чтобы возобновить приостановленную сопрограмму, вы удаляете *nresults значений, возвращенных yield, из ее стека, помещаете значения, которые будут переданы как результаты из yield, а затем вызываете lua_resume.
Параметр from представляет сопрограмму, которая возобновляет L. Если такой сопрограммы нет, этот параметр может быть NULL.
lua_rotate
[-0, +0, –]
void lua_rotate (lua_State *L, int idx, int n);
Вращает элементы стека между допустимым индексом idx и вершиной стека. Элементы вращаются на n позиций в направлении вершины для положительного n или на -n позиций в направлении дна для отрицательного n. Абсолютное значение n не должно превышать размер вращаемого среза. Эта функция не может вызываться с псевдоиндексом, поскольку псевдоиндекс не является фактической позицией в стеке.
lua_setallocf
[-0, +0, –]
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
Изменяет функцию-аллокатор данного состояния на f с пользовательскими данными ud.
lua_setfield
[-1, +0, e]
void lua_setfield (lua_State *L, int index, const char *k);
Выполняет эквивалент t[k] = v, где t — значение по заданному индексу, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Как и в Lua, эта функция может вызвать метаметод для события “newindex” (см. §2.4).
lua_setglobal
[-1, +0, e]
void lua_setglobal (lua_State *L, const char *name);
Извлекает значение из стека и устанавливает его как новое значение глобальной переменной name.
lua_seti
[-1, +0, e]
void lua_seti (lua_State *L, int index, lua_Integer n);
Выполняет эквивалент t[n] = v, где t — значение по заданному индексу, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Как и в Lua, эта функция может вызвать метаметод для события “newindex” (см. §2.4).
lua_setiuservalue
[-1, +0, –]
int lua_setiuservalue (lua_State *L, int index, int n);
Извлекает значение из стека и устанавливает его как новое n-е пользовательское значение, связанное с полным userdata по заданному индексу. Возвращает 0, если userdata не имеет такого значения.
[-1, +0, –]
int lua_setmetatable (lua_State *L, int index);
Извлекает таблицу или nil из стека и устанавливает это значение как новую метатаблицу для значения по заданному индексу. (nil означает отсутствие метатаблицы).
(По историческим причинам эта функция возвращает int, который теперь всегда равен 1).
lua_settable
[-2, +0, e]
void lua_settable (lua_State *L, int index);
Выполняет эквивалент t[k] = v, где t — значение по заданному индексу, v — значение на вершине стека, а k — значение непосредственно под вершиной.
Эта функция извлекает и ключ, и значение из стека. Как и в Lua, эта функция может вызвать метаметод для события “newindex” (см. §2.4).
lua_settop
[-?, +?, e]
void lua_settop (lua_State *L, int index);
Принимает любой приемлемый индекс стека или 0 и устанавливает вершину стека в этот индекс. Если новая вершина больше старой, то новые элементы заполняются значением nil. Если index равен 0, то все элементы стека удаляются.
Эта функция может выполнять произвольный код при удалении из стека индекса, помеченного как закрываемый (to-be-closed).
lua_setwarnf
[-0, +0, –]
void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud);
Устанавливает функцию предупреждения, используемую Lua для выдачи предупреждений (см. lua_WarnFunction). Параметр ud устанавливает значение ud, передаваемое в функцию предупреждения.
lua_State
typedef struct lua_State lua_State;
Непрозрачная структура, которая указывает на поток и косвенно (через поток) на все состояние интерпретатора Lua. Библиотека Lua полностью реентерабельна: у нее нет глобальных переменных. Вся информация о состоянии доступна через эту структуру.
Указатель на эту структуру должен передаваться в качестве первого аргумента каждой функции в библиотеке, кроме lua_newstate, которая создает состояние Lua с нуля.
lua_status
[-0, +0, –]
int lua_status (lua_State *L);
Возвращает статус потока L.
Статус может быть LUA_OK для нормального потока, кодом ошибки, если поток завершил выполнение lua_resume с ошибкой, или LUA_YIELD, если поток приостановлен.
Вы можете вызывать функции только в потоках со статусом LUA_OK. Вы можете возобновлять потоки со статусом LUA_OK (для запуска новой сопрограммы) или LUA_YIELD (для возобновления сопрограммы).
lua_stringtonumber
[-0, +1, –]
size_t lua_stringtonumber (lua_State *L, const char *s);
Преобразует строку с завершающим нулем s в число, помещает это число в стек и возвращает общий размер строки, то есть ее длину плюс один. Преобразование может дать целое число или число с плавающей запятой в соответствии с лексическими соглашениями Lua (см. §3.1). Строка может иметь начальные и конечные пробелы и знак. Если строка не является допустимым числом, возвращает 0 и ничего не помещает. (Обратите внимание, что результат можно использовать как булево значение, true, если преобразование успешно).
lua_toboolean
[-0, +0, –]
int lua_toboolean (lua_State *L, int index);
Преобразует значение Lua по заданному индексу в булево значение C (0 или 1). Как и все проверки в Lua, lua_toboolean возвращает true для любого значения Lua, отличного от false и nil; в противном случае возвращает false. (Если вы хотите принимать только фактические булевы значения, используйте lua_isboolean для проверки типа значения).
lua_tocfunction
[-0, +0, –]
lua_CFunction lua_tocfunction (lua_State *L, int index);
Преобразует значение по заданному индексу в функцию C. Это значение должно быть функцией C; в противном случае возвращает NULL.
lua_toclose
[-0, +0, v]
void lua_toclose (lua_State *L, int index);
Помечает заданный индекс в стеке как закрываемый слот (to-be-closed slot) (см. §3.3.8). Как и закрываемая переменная в Lua, значение в этом слоте стека будет закрыто, когда оно выйдет из области видимости. Здесь, в контексте функции C, “выйти из области видимости” означает, что выполняющаяся функция возвращается в Lua, или происходит ошибка, или слот удаляется из стека через lua_settop или lua_pop, или происходит вызов lua_closeslot. Слот, помеченный как закрываемый, не должен удаляться из стека никакой другой функцией API, кроме lua_settop или lua_pop, если только он предварительно не деактивирован вызовом lua_closeslot.
Эта функция возбуждает ошибку, если значение в заданном слоте не имеет метаметода __close и не является ложным значением.
Эту функцию не следует вызывать для индекса, который равен или находится ниже активного закрываемого слота.
Обратите внимание, что как в случае ошибок, так и при обычном возврате, к моменту выполнения метаметода __close стек C уже свернут, так что любые автоматические переменные C, объявленные в вызывающей функции (например, буфер), будут вне области видимости.
lua_tointeger
[-0, +0, –]
lua_Integer lua_tointeger (lua_State *L, int index);
Эквивалентно lua_tointegerx с isnum, равным NULL.
lua_tointegerx
[-0, +0, –]
lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);
Преобразует значение Lua по заданному индексу в знаковый целочисленный тип lua_Integer. Значение Lua должно быть целым числом, или числом, или строкой, преобразуемой в целое число (см. §3.4.3); в противном случае lua_tointegerx возвращает 0.
Если isnum не NULL, по его ссылке присваивается булево значение, указывающее, успешно ли выполнена операция.
lua_tolstring
[-0, +0, m]
const char *lua_tolstring (lua_State *L, int index, size_t *len);
Преобразует значение Lua по заданному индексу в строку C. Значение Lua должно быть строкой или числом; в противном случае функция возвращает NULL. Если значение — число, то lua_tolstring также изменяет фактическое значение в стеке на строку. (Это изменение сбивает lua_next, когда lua_tolstring применяется к ключам во время обхода таблицы).
Если len не NULL, функция устанавливает *len в длину строки. Возвращаемая строка C всегда имеет ноль ('\0') после своего последнего символа, но может содержать другие нули в своем теле.
Указатель, возвращаемый lua_tolstring, может быть признан недействительным сборщиком мусора, если соответствующее значение Lua удалено из стека (см. §4.1.3).
Эта функция может вызывать ошибки памяти только при преобразовании числа в строку (поскольку в этом случае она может создать новую строку).
lua_tonumber
[-0, +0, –]
lua_Number lua_tonumber (lua_State *L, int index);
Эквивалентно lua_tonumberx с isnum, равным NULL.
lua_tonumberx
[-0, +0, –]
lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);
Преобразует значение Lua по заданному индексу в тип C lua_Number (см. lua_Number). Значение Lua должно быть числом или строкой, преобразуемой в число (см. §3.4.3); в противном случае lua_tonumberx возвращает 0.
Если isnum не NULL, по его ссылке присваивается булево значение, указывающее, успешно ли выполнена операция.
lua_topointer
[-0, +0, –]
const void *lua_topointer (lua_State *L, int index);
Преобразует значение по заданному индексу в обобщенный указатель C (void*). Значение может быть userdata, таблицей, потоком, строкой или функцией; в противном случае 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);
Если значение по заданному индексу является полным userdata, возвращает адрес его блока памяти. Если значение — легкий userdata, возвращает его значение (указатель). В противном случае возвращает 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_Unsigned
typedef ... lua_Unsigned;
Беззнаковая версия lua_Integer.
lua_upvalueindex
[-0, +0, –]
int lua_upvalueindex (int i);
Возвращает псевдоиндекс, представляющий i-е upvalue выполняющейся функции (см. §4.2). i должно быть в диапазоне [1,256].
lua_version
[-0, +0, –]
lua_Number lua_version (lua_State *L);
Возвращает номер версии данного ядра.
lua_WarnFunction
typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
Тип функций предупреждения, вызываемых Lua для выдачи предупреждений. Первый параметр — непрозрачный указатель, установленный lua_setwarnf. Второй параметр — сообщение предупреждения. Третий параметр — булево значение, указывающее, будет ли сообщение продолжено сообщением в следующем вызове.
См. warn для получения дополнительной информации о предупреждениях.
lua_warning
[-0, +0, –]
void lua_warning (lua_State *L, const char *msg, int tocont);
Выдает предупреждение с заданным сообщением. Сообщение в вызове с tocont равным true должно быть продолжено в другом вызове этой функции.
См. warn для получения дополнительной информации о предупреждениях.
lua_Writer
typedef int (*lua_Writer) (lua_State *L,
const void* p,
size_t sz,
void* ud);
Тип функции-писателя, используемой lua_dump. Каждый раз, когда lua_dump создает очередную часть чанка, она вызывает писатель, передавая буфер для записи (p), его размер (sz) и параметр ud, переданный в lua_dump.
После того как lua_dump запишет свою последнюю часть, она сигнализирует об этом, вызывая функцию-писатель еще один раз с буфером NULL (и размером 0).
Писатель возвращает код ошибки: 0 означает отсутствие ошибок; любое другое значение означает ошибку и останавливает lua_dump от дальнейших вызовов писателя.
lua_xmove
[-?, +?, –]
void lua_xmove (lua_State *from, lua_State *to, int n);
Обменивает значения между разными потоками одного и того же состояния.
Эта функция извлекает n значений из стека from и помещает их в стек to.
lua_yield
[-?, +?, v]
int lua_yield (lua_State *L, int nresults);
Эта функция эквивалентна lua_yieldk, но не имеет продолжения (см. §4.5). Следовательно, когда поток возобновляется, он продолжает функцию, которая вызвала функцию, вызывающую lua_yield. Во избежание неожиданностей эту функцию следует вызывать только в хвостовом вызове.
lua_yieldk
[-?, +?, v]
int lua_yieldk (lua_State *L,
int nresults,
lua_KContext ctx,
lua_KFunction k);
Выполняет yield сопрограммы (потока).
Когда функция C вызывает lua_yieldk, выполняющаяся сопрограмма приостанавливает свое выполнение, и вызов lua_resume, запустивший эту сопрограмму, возвращается. Параметр nresults — это количество значений из стека, которые будут переданы как результаты в lua_resume.
Когда сопрограмма возобновляется снова, Lua вызывает заданную функцию продолжения k для продолжения выполнения функции C, которая выполнила yield (см. §4.5). Эта функция продолжения получает тот же стек, что и предыдущая функция, с удаленными n результатами и замененными аргументами, переданными в lua_resume. Более того, функция продолжения получает значение ctx, которое было передано в lua_yieldk.
Обычно эта функция не возвращается; когда сопрограмма в конечном итоге возобновляется, она продолжает выполнение функции продолжения. Однако есть один особый случай: когда эта функция вызывается изнутри хука строки или счетчика (см. §4.7). В этом случае lua_yieldk должна вызываться без продолжения (вероятно, в форме lua_yield) и без результатов, а хук должен возвращаться немедленно после вызова. Lua выполнит yield, и, когда сопрограмма снова возобновится, она продолжит нормальное выполнение функции (Lua), которая вызвала хук.
Эта функция может возбудить ошибку, если она вызывается из потока с ожидающим вызовом C без функции продолжения (то, что называется границей C-вызова), или если она вызывается из потока, который не выполняется внутри resume (обычно главный поток).
4.7 – Отладочный интерфейс
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) */
size_t srclen; /* (S) */
int currentline; /* (l) */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
unsigned char nups; /* (u) количество upvalue */
unsigned char nparams; /* (u) количество параметров */
char isvararg; /* (u) */
unsigned char extraargs; /* (t) количество дополнительных аргументов */
char istailcall; /* (t) */
int ftransfer; /* (r) индекс первого передаваемого значения */
int ntransfer; /* (r) количество передаваемых значений */
char short_src[LUA_IDSIZE]; /* (S) */
/* приватная часть */
другие поля
} lua_Debug;
Структура, используемая для переноса различных фрагментов информации о функции или записи активации. lua_getstack заполняет только приватную часть этой структуры для последующего использования. Чтобы заполнить другие поля lua_Debug полезной информацией, необходимо вызвать lua_getinfo с соответствующим параметром. (В частности, чтобы получить поле, необходимо добавить букву в скобках в комментарии к полю в параметр what функции lua_getinfo.)
Поля lua_Debug имеют следующее значение:
source: источник чанка, создавшего функцию. Если source начинается с '@', это означает, что функция была определена в файле, имя которого следует за '@'. Если source начинается с '=', остальная часть его содержимого описывает источник способом, зависящим от пользователя. В противном случае функция была определена в строке, где source и есть эта строка.srclen: Длина строки source.short_src: “печатная” версия source для использования в сообщениях об ошибках.linedefined: номер строки, с которой начинается определение функции.lastlinedefined: номер строки, на которой заканчивается определение функции.what: строка "Lua", если функция Lua, "C", если функция C, "main", если это главная часть чанка.currentline: текущая строка, в которой выполняется данная функция. Когда информация о строке недоступна, currentline устанавливается в -1.name: подходящее имя для данной функции. Поскольку функции в Lua являются значениями первого класса, у них нет фиксированного имени: некоторые функции могут быть значением нескольких глобальных переменных, в то время как другие могут храниться только в поле таблицы. Функция lua_getinfo проверяет, как была вызвана функция, чтобы найти подходящее имя. Если она не может найти имя, то name устанавливается в NULL.namewhat: объясняет поле name. Значение namewhat может быть "global", "local", "upvalue", "field", "" (пустая строка) плюс некоторые другие варианты, в зависимости от того, как была вызвана функция. (Lua использует пустую строку, когда ни один другой вариант не подходит).istailcall: true, если этот вызов функции был сделан через хвостовой вызов. В этом случае вызыватель этого уровня отсутствует в стеке.extraargs: Количество дополнительных аргументов, добавленных при вызове функций через метаметоды __call. (Каждое метазначение __call добавляет один дополнительный аргумент — вызываемый объект, но может быть цепочка метазначений __call).nups: количество upvalue функции.nparams: количество параметров функции (всегда 0 для функций C).isvararg: true, если функция вариадическая (всегда true для функций C).ftransfer: индекс в стеке первого “передаваемого” значения, то есть параметров при вызове или возвращаемых значений при возврате. (Остальные значения находятся в последовательных индексах). Используя этот индекс, вы можете получать и изменять эти значения через lua_getlocal и lua_setlocal. Это поле имеет значение только во время хука вызова, обозначая первый параметр, или хука возврата, обозначая первое возвращаемое значение. (Для хуков вызова это значение всегда равно 1).ntransfer: Количество передаваемых значений (см. предыдущий пункт). (Для вызовов функций Lua это значение всегда равно nparams).
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_getglobal(L, "f"); /* получить глобальную 'f' */
lua_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined);
Каждый символ в строке what выбирает некоторые поля структуры ar для заполнения или значение для помещения в стек. (Эти символы также задокументированы в объявлении структуры lua_Debug, в скобках в комментариях после каждого поля).
'f': помещает в стек функцию, которая выполняется на данном уровне;'l': заполняет поле currentline;'n': заполняет поля name и namewhat;'r': заполняет поля ftransfer и ntransfer;'S': заполняет поля source, short_src, linedefined, lastlinedefined и what;'t': заполняет поля istailcall и extraargs;'u': заполняет поля nups, nparams и isvararg;'L': помещает в стек таблицу, индексами которой являются строки в функции с некоторым ассоциированным кодом, то есть строки, в которых можно поставить точку останова. (Строки без кода включают пустые строки и комментарии). Если эта опция дана вместе с опцией 'f', ее таблица помещается после функции. Это единственная опция, которая может вызвать ошибку памяти.
Эта функция возвращает 0, чтобы сигнализировать о недопустимой опции в what; даже в этом случае допустимые опции обрабатываются корректно.
lua_getlocal
[-0, +(0|1), –]
const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
Получает информацию о локальной переменной или временном значении заданной записи активации или заданной функции.
В первом случае параметр ar должен быть действительной записью активации, которая была заполнена предыдущим вызовом lua_getstack или передана в качестве аргумента хуку (см. lua_Hook). Индекс n выбирает, какую локальную переменную инспектировать; подробности об индексах и именах переменных см. в debug.getlocal.
lua_getlocal помещает значение переменной в стек и возвращает ее имя.
Во втором случае ar должен быть NULL, а инспектируемая функция должна находиться на вершине стека. В этом случае видны только параметры функций Lua (поскольку нет информации о том, какие переменные активны), и значения в стек не помещаются.
Возвращает NULL (и ничего не помещает), когда индекс больше количества активных локальных переменных.
lua_getstack
[-0, +0, –]
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
Получает информацию о стеке времени выполнения интерпретатора.
Эта функция заполняет части структуры lua_Debug идентификацией записи активации функции, выполняющейся на заданном уровне. Уровень 0 — это текущая выполняющаяся функция, тогда как уровень n+1 — это функция, которая вызвала уровень n (за исключением хвостовых вызовов, которые не учитываются в стеке). При вызове с уровнем, превышающим глубину стека, lua_getstack возвращает 0; в противном случае возвращает 1.
lua_getupvalue
[-0, +(0|1), –]
const char *lua_getupvalue (lua_State *L, int funcindex, int n);
Получает информацию об n-м upvalue замыкания по индексу funcindex. Помещает значение upvalue в стек и возвращает его имя. Возвращает NULL (и ничего не помещает), когда индекс n больше количества upvalue.
Дополнительную информацию об upvalue см. в debug.getupvalue.
lua_Hook
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
Тип для отладочных функций хука.
Всякий раз, когда вызывается хук, его аргумент ar имеет поле event, установленное в конкретное событие, которое вызвало хук. Lua идентифицирует эти события следующими константами: LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKTAILCALL, LUA_HOOKLINE и LUA_HOOKCOUNT. Более того, для событий строки также устанавливается поле currentline. Чтобы получить значение любого другого поля в ar, хук должен вызвать lua_getinfo.
Для событий вызова event может быть LUA_HOOKCALL (обычное значение) или LUA_HOOKTAILCALL (для хвостового вызова); в этом случае не будет соответствующего события возврата.
Пока Lua выполняет хук, он отключает другие вызовы хуков. Следовательно, если хук вызывает обратно в Lua для выполнения функции или чанка, это выполнение происходит без каких-либо вызовов хуков.
Функции хуков не могут иметь продолжений, то есть они не могут вызывать lua_yieldk, lua_pcallk или lua_callk с не-null k.
Функции хуков могут выполнять yield при следующих условиях: Только события счетчика и строки могут выполнять yield; чтобы выполнить yield, функция хука должна завершить свое выполнение вызовом lua_yield с nresults, равным нулю (то есть без значений).
lua_sethook
[-0, +0, –]
void 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 функции Lua.
- Хук счетчика: вызывается после того, как интерпретатор выполняет каждые
count инструкций. Это событие происходит только во время выполнения Lua функции Lua.
Хуки отключаются установкой mask в ноль.
lua_setlocal
[-(0|1), +0, –]
const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
Устанавливает значение локальной переменной заданной записи активации. Присваивает значение на вершине стека переменной и возвращает ее имя. Также извлекает значение из стека.
Возвращает NULL (и ничего не извлекает), когда индекс больше количества активных локальных переменных.
Параметры ar и n такие же, как в функции lua_getlocal.
lua_setupvalue
[-(0|1), +0, –]
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
Устанавливает значение upvalue замыкания. Присваивает значение на вершине стека upvalue и возвращает его имя. Также извлекает значение из стека.
Возвращает NULL (и ничего не извлекает), когда индекс n больше количества upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue.
lua_upvalueid
[-0, +0, –]
void *lua_upvalueid (lua_State *L, int funcindex, int n);
Возвращает уникальный идентификатор для upvalue с номером n из замыкания по индексу funcindex.
Эти уникальные идентификаторы позволяют программе проверять, разделяют ли разные замыкания upvalue. Замыкания Lua, которые разделяют upvalue (то есть обращаются к одной и той же внешней локальной переменной), будут возвращать идентичные идентификаторы для этих индексов upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue, но n не может быть больше количества upvalue.
lua_upvaluejoin
[-0, +0, –]
void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
int funcindex2, int n2);
Делает так, чтобы n1-е upvalue замыкания Lua по индексу funcindex1 ссылалось на n2-е upvalue замыкания Lua по индексу funcindex2.
4 - Вспомогательная библиотека Lua
Полное описание функций и типов вспомогательной библиотеки Lua (lauxlib)
Оглавление
- Введение
- Функции и типы
Введение
Вспомогательная библиотека предоставляет несколько удобных функций для взаимодействия C с Lua. В то время как базовый API предоставляет примитивные функции для всех взаимодействий между C и Lua, вспомогательная библиотека предоставляет функции более высокого уровня для некоторых распространенных задач.
Все функции и типы из вспомогательной библиотеки определены в заголовочном файле lauxlib.h и имеют префикс luaL_.
Все функции вспомогательной библиотеки построены поверх базового API, поэтому они не предоставляют ничего, что нельзя было бы сделать с помощью этого API. Тем не менее, использование вспомогательной библиотеки обеспечивает большую согласованность вашего кода.
Некоторые функции во вспомогательной библиотеке используют внутри себя несколько дополнительных слотов стека. Когда функция вспомогательной библиотеки использует менее пяти слотов, она не проверяет размер стека; она просто предполагает, что слотов достаточно.
Некоторые функции вспомогательной библиотеки используются для проверки аргументов функций C. Поскольку сообщение об ошибке форматируется для аргументов (например, "bad argument #1"), вы не должны использовать эти функции для других значений стека.
Функции, называемые luaL_check*, всегда вызывают ошибку, если проверка не пройдена.
Функции и типы
Здесь мы перечисляем все функции и типы из вспомогательной библиотеки в алфавитном порядке.
luaL_addchar
[-?, +?, m]
void luaL_addchar (luaL_Buffer *B, char c);
Добавляет байт c в буфер B (см. luaL_Buffer).
luaL_addgsub
[-?, +?, m]
const void luaL_addgsub (luaL_Buffer *B, const char *s,
const char *p, const char *r);
Добавляет копию строки s в буфер B (см. luaL_Buffer), заменяя любое вхождение строки p строкой r.
luaL_addlstring
[-?, +?, m]
void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
Добавляет строку, на которую указывает s, длиной l в буфер B (см. luaL_Buffer). Строка может содержать встроенные нули.
luaL_addsize
[-?, +?, –]
void luaL_addsize (luaL_Buffer *B, size_t n);
Добавляет в буфер B строку длиной n, предварительно скопированную в область буфера (см. luaL_prepbuffer).
luaL_addstring
[-?, +?, m]
void luaL_addstring (luaL_Buffer *B, const char *s);
Добавляет строку с завершающим нулем, на которую указывает s, в буфер B (см. luaL_Buffer).
luaL_addvalue
[-?, +?, m]
void luaL_addvalue (luaL_Buffer *B);
Добавляет значение на вершине стека в буфер B (см. luaL_Buffer). Выталкивает значение.
Это единственная функция строковых буферов, которую можно (и нужно) вызывать с дополнительным элементом в стеке, который является значением, добавляемым в буфер.
luaL_argcheck
[-0, +0, v]
void luaL_argcheck (lua_State *L,
int cond,
int arg,
const char *extramsg);
Проверяет, является ли cond истиной. Если нет, вызывает ошибку со стандартным сообщением (см. luaL_argerror).
luaL_argerror
[-0, +0, v]
int luaL_argerror (lua_State *L, int arg, const char *extramsg);
Вызывает ошибку, сообщающую о проблеме с аргументом arg функции C, которая ее вызвала, используя стандартное сообщение, которое включает extramsg в качестве комментария:
bad argument #arg to 'funcname' (extramsg)
Эта функция никогда не возвращается.
luaL_argexpected
[-0, +0, v]
void luaL_argexpected (lua_State *L,
int cond,
int arg,
const char *tname);
Проверяет, является ли cond истиной. Если нет, вызывает ошибку о типе аргумента arg со стандартным сообщением (см. luaL_typeerror).
luaL_Buffer
typedef struct luaL_Buffer luaL_Buffer;
Тип для строкового буфера.
Строковый буфер позволяет коду C строить строки Lua по частям. Шаблон его использования следующий:
- Сначала объявите переменную
b типа luaL_Buffer. - Затем инициализируйте ее вызовом
luaL_buffinit(L, &b). - Затем добавляйте фрагменты строки в буфер, вызывая любую из функций
luaL_add*. - Завершите вызовом
luaL_pushresult(&b). Этот вызов оставляет итоговую строку на вершине стека.
Если вы заранее знаете максимальный размер результирующей строки, вы можете использовать буфер следующим образом:
- Сначала объявите переменную
b типа luaL_Buffer. - Затем инициализируйте ее и предварительно выделите пространство размером
sz вызовом luaL_buffinitsize(L, &b, sz). - Затем создайте строку в этом пространстве.
- Завершите вызовом
luaL_pushresultsize(&b, sz), где sz — общий размер результирующей строки, скопированной в это пространство (который может быть меньше или равен предварительно выделенному размеру).
Во время своей нормальной работы строковый буфер использует переменное количество слотов стека. Поэтому при использовании буфера вы не можете предполагать, что знаете, где находится вершина стека. Вы можете использовать стек между последовательными вызовами операций с буфером, если это использование сбалансировано; то есть, когда вы вызываете операцию с буфером, стек находится на том же уровне, на котором он был сразу после предыдущей операции с буфером. (Единственным исключением из этого правила является luaL_addvalue.) После вызова luaL_pushresult стек возвращается на уровень, на котором он был при инициализации буфера, плюс итоговая строка на его вершине.
luaL_buffaddr
[-0, +0, –]
char *luaL_buffaddr (luaL_Buffer *B);
Возвращает адрес текущего содержимого буфера B (см. luaL_Buffer). Обратите внимание, что любое добавление в буфер может сделать этот адрес недействительным.
luaL_buffinit
[-0, +?, –]
void luaL_buffinit (lua_State *L, luaL_Buffer *B);
Инициализирует буфер B (см. luaL_Buffer). Эта функция не выделяет никакого пространства; буфер должен быть объявлен как переменная.
luaL_bufflen
[-0, +0, –]
size_t luaL_bufflen (luaL_Buffer *B);
Возвращает длину текущего содержимого буфера B (см. luaL_Buffer).
luaL_buffinitsize
[-?, +?, m]
char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz);
Эквивалент последовательности luaL_buffinit, luaL_prepbuffsize.
luaL_buffsub
[-?, +?, –]
void luaL_buffsub (luaL_Buffer *B, int n);
Удаляет n байт из буфера B (см. luaL_Buffer). Буфер должен иметь как минимум столько байт.
[-0, +(0|1), e]
int luaL_callmeta (lua_State *L, int obj, const char *e);
Вызывает метаметод.
Если объект по индексу obj имеет метатаблицу и эта метатаблица имеет поле e, эта функция вызывает это поле, передавая объект в качестве единственного аргумента. В этом случае функция возвращает true и помещает в стек значение, возвращенное вызовом. Если метатаблицы нет или нет метаметода, функция возвращает false, не помещая никакого значения в стек.
luaL_checkany
[-0, +0, v]
void luaL_checkany (lua_State *L, int arg);
Проверяет, есть ли у функции аргумент любого типа (включая nil) в позиции arg.
luaL_checkinteger
[-0, +0, v]
lua_Integer luaL_checkinteger (lua_State *L, int arg);
Проверяет, является ли аргумент функции arg целым числом (или может быть преобразован в целое число), и возвращает это целое число.
luaL_checklstring
[-0, +0, v]
const char *luaL_checklstring (lua_State *L, int arg, size_t *l);
Проверяет, является ли аргумент функции arg строкой, и возвращает эту строку; если l не NULL, заполняет его ссылку длиной строки.
Эта функция использует lua_tolstring для получения результата, поэтому здесь применяются все преобразования и предостережения этой функции.
luaL_checknumber
[-0, +0, v]
lua_Number luaL_checknumber (lua_State *L, int arg);
Проверяет, является ли аргумент функции arg числом, и возвращает это число, преобразованное в lua_Number.
luaL_checkoption
[-0, +0, v]
int luaL_checkoption (lua_State *L,
int arg,
const char *def,
const char *const lst[]);
Проверяет, является ли аргумент функции arg строкой, и ищет эту строку в массиве lst (который должен заканчиваться NULL). Возвращает индекс в массиве, где была найдена строка. Вызывает ошибку, если аргумент не является строкой или если строка не может быть найдена.
Если def не NULL, функция использует def как значение по умолчанию, когда аргумент arg отсутствует или когда этот аргумент равен nil.
Это полезная функция для сопоставления строк с перечислениями C. (Обычное соглашение в библиотеках Lua — использовать строки вместо чисел для выбора опций.)
luaL_checkstack
[-0, +0, v]
void luaL_checkstack (lua_State *L, int sz, const char *msg);
Увеличивает размер стека до top + sz элементов, вызывая ошибку, если стек не может вырасти до этого размера. msg — дополнительный текст для сообщения об ошибке (или NULL для отсутствия дополнительного текста).
luaL_checkstring
[-0, +0, v]
const char *luaL_checkstring (lua_State *L, int arg);
Проверяет, является ли аргумент функции arg строкой, и возвращает эту строку.
Эта функция использует lua_tolstring для получения результата, поэтому здесь применяются все преобразования и предостережения этой функции.
luaL_checktype
[-0, +0, v]
void luaL_checktype (lua_State *L, int arg, int t);
Проверяет, имеет ли аргумент функции arg тип t. См. lua_type для кодировки типов для t.
luaL_checkudata
[-0, +0, v]
void *luaL_checkudata (lua_State *L, int arg, const char *tname);
Проверяет, является ли аргумент функции arg пользовательскими данными типа tname (см. luaL_newmetatable), и возвращает адрес блока памяти пользовательских данных (см. lua_touserdata).
luaL_checkversion
[-0, +0, v]
void luaL_checkversion (lua_State *L);
Проверяет, используют ли код, выполняющий вызов, и вызываемая библиотека Lua одну и ту же версию Lua и одни и те же числовые типы.
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 (LUA_OK), если ошибок нет, или 1 в случае ошибок. (За исключением ошибок нехватки памяти, которые вызываются.)
luaL_dostring
[-0, +?, –]
int luaL_dostring (lua_State *L, const char *str);
Загружает и выполняет указанную строку. Определен как следующий макрос:
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
Возвращает 0 (LUA_OK), если ошибок нет, или 1 в случае ошибок.
luaL_error
[-0, +0, v]
int luaL_error (lua_State *L, const char *fmt, ...);
Вызывает ошибку. Формат сообщения об ошибке задается fmt плюс любые дополнительные аргументы, следуя тем же правилам, что и lua_pushfstring. Она также добавляет в начало сообщения имя файла и номер строки, где произошла ошибка, если эта информация доступна.
Эта функция никогда не возвращается, но идиоматично использовать ее в функциях C как return luaL_error(args).
luaL_execresult
[-0, +3, m]
int luaL_execresult (lua_State *L, int stat);
Эта функция создает возвращаемые значения для функций, связанных с процессами, в стандартной библиотеке (os.execute и io.close).
luaL_fileresult
[-0, +(1|3), m]
int luaL_fileresult (lua_State *L, int stat, const char *fname);
Эта функция создает возвращаемые значения для функций, связанных с файлами, в стандартной библиотеке (io.open, os.rename, file:seek и т.д.).
[-0, +(0|1), m]
int luaL_getmetafield (lua_State *L, int obj, const char *e);
Помещает в стек поле e из метатаблицы объекта по индексу obj и возвращает тип помещенного значения. Если объект не имеет метатаблицы или если метатаблица не имеет этого поля, ничего не помещает и возвращает LUA_TNIL.
[-0, +1, m]
int luaL_getmetatable (lua_State *L, const char *tname);
Помещает в стек метатаблицу, связанную с именем tname в реестре (см. luaL_newmetatable), или nil, если с этим именем не связано метатаблицы. Возвращает тип помещенного значения.
luaL_getsubtable
[-0, +1, e]
int luaL_getsubtable (lua_State *L, int idx, const char *fname);
Обеспечивает, что значение t[fname], где t — значение по индексу idx, является таблицей, и помещает эту таблицу в стек. Возвращает true, если находит там существующую таблицу, и false, если создает новую таблицу.
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_len
[-0, +0, e]
lua_Integer luaL_len (lua_State *L, int index);
Возвращает “длину” значения по указанному индексу в виде числа; это эквивалентно оператору # в Lua (см. §3.4.7). Вызывает ошибку, если результат операции не является целым числом. (Этот случай может произойти только через метаметоды.)
luaL_loadbuffer
[-0, +1, –]
int luaL_loadbuffer (lua_State *L,
const char *buff,
size_t sz,
const char *name);
Эквивалент luaL_loadbufferx с mode, равным NULL.
luaL_loadbufferx
[-0, +1, –]
int luaL_loadbufferx (lua_State *L,
const char *buff,
size_t sz,
const char *name,
const char *mode);
Загружает буфер как чанк Lua. Эта функция использует lua_load для загрузки чанка в буфере, на который указывает buff, размером sz.
Эта функция возвращает те же результаты, что и lua_load. name — имя чанка, используемое для отладочной информации и сообщений об ошибках. Строка mode работает так же, как в функции lua_load. В частности, эта функция поддерживает режим 'B' для фиксированных буферов.
luaL_loadfile
[-0, +1, m]
int luaL_loadfile (lua_State *L, const char *filename);
Эквивалент luaL_loadfilex с mode, равным NULL.
luaL_loadfilex
[-0, +1, m]
int luaL_loadfilex (lua_State *L, const char *filename,
const char *mode);
Загружает файл как чанк Lua. Эта функция использует lua_load для загрузки чанка в файле с именем filename. Если filename равен NULL, то загружает из стандартного ввода. Первая строка в файле игнорируется, если она начинается с #.
Строка mode работает так же, как в функции lua_load.
Эта функция возвращает те же результаты, что и lua_load, или LUA_ERRFILE для ошибок, связанных с файлом.
Как и lua_load, эта функция только загружает чанк; она не выполняет его.
luaL_loadstring
[-0, +1, –]
int luaL_loadstring (lua_State *L, const char *s);
Загружает строку как чанк Lua. Эта функция использует lua_load для загрузки чанка в строке с завершающим нулем s.
Эта функция возвращает те же результаты, что и lua_load.
Также как и lua_load, эта функция только загружает чанк; она не выполняет его.
luaL_makeseed
[-0, +0, –]
unsigned int luaL_makeseed (lua_State *L);
Возвращает значение со слабой попыткой случайности. Параметр L может быть NULL, если состояние Lua недоступно.
luaL_newlib
[-0, +1, m]
void luaL_newlib (lua_State *L, const luaL_Reg l[]);
Создает новую таблицу и регистрирует в ней функции из списка l.
Реализована как следующий макрос:
(luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
Массив l должен быть фактическим массивом, а не указателем на него.
luaL_newlibtable
[-0, +1, m]
void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);
Создает новую таблицу с размером, оптимизированным для хранения всех записей в массиве l (но фактически не сохраняет их). Предназначена для использования в сочетании с luaL_setfuncs (см. luaL_newlib).
Реализована как макрос. Массив l должен быть фактическим массивом, а не указателем на него.
[-0, +1, m]
int luaL_newmetatable (lua_State *L, const char *tname);
Если в реестре уже есть ключ tname, возвращает 0. В противном случае создает новую таблицу для использования в качестве метатаблицы для пользовательских данных, добавляет в эту новую таблицу пару __name = tname, добавляет в реестр пару [tname] = new table и возвращает 1.
В обоих случаях функция помещает в стек итоговое значение, связанное с tname в реестре.
luaL_newstate
[-0, +0, –]
lua_State *luaL_newstate (void);
Создает новое состояние Lua. Вызывает lua_newstate с luaL_alloc в качестве функции распределения памяти и результатом luaL_makeseed(NULL) в качестве seed, а затем устанавливает функцию предупреждения и функцию паники (см. §4.4), которые выводят сообщения в стандартный вывод ошибок.
Возвращает новое состояние или NULL в случае ошибки выделения памяти.
luaL_opt
[-0, +0, –]
T luaL_opt (L, func, arg, dflt);
Этот макрос определяется следующим образом:
(lua_isnoneornil(L,(arg)) ? (dflt) : func(L,(arg)))
Словами: если аргумент arg равен nil или отсутствует, макрос возвращает значение по умолчанию dflt. В противном случае он возвращает результат вызова func с состоянием L и индексом аргумента arg в качестве аргументов. Обратите внимание, что он вычисляет выражение dflt только при необходимости.
luaL_optinteger
[-0, +0, v]
lua_Integer luaL_optinteger (lua_State *L,
int arg,
lua_Integer d);
Если аргумент функции arg является целым числом (или может быть преобразован в целое число), возвращает это целое число. Если этот аргумент отсутствует или равен nil, возвращает d. В противном случае вызывает ошибку.
luaL_optlstring
[-0, +0, v]
const char *luaL_optlstring (lua_State *L,
int arg,
const char *d,
size_t *l);
Если аргумент функции arg является строкой, возвращает эту строку. Если этот аргумент отсутствует или равен nil, возвращает d. В противном случае вызывает ошибку.
Если l не NULL, заполняет его ссылку длиной результата. Если результат NULL (возможно только при возврате d и d == NULL), его длина считается нулевой.
Эта функция использует lua_tolstring для получения результата, поэтому здесь применяются все преобразования и предостережения этой функции.
luaL_optnumber
[-0, +0, v]
lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number d);
Если аргумент функции arg является числом, возвращает это число как lua_Number. Если этот аргумент отсутствует или равен nil, возвращает d. В противном случае вызывает ошибку.
luaL_optstring
[-0, +0, v]
const char *luaL_optstring (lua_State *L,
int arg,
const char *d);
Если аргумент функции arg является строкой, возвращает эту строку. Если этот аргумент отсутствует или равен nil, возвращает d. В противном случае вызывает ошибку.
luaL_prepbuffer
[-?, +?, m]
char *luaL_prepbuffer (luaL_Buffer *B);
Эквивалент luaL_prepbuffsize с предопределенным размером LUAL_BUFFERSIZE.
luaL_prepbuffsize
[-?, +?, m]
char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz);
Возвращает адрес пространства размером sz, куда вы можете скопировать строку для добавления в буфер B (см. luaL_Buffer). После копирования строки в это пространство вы должны вызвать luaL_addsize с размером строки, чтобы фактически добавить ее в буфер.
luaL_pushfail
[-0, +1, –]
void luaL_pushfail (lua_State *L);
Помещает значение fail в стек (см. §6).
luaL_pushresult
[-?, +1, m]
void luaL_pushresult (luaL_Buffer *B);
Завершает использование буфера B, оставляя итоговую строку на вершине стека.
luaL_pushresultsize
[-?, +1, m]
void luaL_pushresultsize (luaL_Buffer *B, size_t sz);
Эквивалент последовательности luaL_addsize, luaL_pushresult.
luaL_ref
[-1, +0, m]
int luaL_ref (lua_State *L, int t);
Создает и возвращает ссылку в таблице по индексу t для объекта на вершине стека (и выталкивает объект).
Система ссылок использует целочисленные ключи таблицы. Ссылка — это уникальный целочисленный ключ; luaL_ref обеспечивает уникальность возвращаемых ключей. Запись 1 зарезервирована для внутреннего использования. Перед первым использованием luaL_ref целочисленные ключи таблицы должны образовывать правильную последовательность (без пропусков), а значение в записи 1 должно быть false: nil, если последовательность пуста, false в противном случае. Вы не должны вручную устанавливать целочисленные ключи в таблице после первого использования luaL_ref.
Вы можете получить объект, на который ссылается ссылка r, вызвав lua_rawgeti(L, t, r) или lua_geti(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_setfuncs. name — имя функции, func — указатель на функцию. Любой массив luaL_Reg должен заканчиваться сигнальной записью, в которой и name, и func равны NULL.
luaL_requiref
[-0, +1, e]
void luaL_requiref (lua_State *L, const char *modname,
lua_CFunction openf, int glb);
Если package.loaded[modname] не является true, вызывает функцию openf со строкой modname в качестве аргумента и устанавливает результат вызова в package.loaded[modname], как если бы эта функция была вызвана через require.
Если glb равно true, также сохраняет модуль в глобальную переменную modname.
Оставляет копию модуля в стеке.
luaL_setfuncs
[-nup, +0, m]
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
Регистрирует все функции в массиве l (см. luaL_Reg) в таблице на вершине стека (ниже необязательных upvalues, см. далее).
Когда nup не равен нулю, все функции создаются с nup upvalues, инициализированными копиями nup значений, предварительно помещенных в стек поверх таблицы библиотеки. Эти значения выталкиваются из стека после регистрации.
Функция со значением NULL представляет заполнитель, который заполняется значением false.
[-0, +0, –]
void luaL_setmetatable (lua_State *L, const char *tname);
Устанавливает метатаблицу объекта на вершине стека как метатаблицу, связанную с именем tname в реестре (см. luaL_newmetatable).
luaL_alloc
void *luaL_alloc (void *ud, void *ptr, size_t osize, size_t nsize);
Стандартная функция распределения памяти для Lua (см. lua_Alloc), построенная поверх функций C realloc и free.
luaL_Stream
typedef struct luaL_Stream {
FILE *f;
lua_CFunction closef;
} luaL_Stream;
Стандартное представление файловых дескрипторов, используемое стандартной библиотекой ввода-вывода.
Файловый дескриптор реализован как полные пользовательские данные с метатаблицей, называемой LUA_FILEHANDLE (где LUA_FILEHANDLE — это макрос с фактическим именем метатаблицы). Метатаблица создается библиотекой ввода-вывода (см. luaL_newmetatable).
Эти пользовательские данные должны начинаться со структуры luaL_Stream; они могут содержать другие данные после этой начальной структуры. Поле f указывает на соответствующий поток C или равно NULL, чтобы указать на не полностью созданный дескриптор. Поле closef указывает на функцию Lua, которая будет вызвана для закрытия потока при закрытии или сборке дескриптора; эта функция получает файловый дескриптор в качестве единственного аргумента и должна возвращать либо true в случае успеха, либо false плюс сообщение об ошибке в случае ошибки. Как только Lua вызывает это поле, он изменяет значение поля на NULL, чтобы сигнализировать о том, что дескриптор закрыт.
luaL_testudata
[-0, +0, m]
void *luaL_testudata (lua_State *L, int arg, const char *tname);
Эта функция работает как luaL_checkudata, за исключением того, что при неудачной проверке она возвращает NULL вместо вызова ошибки.
luaL_tolstring
[-0, +1, e]
const char *luaL_tolstring (lua_State *L, int idx, size_t *len);
Преобразует любое значение Lua по указанному индексу в строку C в разумном формате. Результирующая строка помещается в стек и также возвращается функцией (см. §4.1.3). Если len не NULL, функция также устанавливает *len в длину строки.
Если значение имеет метатаблицу с полем __tostring, то luaL_tolstring вызывает соответствующий метаметод со значением в качестве аргумента и использует результат вызова в качестве своего результата.
luaL_traceback
[-0, +1, m]
void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
int level);
Создает и помещает в стек трассировку стека L1. Если msg не NULL, он добавляется в начало трассировки. Параметр level указывает, с какого уровня начинать трассировку.
luaL_typeerror
[-0, +0, v]
int luaL_typeerror (lua_State *L, int arg, const char *tname);
Вызывает ошибку типа для аргумента arg функции C, которая ее вызвала, используя стандартное сообщение; tname — это “имя” ожидаемого типа. Эта функция никогда не возвращается.
luaL_typename
[-0, +0, –]
const char *luaL_typename (lua_State *L, int index);
Возвращает имя типа значения по указанному индексу.
luaL_unref
[-0, +0, –]
void luaL_unref (lua_State *L, int t, int ref);
Освобождает ссылку (см. luaL_ref). Целое число ref должно быть либо LUA_NOREF, либо LUA_REFNIL, либо ссылкой, ранее возвращенной luaL_ref и еще не освобожденной. Если ref равен LUA_NOREF или LUA_REFNIL, эта функция ничего не делает. В противном случае запись удаляется из таблицы, чтобы объект, на который ссылались, мог быть собран, а ссылка ref могла быть снова использована luaL_ref.
luaL_where
[-0, +1, m]
void luaL_where (lua_State *L, int lvl);
Помещает в стек строку, идентифицирующую текущую позицию управления на уровне lvl в стеке вызовов. Обычно эта строка имеет следующий формат:
chunkname:currentline:
Уровень 0 — выполняющаяся функция, уровень 1 — функция, вызвавшая выполняющуюся функцию, и т.д.
Эта функция используется для построения префикса для сообщений об ошибках.
5 - Руководство по языку Lua: Стандартные библиотеки
Полное описание стандартных библиотек Lua, включая базовые функции, работу со строками, таблицами, математику, ввод/вывод, ОС и отладку
Оглавление
- Загрузка библиотек в коде C
- Базовые функции
- Управление сопрограммами
- Модули
- Манипуляции со строками
- Поддержка UTF-8
- Манипуляции с таблицами
- Математические функции
- Средства ввода и вывода
- Средства операционной системы
- Библиотека отладки
6 – Стандартные библиотеки
Стандартные библиотеки Lua предоставляют полезные функции, реализованные на C через C API. Некоторые из этих функций предоставляют основные службы для языка (например, type и getmetatable); другие предоставляют доступ к внешним службам (например, ввод/вывод); а третьи могли бы быть реализованы на самом Lua, но по разным причинам заслуживают реализации на C (например, table.sort).
Все библиотеки реализованы через официальный C API и предоставляются как отдельные модули C. Если не указано иное, эти библиотечные функции не корректируют количество своих аргументов в соответствии с ожидаемыми параметрами. Например, функцию, задокументированную как foo(arg), не следует вызывать без аргумента.
Обозначение fail означает ложное значение, представляющее некую неудачу. (В настоящее время fail эквивалентно nil, но это может измениться в будущих версиях. Рекомендуется всегда проверять успешность этих функций с помощью (not status), а не (status == nil).)
В настоящее время Lua имеет следующие стандартные библиотеки:
- базовая библиотека (§6.2);
- библиотека сопрограмм (§6.3);
- библиотека пакетов (§6.4);
- манипуляции со строками (§6.5);
- базовая поддержка UTF-8 (§6.6);
- манипуляции с таблицами (§6.7);
- математические функции (§6.8) (sin, log и т.д.);
- ввод и вывод (§6.9);
- средства операционной системы (§6.10);
- средства отладки (§6.11).
За исключением базовой библиотеки и библиотеки пакетов, каждая библиотека предоставляет все свои функции как поля глобальной таблицы или как методы своих объектов.
6.1 – Загрузка библиотек в коде C
Главная программа на C должна явно загрузить стандартные библиотеки в состояние, если она хочет, чтобы ее скрипты могли их использовать. Для этого главная программа может вызвать функцию luaL_openlibs. В качестве альтернативы, главная программа может выбрать, какие библиотеки открывать, используя luaL_openselectedlibs. Обе функции объявлены в заголовочном файле lualib.h.
Автономный интерпретатор lua (см. §7) уже открывает все стандартные библиотеки.
luaL_openlibs
[-0, +0, e]
void luaL_openlibs (lua_State *L);
Открывает все стандартные библиотеки Lua в данном состоянии.
luaL_openselectedlibs
[-0, +0, e]
void luaL_openselectedlibs (lua_State *L, int load, int preload);
Открывает (загружает) и предзагружает выбранные стандартные библиотеки в состояние L. (Предзагрузить означает добавить загрузчик библиотеки в таблицу package.preload, чтобы библиотеку можно было затребовать (require) позже в программе. Имейте в виду, что сам require предоставляется библиотекой пакетов. Если программа не загружает эту библиотеку, она не сможет ничего затребовать.)
Целое число load выбирает, какие библиотеки загружать; целое число preload выбирает, какие из незагруженных библиотек предзагружать. Оба являются масками, сформированными побитовым ИЛИ следующих констант:
LUA_GLIBK : базовая библиотека.LUA_LOADLIBK : библиотека пакетов.LUA_COLIBK : библиотека сопрограмм.LUA_STRLIBK : библиотека строк.LUA_UTF8LIBK : библиотека UTF-8.LUA_TABLIBK : библиотека таблиц.LUA_MATHLIBK : математическая библиотека.LUA_IOLIBK : библиотека ввода/вывода.LUA_OSLIBK : библиотека операционной системы.LUA_DBLIBK : библиотека отладки.
6.2 – Базовые функции
Базовая библиотека предоставляет ядро функций для Lua. Если вы не включаете эту библиотеку в свое приложение, вам следует тщательно проверить, нужно ли вам предоставлять реализации для некоторых ее средств.
assert (v [, message])
Вызывает ошибку, если значение ее аргумента v ложно (т.е. nil или false); в противном случае возвращает все свои аргументы. В случае ошибки message является объектом ошибки; при отсутствии по умолчанию используется "assertion failed!"
collectgarbage ([opt [, arg]])
Эта функция является универсальным интерфейсом к сборщику мусора. Она выполняет различные функции в зависимости от своего первого аргумента, opt:
"collect": Выполняет полный цикл сборки мусора. Это опция по умолчанию.
"stop": Останавливает автоматическое выполнение сборщика мусора. Сборщик будет запускаться только при явном вызове, до вызова для его перезапуска.
"restart": Перезапускает автоматическое выполнение сборщика мусора.
"count": Возвращает общий объем памяти, используемый Lua, в Кбайтах. Значение имеет дробную часть, так что умножение его на 1024 дает точное количество байтов, используемых Lua.
"step": Выполняет шаг сборки мусора. За этой опцией может следовать дополнительный аргумент, целое число с размером шага.
Если размер — положительное n, сборщик действует так, как будто было выделено n новых байтов. Если размер равен нулю, сборщик выполняет базовый шаг. В инкрементальном режиме базовый шаг соответствует текущему размеру шага. В поколенческом режиме базовый шаг выполняет полную малую сборку или инкрементальный шаг, если сборщик его запланировал.
В инкрементальном режиме функция возвращает true, если шаг завершил цикл сборки. В поколенческом режиме функция возвращает true, если шаг завершил большую сборку.
"isrunning": Возвращает булево значение, указывающее, запущен ли сборщик (т.е. не остановлен).
"incremental": Изменяет режим сборщика на инкрементальный и возвращает предыдущий режим.
"generational": Изменяет режим сборщика на поколенческий и возвращает предыдущий режим.
"param": Изменяет и/или извлекает значения параметра сборщика. За этой опцией должны следовать один или два дополнительных аргумента: имя изменяемого или извлекаемого параметра (строка) и необязательное новое значение для этого параметра, целое число в диапазоне [0,100000]. Первый аргумент должен иметь одно из следующих значений:
"minormul": Множитель малой сборки."majorminor": Множитель перехода от большой к малой сборке."minormajor": Множитель перехода от малой к большой сборке."pause": Пауза сборщика мусора."stepmul": Множитель шага."stepsize": Размер шага.
Вызов всегда возвращает предыдущее значение параметра. Если вызов не передает новое значение, значение остается неизменным.
Lua хранит эти значения в сжатом формате, поэтому значение, возвращаемое как предыдущее, может не точно совпадать с последним установленным значением.
См. §2.5 для более подробной информации о сборке мусора и некоторых из этих опций.
Эту функцию не следует вызывать из финализатора.
dofile ([filename])
Открывает указанный файл и выполняет его содержимое как чанк Lua, возвращая все значения, возвращенные чанком. При вызове без аргументов dofile выполняет содержимое стандартного ввода (stdin). В случае ошибок dofile передает ошибку своему вызывающему коду. (То есть dofile не работает в защищенном режиме.)
error (message [, level])
Вызывает ошибку (см. §2.3) с message в качестве объекта ошибки. Эта функция никогда не возвращает управление.
Обычно error добавляет некоторую информацию о позиции ошибки в начало сообщения, если сообщение является строкой. Аргумент level указывает, как получить позицию ошибки. При уровне 1 (по умолчанию) позиция ошибки — это место вызова функции error. Уровень 2 указывает на ошибку в месте вызова функции, которая вызвала error; и так далее. Передача уровня 0 предотвращает добавление информации о позиции ошибки в сообщение.
_G
Глобальная переменная (не функция), которая содержит глобальное окружение (см. §2.2). Сама Lua не использует эту переменную; изменение ее значения не влияет ни на какое окружение, и наоборот.
Если object не имеет метатаблицы, возвращает nil. В противном случае, если метатаблица объекта имеет поле __metatable, возвращает связанное с ним значение. В противном случае возвращает метатаблицу данного объекта.
ipairs (t)
Возвращает три значения (функцию-итератор, значение t и 0), так что конструкция
for i,v in ipairs(t) do body end
будет итерироваться по парам ключ-значение (1,t[1]), (2,t[2]), …, до первого отсутствующего индекса.
load (chunk [, chunkname [, mode [, env]]])
Загружает чанк.
Если chunk — строка, то чанк является этой строкой. Если chunk — функция, load вызывает ее повторно для получения частей чанка. Каждый вызов chunk должен возвращать строку, которая конкатенируется с предыдущими результатами. Возврат пустой строки, nil или отсутствие возврата сигнализирует о конце чанка.
Если синтаксических ошибок нет, load возвращает скомпилированный чанк как функцию; в противном случае возвращает fail плюс сообщение об ошибке.
Когда вы загружаете главный чанк, результирующая функция всегда будет иметь ровно одно верхнее значение (upvalue) — переменную _ENV (см. §2.2). Однако, когда вы загружаете бинарный чанк, созданный из функции (см. string.dump), результирующая функция может иметь произвольное количество верхних значений, и нет гарантии, что ее первым верхним значением будет переменная _ENV. (Неглавная функция может даже не иметь верхнего значения _ENV.)
Независимо от этого, если результирующая функция имеет какие-либо верхние значения, ее первое верхнее значение устанавливается в значение env, если этот параметр указан, или в значение глобального окружения. Другие верхние значения инициализируются как nil. Все верхние значения являются новыми, то есть они не разделяются ни с какой другой функцией.
chunkname используется как имя чанка для сообщений об ошибках и отладочной информации (см. §4.7). При отсутствии по умолчанию используется chunk, если chunk — строка, или "=(load)" в противном случае.
Строка mode определяет, может ли чанк быть текстовым или бинарным (то есть предварительно скомпилированным чанком). Это может быть строка "b" (только бинарные чанки), "t" (только текстовые чанки) или "bt" (и бинарные, и текстовые). По умолчанию "bt".
Lua не проверяет целостность бинарных чанков. Злонамеренно созданные бинарные чанки могут привести к краху интерпретатора. Вы можете использовать параметр mode, чтобы предотвратить загрузку бинарных чанков.
loadfile ([filename [, mode [, env]]])
Аналогична load, но получает чанк из файла filename или из стандартного ввода, если имя файла не указано.
next (table [, index])
Позволяет программе обойти все поля таблицы. Ее первый аргумент — таблица, а второй аргумент — индекс в этой таблице. Вызов next возвращает следующий индекс таблицы и связанное с ним значение. При вызове с nil в качестве второго аргумента next возвращает начальный индекс и связанное с ним значение. При вызове с последним индексом или с nil в пустой таблице next возвращает nil. Если второй аргумент отсутствует, он интерпретируется как nil. В частности, вы можете использовать next(t) для проверки, пуста ли таблица.
Порядок перечисления индексов не определен, даже для числовых индексов. (Для обхода таблицы в числовом порядке используйте числовой for.)
Не следует присваивать значение несуществующему полю таблицы во время ее обхода. Однако вы можете изменять существующие поля. В частности, вы можете устанавливать существующие поля в nil.
pairs (t)
Если t имеет метаметод __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 плюс объект ошибки. Обратите внимание, что ошибки, перехваченные pcall, не вызывают обработчик сообщений.
print (···)
Получает любое количество аргументов и выводит их значения в stdout, преобразуя каждый аргумент в строку по тем же правилам, что и tostring.
Функция print не предназначена для форматированного вывода, а только как быстрый способ показать значение, например, для отладки. Для полного контроля над выводом используйте string.format и io.write.
rawequal (v1, v2)
Проверяет, равен ли v1 v2, без вызова метаметода __eq. Возвращает булево значение.
rawget (table, index)
Получает реальное значение table[index], не используя метазначение __index. table должна быть таблицей; index может быть любым значением.
rawlen (v)
Возвращает длину объекта v, который должен быть таблицей или строкой, без вызова метаметода __len. Возвращает целое число.
rawset (table, index, value)
Устанавливает реальное значение table[index] в value, не используя метазначение __newindex. table должна быть таблицей, index — любым значением, отличным от nil и NaN, а value — любым значением Lua.
Эта функция возвращает table.
select (index, ···)
Если index — число, возвращает все аргументы после аргумента с номером index; отрицательное число индексирует с конца (-1 — последний аргумент). В противном случае index должен быть строкой "#", и select возвращает общее количество полученных дополнительных аргументов.
Устанавливает метатаблицу для данной таблицы. Если metatable равно nil, удаляет метатаблицу данной таблицы. Если исходная метатаблица имеет поле __metatable, вызывает ошибку.
Эта функция возвращает table.
Чтобы изменить метатаблицу других типов из кода Lua, вы должны использовать библиотеку отладки (§6.11).
tonumber (e [, base])
При вызове без base tonumber пытается преобразовать свой аргумент в число. Если аргумент уже является числом или строкой, преобразуемой в число, tonumber возвращает это число; в противном случае возвращает fail.
Преобразование строк может давать целые числа или числа с плавающей точкой в соответствии с лексическими соглашениями Lua (см. §3.1). Строка может иметь начальные и конечные пробелы и знак.
При вызове с base аргумент e должен быть строкой, интерпретируемой как целое число в этой системе счисления. base может быть любым целым числом от 2 до 36 включительно. В системах счисления больше 10 буква ‘A’ (в верхнем или нижнем регистре) представляет 10, ‘B’ представляет 11 и так далее, ‘Z’ представляет 35. Если строка e не является допустимым числом в заданной системе счисления, функция возвращает fail.
tostring (v)
Получает значение любого типа и преобразует его в строку в удобочитаемом формате.
Если метатаблица v имеет поле __tostring, tostring вызывает соответствующее значение с v в качестве аргумента и использует результат вызова в качестве своего результата. В противном случае, если метатаблица v имеет поле __name со строковым значением, tostring может использовать эту строку в своем конечном результате.
Для полного контроля над тем, как преобразуются числа, используйте string.format.
type (v)
Возвращает тип своего единственного аргумента, закодированный в виде строки. Возможные результаты этой функции: "nil" (строка, а не значение nil), "number", "string", "boolean", "table", "function", "thread" и "userdata".
_VERSION
Глобальная переменная (не функция), которая содержит строку с текущей версией Lua. Текущее значение этой переменной — "Lua 5.5".
warn (msg1, ···)
Выдает предупреждение с сообщением, составленным путем конкатенации всех ее аргументов (которые должны быть строками).
По соглашению, однокомпонентное сообщение, начинающееся с ‘@’, предназначено быть управляющим сообщением, то есть сообщением для самой системы предупреждений. В частности, стандартная функция предупреждения в Lua распознает управляющие сообщения "@off" (для остановки выдачи предупреждений) и "@on" (для (пере)запуска выдачи); неизвестные управляющие сообщения игнорируются.
xpcall (f, msgh [, arg1, ···])
Эта функция аналогична pcall, за исключением того, что она устанавливает новый обработчик сообщений msgh.
6.3 – Управление сопрограммами
Эта библиотека включает операции для управления сопрограммами, которые находятся внутри таблицы coroutine. См. §2.6 для общего описания сопрограмм.
coroutine.close ([co])
Закрывает сопрограмму co, то есть закрывает все ее ожидающие закрытия переменные и переводит сопрограмму в мертвое состояние. По умолчанию co — это выполняющаяся сопрограмма.
Данная сопрограмма должна быть мертвой, приостановленной или выполняющейся. Для выполняющейся сопрограммы эта функция не возвращает управление. Вместо этого возвращается resume, который (пере)запустил сопрограмму.
Для других сопрограмм, в случае ошибки (либо исходной ошибки, остановившей сопрограмму, либо ошибок в методах закрытия), эта функция возвращает false плюс объект ошибки; в противном случае она возвращает true.
coroutine.create (f)
Создает новую сопрограмму с телом f. f должна быть функцией. Возвращает эту новую сопрограмму, объект типа "thread".
coroutine.isyieldable ([co])
Возвращает true, если сопрограмма co может прерваться (yield). По умолчанию co — это выполняющаяся сопрограмма.
Сопрограмма может прерываться, если она не является главным потоком и не находится внутри непрерываемой C-функции.
coroutine.resume (co [, val1, ···])
Запускает или продолжает выполнение сопрограммы co. При первом возобновлении сопрограммы она начинает выполнение своего тела. Значения val1, … передаются в качестве аргументов функции тела. Если сопрограмма прервалась, resume перезапускает ее; значения val1, … передаются как результаты из yield.
Если сопрограмма выполняется без ошибок, resume возвращает true плюс любые значения, переданные в yield (когда сопрограмма прерывается), или любые значения, возвращенные функцией тела (когда сопрограмма завершается). Если произошла ошибка, resume возвращает false плюс сообщение об ошибке.
coroutine.running ()
Возвращает выполняющуюся сопрограмму и булево значение, true, если выполняющаяся сопрограмма является главной.
coroutine.status (co)
Возвращает статус сопрограммы co в виде строки: "running", если сопрограмма выполняется (то есть это та, которая вызвала status); "suspended", если сопрограмма приостановлена в вызове yield или если она еще не начала выполняться; "normal", если сопрограмма активна, но не выполняется (то есть она возобновила другую сопрограмму); и "dead", если сопрограмма завершила свою функцию тела или остановилась с ошибкой.
coroutine.wrap (f)
Создает новую сопрограмму с телом f; f должна быть функцией. Возвращает функцию, которая возобновляет сопрограмму при каждом вызове. Любые аргументы, переданные этой функции, ведут себя как дополнительные аргументы для resume. Функция возвращает те же значения, что и resume, за исключением первого булева. В случае ошибки функция закрывает сопрограмму и распространяет ошибку.
coroutine.yield (···)
Приостанавливает выполнение вызывающей сопрограммы. Любые аргументы для yield передаются как дополнительные результаты в resume.
6.4 – Модули
Библиотека пакетов предоставляет базовые средства для загрузки модулей в Lua. Она экспортирует одну функцию непосредственно в глобальное окружение: require. Все остальное экспортируется в таблице package.
require (modname)
Загружает данный модуль. Функция начинает с проверки таблицы package.loaded, чтобы определить, загружен ли уже modname. Если да, то require возвращает значение, хранящееся в package.loaded[modname]. (Отсутствие второго результата в этом случае сигнализирует, что этому вызову не пришлось загружать модуль.) В противном случае она пытается найти загрузчик для модуля.
Чтобы найти загрузчик, require руководствуется таблицей package.searchers. Каждый элемент в этой таблице является функцией поиска, которая ищет модуль определенным способом. Изменяя эту таблицу, мы можем изменить способ поиска модуля функцией require. Следующее объяснение основано на конфигурации по умолчанию для package.searchers.
Сначала require запрашивает package.preload[modname]. Если там есть значение, это значение (которое должно быть функцией) является загрузчиком. В противном случае require ищет Lua-загрузчик, используя путь, хранящийся в package.path. Если это также не удается, она ищет C-загрузчик, используя путь, хранящийся в package.cpath. Если и это не удается, она пробует универсальный загрузчик (см. package.searchers).
Как только загрузчик найден, require вызывает загрузчик с двумя аргументами: modname и дополнительным значением, данными загрузчика, также возвращенными функцией поиска. Данные загрузчика могут быть любым значением, полезным для модуля; для стандартных функций поиска они указывают, где был найден загрузчик. (Например, если загрузчик был получен из файла, это дополнительное значение — путь к файлу.) Если загрузчик возвращает любое значение, отличное от nil, require присваивает возвращенное значение package.loaded[modname]. Если загрузчик не возвращает значение, отличное от nil, и не присвоил никакого значения package.loaded[modname], то require присваивает true этой записи. В любом случае require возвращает конечное значение package.loaded[modname]. Помимо этого значения, require также возвращает вторым результатом данные загрузчика, возвращенные функцией поиска, которые указывают, как require нашла модуль.
Если возникает какая-либо ошибка при загрузке или выполнении модуля, или если не удается найти ни одного загрузчика для модуля, require вызывает ошибку.
package.config
Строка, описывающая некоторые конфигурации времени компиляции для пакетов. Эта строка представляет собой последовательность строк:
- Первая строка — это строка-разделитель каталогов. По умолчанию
'\' для Windows и '/' для всех других систем. - Вторая строка — это символ, разделяющий шаблоны в пути. По умолчанию
';'. - Третья строка — это строка, обозначающая точки подстановки в шаблоне. По умолчанию
'?'. - Четвертая строка — это строка, которая в пути в Windows заменяется на каталог исполняемого файла. По умолчанию
'!'. - Пятая строка — это метка для игнорирования всего текста после нее при построении имени функции
luaopen_. По умолчанию '-'.
package.cpath
Строка с путем, используемым require для поиска C-загрузчика.
Lua инициализирует C-путь package.cpath так же, как и Lua-путь package.path, используя переменную окружения LUA_CPATH_5_5, или переменную окружения LUA_CPATH, или путь по умолчанию, определенный в luaconf.h.
package.loaded
Таблица, используемая require для контроля того, какие модули уже загружены. Когда вы запрашиваете модуль modname и package.loaded[modname] не равно false, require просто возвращает значение, хранящееся там.
Эта переменная является лишь ссылкой на реальную таблицу; присваивания этой переменной не изменяют таблицу, используемую require. Реальная таблица хранится в реестре C (см. §4.3), индексируемая ключом LUA_LOADED_TABLE (строкой).
package.loadlib (libname, funcname)
Динамически связывает главную программу с C-библиотекой libname.
Если funcname равно "*", то она только связывается с библиотекой, делая символы, экспортируемые библиотекой, доступными для других динамически связанных библиотек. В противном случае она ищет функцию funcname внутри библиотеки и возвращает эту функцию как C-функцию. Таким образом, funcname должна соответствовать прототипу lua_CFunction (см. lua_CFunction).
Это функция низкого уровня. Она полностью обходит систему пакетов и модулей. В отличие от require, она не выполняет поиск по путям и не добавляет автоматически расширения. libname должно быть полным именем файла C-библиотеки, включая при необходимости путь и расширение. funcname должно быть точным именем, экспортируемым C-библиотекой (которое может зависеть от используемого C-компилятора и компоновщика).
Эта функциональность не поддерживается стандартом ISO C. Поэтому loadlib доступна только на некоторых платформах: Linux, Windows, Mac OS X, Solaris, BSD, а также других Unix-системах, поддерживающих стандарт dlfcn.
Эта функция по своей сути небезопасна, так как позволяет Lua вызывать любую функцию в любой читаемой динамической библиотеке в системе. (Lua вызывает любую функцию, предполагая, что функция имеет правильный прототип и соблюдает правильный протокол (см. lua_CFunction). Поэтому вызов произвольной функции в произвольной динамической библиотеке чаще всего приводит к нарушению доступа.)
package.path
Строка с путем, используемым require для поиска Lua-загрузчика.
При запуске Lua инициализирует эту переменную значением переменной окружения LUA_PATH_5_5 или переменной окружения LUA_PATH, или путем по умолчанию, определенным в luaconf.h, если эти переменные окружения не определены. ";;" в значении переменной окружения заменяется путем по умолчанию.
package.preload
Таблица для хранения загрузчиков для конкретных модулей (см. require).
Эта переменная является лишь ссылкой на реальную таблицу; присваивания этой переменной не изменяют таблицу, используемую require. Реальная таблица хранится в реестре C (см. §4.3), индексируемая ключом LUA_PRELOAD_TABLE (строкой).
package.searchers
Таблица, используемая require для управления поиском модулей.
Каждая запись в этой таблице является функцией поиска. При поиске модуля require вызывает каждую из этих функций поиска в порядке возрастания, передавая имя модуля (аргумент, переданный в require) в качестве единственного аргумента. Если функция поиска находит модуль, она возвращает другую функцию — загрузчик модуля, плюс дополнительное значение — данные загрузчика, которые будут переданы этому загрузчику и возвращены вторым результатом из require. Если она не может найти модуль, она возвращает строку с объяснением причины (или nil, если ей нечего сказать).
Lua инициализирует эту таблицу четырьмя функциями поиска.
Первая функция поиска просто ищет загрузчик в таблице package.preload.
Вторая функция поиска ищет загрузчик как Lua-библиотеку, используя путь, хранящийся в package.path. Поиск выполняется, как описано в функции package.searchpath.
Третья функция поиска ищет загрузчик как C-библиотеку, используя путь, заданный переменной package.cpath. Поиск также выполняется, как описано в функции package.searchpath. Например, если C-путь — это строка
"./?.so;./?.dll;/usr/local/?/init.so"
функция поиска для модуля foo попытается открыть файлы ./foo.so, ./foo.dll и /usr/local/foo/init.so в этом порядке. Найдя C-библиотеку, эта функция поиска сначала использует средство динамической загрузки для связывания приложения с библиотекой. Затем она пытается найти C-функцию внутри библиотеки, которая будет использоваться в качестве загрузчика. Имя этой C-функции — это строка "luaopen_", конкатенированная с копией имени модуля, где каждая точка заменена на подчеркивание. Более того, если имя модуля содержит дефис, его суффикс после (и включая) первого дефиса удаляется. Например, если имя модуля a.b.c-v2.1, имя функции будет luaopen_a_b_c.
Четвертая функция поиска пробует универсальный загрузчик. Она ищет в C-пути библиотеку для корневого имени заданного модуля. Например, при запросе a.b.c она будет искать C-библиотеку для a. Если она найдена, она ищет в ней функцию открытия для подмодуля; в нашем примере это будет luaopen_a_b_c. С помощью этого средства пакет может упаковать несколько C-подмодулей в одну библиотеку, при этом каждый подмодуль сохраняет свою оригинальную функцию открытия.
Все функции поиска, кроме первой (предзагрузки), возвращают в качестве дополнительного значения путь к файлу, где был найден модуль, как возвращено package.searchpath. Первая функция поиска всегда возвращает строку ":preload:".
Функции поиска не должны вызывать ошибок и не должны иметь побочных эффектов в Lua. (Они могут иметь побочные эффекты в C, например, связывая приложение с библиотекой.)
package.searchpath (name, path [, sep [, rep]])
Ищет заданное name в заданном path.
Путь — это строка, содержащая последовательность шаблонов, разделенных точкой с запятой. Для каждого шаблона функция заменяет каждый вопросительный знак (если есть) в шаблоне копией name, в которой все вхождения sep (по умолчанию точка) заменены на rep (по умолчанию системный разделитель каталогов), а затем пытается открыть полученное имя файла.
Например, если путь — строка
"./?.lua;./?.lc;/usr/local/?/init.lua"
поиск имени foo.a попытается открыть файлы ./foo/a.lua, ./foo/a.lc и /usr/local/foo/a/init.lua в этом порядке.
Возвращает результирующее имя первого файла, который удается открыть в режиме чтения (после закрытия файла), или fail плюс сообщение об ошибке, если ни один не подошел. (Это сообщение об ошибке перечисляет все имена файлов, которые пытались открыть.)
6.5 – Манипуляции со строками
Эта библиотека предоставляет общие функции для работы со строками, такие как поиск и извлечение подстрок, а также сопоставление с образцом. При индексации строки в 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.sub.
Числовые коды не обязательно переносимы между платформами.
string.char (···)
Получает ноль или более целых чисел. Возвращает строку длиной, равной количеству аргументов, в которой каждый символ имеет внутренний числовой код, равный соответствующему аргументу.
Числовые коды не обязательно переносимы между платформами.
string.dump (function [, strip])
Возвращает строку, содержащую бинарное представление (бинарный чанк) заданной функции, так что последующая load этой строки вернет копию функции (но с новыми верхними значениями). Если strip — истинное значение, бинарное представление может не включать всю отладочную информацию о функции для экономии места.
У функций с верхними значениями сохраняется только их количество. При (пере)загрузке эти верхние значения получают новые экземпляры. (Подробности о том, как эти верхние значения инициализируются, см. в описании функции load. Вы можете использовать библиотеку отладки для сериализации и перезагрузки верхних значений функции способом, адекватным вашим потребностям.)
string.find (s, pattern [, init [, plain]])
Ищет первое совпадение с pattern (см. §6.5.1) в строке s. Если находит совпадение, find возвращает индексы s, где это вхождение начинается и заканчивается; в противном случае возвращает fail. Третий, необязательный числовой аргумент init указывает, с какой позиции начинать поиск; его значение по умолчанию 1, и оно может быть отрицательным. Значение true в качестве четвертого, необязательного аргумента plain отключает средства сопоставления с образцом, так что функция выполняет простой “поиск подстроки”, при этом ни один символ в pattern не считается магическим.
Если в образце есть захваты, то при успешном совпадении захваченные значения также возвращаются после двух индексов.
Возвращает отформатированную версию своего переменного числа аргументов в соответствии с описанием, данным в первом аргументе, который должен быть строкой. Строка формата следует тем же правилам, что и функция ISO C sprintf. Допустимые спецификаторы преобразования: A, a, c, d, E, e, f, G, g, i, o, p, s, u, X, x и '%', а также не-C спецификатор q. Допустимые флаги: '-', '+', '#', '0' и ' ' (пробел). Как ширина, так и точность, если указаны, ограничены двумя цифрами.
Спецификатор q форматирует булевы значения, nil, числа и строки таким образом, что результат является допустимой константой в исходном коде Lua. Булевы значения и nil записываются очевидным образом (true, false, nil). Числа с плавающей точкой записываются в шестнадцатеричном виде для сохранения полной точности. Строка записывается в двойных кавычках с использованием escape-последовательностей, где это необходимо, чтобы гарантировать, что она может быть безопасно прочитана обратно интерпретатором Lua. Например, вызов
string.format('%q', 'a string with "quotes" and \n new line')
может произвести строку:
"a string with \"quotes\" and \
new line"
Этот спецификатор не поддерживает модификаторы (флаги, ширину, точность).
Спецификаторы преобразования A, a, E, e, f, G и g ожидают число в качестве аргумента. Спецификаторы c, d, i, o, u, X и x ожидают целое число. Когда Lua скомпилирован с компилятором C89, спецификаторы A и a (шестнадцатеричные числа с плавающей точкой) не поддерживают модификаторы.
Спецификатор s ожидает строку; если его аргумент не является строкой, он преобразуется в нее по тем же правилам, что и tostring. Если спецификатор имеет какой-либо модификатор, соответствующий строковый аргумент не должен содержать встроенных нулей.
Спецификатор p форматирует указатель, возвращенный lua_topointer. Это дает уникальный строковый идентификатор для таблиц, пользовательских данных, потоков, строк и функций. Для других значений (числа, nil, булевы значения) этот спецификатор дает строку, представляющую указатель NULL.
string.gmatch (s, pattern [, init])
Возвращает функцию-итератор, которая при каждом вызове возвращает следующие захваты из pattern (см. §6.5.1) по строке s. Если pattern не указывает захватов, то при каждом вызове выдается все совпадение целиком. Третий, необязательный числовой аргумент init указывает, с какой позиции начинать поиск; его значение по умолчанию 1, и оно может быть отрицательным.
В качестве примера, следующий цикл будет итерироваться по всем словам из строки s, печатая по одному в строке:
s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
print(w)
end
Следующий пример собирает все пары 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 (см. §6.5.1) были заменены строкой замены, указанной в repl, которая может быть строкой, таблицей или функцией. gsub также возвращает вторым значением общее количество произошедших совпадений. Имя gsub происходит от Global SUBstitution.
Если repl — строка, то ее значение используется для замены. Символ % работает как escape-символ: любая последовательность в repl вида %d, где d от 1 до 9, обозначает значение d-й захваченной подстроки; последовательность %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 load(s)()
end)
-- x="4+5 = 9"
local t = {name="lua", version="5.5"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
-- x="lua-5.5.tar.gz"
string.len (s)
Получает строку и возвращает ее длину. Пустая строка "" имеет длину 0. Встроенные нули считаются, поэтому "a\000bc\000" имеет длину 5.
string.lower (s)
Получает строку и возвращает копию этой строки, в которой все заглавные буквы заменены на строчные. Все остальные символы остаются без изменений. Определение того, что является заглавной буквой, зависит от текущей локали.
string.match (s, pattern [, init])
Ищет первое совпадение с образцом (см. §6.5.1) в строке s. Если находит, match возвращает захваты из образца; в противном случае возвращает fail. Если образец не указывает захватов, возвращается все совпадение целиком. Третий, необязательный числовой аргумент init указывает, с какой позиции начинать поиск; его значение по умолчанию 1, и оно может быть отрицательным.
string.pack (fmt, v1, v2, ···)
Возвращает бинарную строку, содержащую значения v1, v2 и т.д., сериализованные в бинарной форме (упакованные) в соответствии со строкой формата fmt (см. §6.5.2).
string.packsize (fmt)
Возвращает длину строки, получаемой в результате string.pack с заданным форматом. Строка формата не может иметь опции переменной длины 's' или 'z' (см. §6.5.2).
string.rep (s, n [, sep])
Возвращает строку, которая является конкатенацией n копий строки s, разделенных строкой sep. Значение по умолчанию для sep — пустая строка (то есть без разделителя). Возвращает пустую строку, если n не положительно.
(Обратите внимание, что очень легко исчерпать память вашей машины одним вызовом этой функции.)
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) (для положительного i) возвращает суффикс s длиной i.
Если после преобразования отрицательных индексов i меньше 1, оно корректируется до 1. Если j больше длины строки, оно корректируется до этой длины. Если после этих коррекций i больше j, функция возвращает пустую строку.
string.unpack (fmt, s [, pos])
Возвращает значения, упакованные в строке s (см. string.pack) в соответствии со строкой формата fmt (см. §6.5.2). Необязательный параметр pos указывает, с какой позиции начинать чтение в s (по умолчанию 1). После прочитанных значений эта функция также возвращает индекс первого непрочитанного байта в s.
string.upper (s)
Получает строку и возвращает копию этой строки, в которой все строчные буквы заменены на заглавные. Все остальные символы остаются без изменений. Определение того, что является строчной буквой, зависит от текущей локали.
6.5.1 – Образцы (Patterns)
Образцы в Lua описываются обычными строками, которые интерпретируются как образцы функциями сопоставления с образцом string.find, string.gmatch, string.gsub и string.match. В этом разделе описывается синтаксис и значение (то есть что они сопоставляют) этих строк.
Класс символов:
Класс символов используется для представления набора символов. Следующие комбинации допустимы при описании класса символов:
x: (где x не является одним из магических символов ^$()%.[]*+-?) представляет сам символ x.
.: (точка) представляет все символы.
%a: представляет все буквы.
%c: представляет все управляющие символы.
%d: представляет все цифры.
%g: представляет все печатные символы, кроме пробела.
%l: представляет все строчные буквы.
%p: представляет все знаки пунктуации.
%s: представляет все пробельные символы.
%u: представляет все заглавные буквы.
%w: представляет все буквенно-цифровые символы.
%x: представляет все шестнадцатеричные цифры.
%x: (где x — любой небуквенно-цифровой символ) представляет сам символ x. Это стандартный способ экранирования магических символов. Любой небуквенно-цифровой символ (включая все знаки пунктуации, даже немагические) может быть предварен '%', чтобы представить самого себя в образце.
[set]: представляет класс, который является объединением всех символов в set. Диапазон символов может быть указан путем разделения конечных символов диапазона в порядке возрастания с помощью '-'. Все классы %x, описанные выше, также могут использоваться как компоненты в set. Все остальные символы в set представляют сами себя. Например, [%w_] (или [_%w]) представляет все буквенно-цифровые символы плюс подчеркивание, [0-7] представляет восьмеричные цифры, а [0-7%l%-] представляет восьмеричные цифры плюс строчные буквы плюс символ '-'.
Вы можете поместить закрывающую квадратную скобку в набор, расположив ее как первый символ в наборе. Вы можете поместить дефис в набор, расположив его как первый или последний символ в наборе. (Вы также можете использовать экранирование для обоих случаев.)
Взаимодействие между диапазонами и классами не определено. Поэтому образцы типа [%a-z] или [a-%%] не имеют смысла.
[^set]: представляет дополнение к set, где set интерпретируется как выше.
Для всех классов, представленных одиночными буквами (%a, %c и т.д.), соответствующая заглавная буква представляет дополнение класса. Например, %S представляет все непробельные символы.
Определения буквы, пробела и других групп символов зависят от текущей локали. В частности, класс [a-z] может быть не эквивалентен %l.
Элемент образца:
Элементом образца может быть
- одиночный класс символов, который соответствует любому одиночному символу в классе;
- одиночный класс символов, за которым следует
'*', что соответствует последовательностям из нуля или более символов в классе. Эти элементы повторения всегда будут соответствовать самой длинной возможной последовательности; - одиночный класс символов, за которым следует
'+', что соответствует последовательностям из одного или более символов в классе. Эти элементы повторения всегда будут соответствовать самой длинной возможной последовательности; - одиночный класс символов, за которым следует
'-', что также соответствует последовательностям из нуля или более символов в классе. В отличие от '*', эти элементы повторения всегда будут соответствовать самой короткой возможной последовательности; - одиночный класс символов, за которым следует
'?', что соответствует нулю или одному вхождению символа в классе. Всегда соответствует одному вхождению, если это возможно; %n, для n от 1 до 9; такой элемент соответствует подстроке, равной n-й захваченной строке (см. ниже);%bxy, где x и y — два различных символа; такой элемент соответствует строкам, которые начинаются с x, заканчиваются на y и где x и y сбалансированы. Это означает, что если читать строку слева направо, считая +1 для x и -1 для y, конечный y — это первый y, где счетчик достигает 0. Например, элемент %b() соответствует выражениям со сбалансированными круглыми скобками.%f[set], образец границы; такой элемент соответствует пустой строке в любой позиции, такой что следующий символ принадлежит set, а предыдущий символ не принадлежит set. Набор set интерпретируется, как описано ранее. Начало и конец строки обрабатываются так, как если бы они были символом '\0'.
Образец:
Образец — это последовательность элементов образца. Символ '^' в начале образца привязывает совпадение к началу строки. Символ '$' в конце образца привязывает совпадение к концу строки. В других позициях '^' и '$' не имеют специального значения и представляют сами себя.
Захваты:
Образец может содержать подобразцы, заключенные в круглые скобки; они описывают захваты. Когда совпадение успешно, подстроки строки, соответствующие захватам, сохраняются (захватываются) для будущего использования. Захваты нумеруются в соответствии с их левыми скобками. Например, в образце "(a*(.)%w(%s*))" часть строки, соответствующая "a*(.)%w(%s*)", сохраняется как первый захват и, следовательно, имеет номер 1; символ, соответствующий ".", захватывается с номером 2, а часть, соответствующая "%s*", имеет номер 3.
В качестве особого случая, захват () захватывает текущую позицию в строке (число). Например, если применить образец "()aa()" к строке "flaaap", будет два захвата: 3 и 5.
Множественные совпадения:
Функция string.gsub и итератор string.gmatch ищут множественные вхождения заданного образца в строке. Для этих функций новое совпадение считается допустимым, только если оно заканчивается хотя бы на один байт позже конца предыдущего совпадения. Другими словами, автомат образцов никогда не принимает пустую строку в качестве совпадения сразу после другого совпадения. В качестве примера рассмотрим результаты следующего кода:
> string.gsub("abc", "()a*()", print);
--> 1 2
--> 3 3
--> 4 4
Второй и третий результаты получаются, когда Lua сопоставляет пустую строку после 'b' и еще одну после 'c'. Lua не сопоставляет пустую строку после 'a', потому что она закончилась бы в той же позиции, что и предыдущее совпадение.
6.5.2 – Строки формата для Pack и Unpack
Первым аргументом для string.pack, string.packsize и string.unpack является строка формата, которая описывает структуру создаваемой или читаемой структуры.
Строка формата — это последовательность опций преобразования. Опции преобразования следующие:
<: устанавливает little-endian (порядок байтов от младшего к старшему)>: устанавливает big-endian (порядок байтов от старшего к младшему)=: устанавливает native-endian (родной порядок байтов)![n]: устанавливает максимальное выравнивание в n (по умолчанию родное выравнивание)b: знаковый байт (char)B: беззнаковый байт (unsigned char)h: знаковый short (родного размера)H: беззнаковый short (родного размера)l: знаковый long (родного размера)L: беззнаковый long (родного размера)j: lua_IntegerJ: lua_UnsignedT: size_t (родного размера)i[n]: знаковый int размером n байт (по умолчанию родной размер)I[n]: беззнаковый int размером n байт (по умолчанию родной размер)f: float (родного размера)d: double (родного размера)n: lua_Numbercn: строка фиксированного размера длиной n байтz: строка, завершающаяся нулемs[n]: строка, предваренная своей длиной, закодированной как беззнаковое целое размером n байт (по умолчанию size_t)x: один байт заполненияXop: пустой элемент, который выравнивает в соответствии с опцией op (которая в остальном игнорируется)' ': (пробел) игнорируется
(Запись "[n]" означает необязательное целое число.) За исключением заполнения, пробелов и конфигураций (опции "xX <=>!"), каждая опция соответствует аргументу в string.pack или результату в string.unpack.
Для опций "!n", "sn", "in" и "In" n может быть любым целым числом от 1 до 16. Все целочисленные опции проверяют переполнение; string.pack проверяет, помещается ли данное значение в заданный размер; string.unpack проверяет, помещается ли прочитанное значение в целое число Lua. Для беззнаковых опций целые числа Lua также рассматриваются как беззнаковые.
Любая строка формата начинается так, как если бы перед ней стояло "!1=", то есть с максимальным выравниванием 1 (без выравнивания) и родным порядком байтов.
Родной порядок байтов предполагает, что вся система имеет либо big-endian, либо little-endian порядок. Функции упаковки не будут корректно эмулировать поведение форматов со смешанным порядком байтов.
Выравнивание работает следующим образом: Для каждой опции формат дополняется до тех пор, пока данные не начнутся со смещением, кратным минимуму между размером опции и максимальным выравниванием; этот минимум должен быть степенью двойки. Опции "c" и "z" не выравниваются; опция "s" следует выравниванию своего начального целого.
Все заполнение заполняется нулями в string.pack и игнорируется в string.unpack.
6.6 – Поддержка UTF-8
Эта библиотека предоставляет базовую поддержку кодировки UTF-8. Она предоставляет все свои функции внутри таблицы utf8. Эта библиотека не предоставляет никакой поддержки Unicode, кроме обработки кодировки. Любая операция, требующая знания смысла символа, например, классификация символов, выходит за рамки ее возможностей.
Если не указано иное, все функции, ожидающие позицию в байтах в качестве параметра, предполагают, что данная позиция является либо началом байтовой последовательности, либо длиной строки плюс один. Как и в библиотеке строк, отрицательные индексы отсчитываются от конца строки.
Функции, создающие байтовые последовательности, принимают все значения вплоть до 0x7FFFFFFF, как определено в оригинальной спецификации UTF-8; это подразумевает байтовые последовательности длиной до шести байт.
Функции, интерпретирующие байтовые последовательности, принимают только допустимые последовательности (правильно сформированные и не избыточные). По умолчанию они принимают только байтовые последовательности, дающие допустимые кодовые точки Unicode, отвергая значения больше 10FFFF и суррогаты. Булев аргумент lax, если доступен, отменяет эти проверки, так что принимаются все значения вплоть до 0x7FFFFFFF. (Неправильно сформированные и избыточные последовательности по-прежнему отвергаются.)
utf8.char (···)
Получает ноль или более целых чисел, преобразует каждое в соответствующую ему байтовую последовательность UTF-8 и возвращает строку с конкатенацией всех этих последовательностей.
utf8.charpattern
Образец (строка, а не функция) "[\0-\x7F\xC2-\xFD][\x80-\xBF]*" (см. §6.5.1), который соответствует ровно одной байтовой последовательности UTF-8, при условии, что строка является допустимой строкой UTF-8.
utf8.codes (s [, lax])
Возвращает значения таким образом, что конструкция
for p, c in utf8.codes(s) do body end
будет итерироваться по всем символам UTF-8 в строке s, где p — позиция (в байтах), а c — кодовая точка каждого символа. Вызывает ошибку, если встречает недопустимую байтовую последовательность.
utf8.codepoint (s [, i [, j [, lax]]])
Возвращает кодовые точки (как целые числа) из всех символов в s, которые начинаются между байтовыми позициями i и j (обе включительно). Значение по умолчанию для i — 1, а для j — i. Вызывает ошибку, если встречает недопустимую байтовую последовательность.
utf8.len (s [, i [, j [, lax]]])
Возвращает количество символов UTF-8 в строке s, которые начинаются между позициями i и j (обе включительно). Значение по умолчанию для i — 1, а для j — -1. Если находит недопустимую байтовую последовательность, возвращает fail плюс позицию первого недопустимого байта.
utf8.offset (s, n [, i])
Возвращает позицию n-го символа s (начиная с байтовой позиции i) в виде двух целых чисел: индекс (в байтах), где начинается его кодировка, и индекс (в байтах), где она заканчивается.
Если указанный символ находится сразу после конца s, функция ведет себя так, как если бы там был '\0'. Если указанный символ не находится ни в строке, ни сразу после ее конца, функция возвращает fail.
Отрицательное n получает символы до позиции i. По умолчанию i равно 1, когда n неотрицательно, и #s + 1 в противном случае, так что utf8.offset(s,-n) получает смещение n-го символа с конца строки.
В качестве особого случая, когда n равно 0, функция возвращает начало и конец кодировки символа, который содержит i-й байт s.
Эта функция предполагает, что s является допустимой строкой UTF-8.
6.7 – Манипуляции с таблицами
Эта библиотека предоставляет общие функции для манипуляции таблицами. Она предоставляет все свои функции внутри таблицы table.
Помните, что всякий раз, когда операция требует длины таблицы, применяются все предостережения относительно оператора длины (см. §3.4.7). Все функции игнорируют нечисловые ключи в таблицах, переданных в качестве аргументов.
table.concat (list [, sep [, i [, j]]])
Для списка, где все элементы являются строками или числами, возвращает строку list[i]..sep..list[i+1] ... sep..list[j]. Значение по умолчанию для sep — пустая строка, для i — 1, для j — #list. Если i больше j, возвращает пустую строку.
table.create (nseq [, nrec])
Создает новую пустую таблицу, предварительно выделяя память. Это предварительное выделение может помочь производительности и сэкономить память, если вы заранее знаете, сколько элементов будет в таблице.
Параметр nseq — это подсказка о том, сколько элементов будет в таблице в виде последовательности. Необязательный параметр nrec — это подсказка о том, сколько других элементов будет в таблице; по умолчанию ноль.
table.insert (list, [pos,] value)
Вставляет элемент value в позицию pos в списке list, сдвигая вверх элементы list[pos], list[pos+1], ..., list[#list]. Значение по умолчанию для pos — #list+1, так что вызов table.insert(t,x) вставляет x в конец списка t.
table.move (a1, f, e, t [,a2])
Перемещает элементы из таблицы a1 в таблицу a2, выполняя эквивалент следующего множественного присваивания: a2[t],... = a1[f],...,a1[e]. По умолчанию a2 равна a1. Диапазон назначения может перекрываться с диапазоном источника. Количество перемещаемых элементов должно помещаться в целое число Lua. Если f больше e, ничего не перемещается.
Возвращает таблицу назначения a2.
table.pack (···)
Возвращает новую таблицу со всеми аргументами, сохраненными под ключами 1, 2 и т.д., и с полем "n", содержащим общее количество аргументов. Обратите внимание, что результирующая таблица может не быть последовательностью, если некоторые аргументы равны nil.
table.remove (list [, pos])
Удаляет из списка list элемент в позиции pos, возвращая значение удаленного элемента. Когда pos — целое число между 1 и #list, она сдвигает вниз элементы list[pos+1], list[pos+2], ..., list[#list] и стирает элемент list[#list]; Индекс pos также может быть 0, когда #list равно 0, или #list + 1.
Значение по умолчанию для pos — #list, так что вызов table.remove(l) удаляет последний элемент списка l.
table.sort (list [, comp])
Сортирует элементы списка в заданном порядке, на месте, от list[1] до list[#list]. Если указана comp, она должна быть функцией, которая получает два элемента списка и возвращает true, если первый элемент должен стоять перед вторым в конечном порядке, так что после сортировки i <= j влечет not comp(list[j],list[i]). Если comp не указана, используется стандартный оператор Lua <.
Функция comp должна определять непротиворечивый порядок; более формально, функция должна определять строгий слабый порядок. (Слабый порядок похож на полный порядок, но он может приравнивать разные элементы для целей сравнения.)
Алгоритм сортировки не является стабильным: Различные элементы, считающиеся равными при заданном порядке, могут изменить свое относительное положение в результате сортировки.
table.unpack (list [, i [, j]])
Возвращает элементы из данного списка. Эта функция эквивалентна
return list[i], list[i+1], ..., list[j]
По умолчанию i равно 1, а j равно #list.
6.8 – Математические функции
Эта библиотека предоставляет базовые математические функции. Она предоставляет все свои функции и константы внутри таблицы math. Функции с аннотацией “integer/float” дают целочисленные результаты для целочисленных аргументов и результаты с плавающей точкой для нецелочисленных аргументов. Функции округления math.ceil, math.floor и math.modf возвращают целое число, если результат помещается в диапазон целых чисел, или число с плавающей точкой в противном случае.
math.abs (x)
Возвращает максимальное значение между x и -x. (integer/float)
math.acos (x)
Возвращает арккосинус x (в радианах).
math.asin (x)
Возвращает арксинус x (в радианах).
math.atan (y [, x])
Возвращает арктангенс y/x (в радианах), используя знаки обоих аргументов для определения квадранта результата. Также корректно обрабатывает случай, когда x равен нулю.
Значение по умолчанию для x — 1, так что вызов math.atan(y) возвращает арктангенс y.
math.ceil (x)
Возвращает наименьшее целое значение, большее или равное x.
math.cos (x)
Возвращает косинус x (предполагается, что x в радианах).
math.deg (x)
Преобразует угол x из радиан в градусы.
math.exp (x)
Возвращает значение ex (где e — основание натуральных логарифмов).
math.floor (x)
Возвращает наибольшее целое значение, меньшее или равное x.
math.fmod (x, y)
Возвращает остаток от деления x на y, который округляет частное в сторону нуля. (integer/float)
math.frexp (x)
Возвращает два числа m и e такие, что x = m * 2^e, где e — целое число. Когда x равен нулю, NaN, +inf или -inf, m равен x; в противном случае абсолютное значение m находится в диапазоне [0.5, 1).
math.huge
Значение с плавающей точкой HUGE_VAL, значение, большее любого другого числового значения.
math.ldexp (m, e)
Возвращает m * 2^e, где e — целое число.
math.log (x [, base])
Возвращает логарифм x по заданному основанию base. По умолчанию base равно e (так что функция возвращает натуральный логарифм x).
math.max (x, ···)
Возвращает аргумент с максимальным значением в соответствии с оператором Lua <.
math.maxinteger
Целое число с максимальным значением для целого числа.
math.min (x, ···)
Возвращает аргумент с минимальным значением в соответствии с оператором Lua <.
math.mininteger
Целое число с минимальным значением для целого числа.
math.modf (x)
Возвращает целую часть x и дробную часть x. Ее второй результат всегда является числом с плавающей точкой.
math.pi
Значение π.
math.rad (x)
Преобразует угол x из градусов в радианы.
math.random ([m [, n]])
При вызове без аргументов возвращает псевдослучайное число с плавающей точкой с равномерным распределением в диапазоне [0, 1). При вызове с двумя целыми числами m и n, math.random возвращает псевдослучайное целое число с равномерным распределением в диапазоне [m, n]. Вызов math.random(n) для положительного n эквивалентен math.random(1,n). Вызов math.random(0) производит целое число, в котором все биты (псевдо)случайны.
Эта функция использует алгоритм xoshiro256** для получения псевдослучайных 64-битных целых чисел, которые являются результатами вызовов с аргументом 0. Другие результаты (диапазоны и числа с плавающей точкой) несмещенно извлекаются из этих целых чисел.
Lua инициализирует свой генератор псевдослучайных чисел эквивалентом вызова math.randomseed без аргументов, так что math.random должен генерировать разные последовательности результатов при каждом запуске программы.
math.randomseed ([x [, y]])
При вызове хотя бы с одним аргументом целочисленные параметры x и y объединяются в зерно (seed), которое используется для реинициализации генератора псевдослучайных чисел; одинаковые зерна производят одинаковые последовательности чисел. По умолчанию y равно нулю.
При вызове без аргументов Lua генерирует зерно со слабой попыткой случайности.
Эта функция возвращает два компонента зерна, которые были фактически использованы, так что их повторная установка повторяет последовательность.
Чтобы обеспечить требуемый уровень случайности начального состояния (или, наоборот, иметь детерминированную последовательность, например, при отладке программы), следует вызывать math.randomseed с явными аргументами.
math.sin (x)
Возвращает синус x (предполагается, что x в радианах).
math.sqrt (x)
Возвращает квадратный корень из x. (Вы также можете использовать выражение x^0.5 для вычисления этого значения.)
math.tan (x)
Возвращает тангенс x (предполагается, что x в радианах).
math.tointeger (x)
Если значение x может быть преобразовано в целое число, возвращает это целое число. В противном случае возвращает fail.
math.type (x)
Возвращает "integer", если x — целое число, "float", если это число с плавающей точкой, или fail, если x не является числом.
math.ult (m, n)
Возвращает булево значение, true, если и только если целое число m меньше целого числа n при их сравнении как беззнаковых целых чисел.
6.9 – Средства ввода и вывода
Библиотека ввода/вывода предоставляет два разных стиля для манипуляции файлами. Первый использует неявные файловые дескрипторы; то есть существуют операции для установки файла ввода по умолчанию и файла вывода по умолчанию, и все операции ввода/вывода выполняются с этими файлами по умолчанию. Второй стиль использует явные файловые дескрипторы.
При использовании неявных файловых дескрипторов все операции предоставляются таблицей io. При использовании явных файловых дескрипторов операция io.open возвращает файловый дескриптор, а затем все операции предоставляются как методы файлового дескриптора.
Метатаблица для файловых дескрипторов предоставляет метаметоды __gc и __close, которые пытаются закрыть файл при вызове.
Таблица io также предоставляет три предопределенных файловых дескриптора с их обычными значениями из C: io.stdin, io.stdout и io.stderr. Библиотека ввода/вывода никогда не закрывает эти файлы.
Если не указано иное, все функции ввода/вывода возвращают fail при неудаче плюс сообщение об ошибке в качестве второго результата и системно-зависимый код ошибки в качестве третьего результата, и некоторое значение, отличное от false, при успехе. На не-POSIX системах вычисление сообщения об ошибке и кода ошибки в случае ошибок может быть не потокобезопасным, поскольку они полагаются на глобальную переменную C errno.
io.close ([file])
Эквивалент file:close(). Без файла закрывает файл вывода по умолчанию.
io.flush ()
Эквивалент io.output():flush().
При вызове с именем файла открывает указанный файл (в текстовом режиме) и устанавливает его дескриптор как файл ввода по умолчанию. При вызове с файловым дескриптором просто устанавливает этот файловый дескриптор как файл ввода по умолчанию. При вызове без аргументов возвращает текущий файл ввода по умолчанию.
В случае ошибок эта функция вызывает ошибку вместо возврата кода ошибки.
io.lines ([filename, ···])
Открывает указанный файл в режиме чтения и возвращает функцию-итератор, которая работает как file:lines(...) для открытого файла. Когда функция-итератор не может прочитать ни одного значения, она автоматически закрывает файл. Помимо функции-итератора, io.lines возвращает три других значения: два значения nil в качестве заполнителей и созданный файловый дескриптор. Таким образом, при использовании в общем цикле for файл закрывается, даже если цикл прерывается ошибкой или break.
Вызов io.lines() (без имени файла) эквивалентен io.input():lines("l"); то есть он итерируется по строкам файла ввода по умолчанию. В этом случае итератор не закрывает файл по окончании цикла.
В случае ошибок при открытии файла эта функция вызывает ошибку вместо возврата кода ошибки.
io.open (filename [, mode])
Эта функция открывает файл в режиме, указанном в строке mode. В случае успеха возвращает новый файловый дескриптор.
Строка режима может быть любой из следующих:
"r": режим чтения (по умолчанию);"w": режим записи;"a": режим добавления;"r+": режим обновления, все предыдущие данные сохраняются;"w+": режим обновления, все предыдущие данные стираются;"a+": режим добавления с обновлением, предыдущие данные сохраняются, запись разрешена только в конец файла.
Строка режима может также иметь 'b' в конце, что необходимо в некоторых системах для открытия файла в бинарном режиме.
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 — закрытый файловый дескриптор, или fail, если obj не является файловым дескриптором.
io.write (···)
Эквивалент io.output():write(...).
file:close ()
Закрывает file. Обратите внимание, что файлы автоматически закрываются, когда их дескрипторы собираются сборщиком мусора, но это происходит через непредсказуемый промежуток времени.
При закрытии файлового дескриптора, созданного с помощью io.popen, file:close возвращает те же значения, что и os.execute.
file:flush ()
Сохраняет все записанные данные в файл.
file:lines (···)
Возвращает функцию-итератор, которая при каждом вызове читает файл в соответствии с заданными форматами. Если формат не указан, по умолчанию используется "l". В качестве примера, конструкция
for c in file:lines(1) do body end
будет итерироваться по всем символам файла, начиная с текущей позиции. В отличие от io.lines, эта функция не закрывает файл по окончании цикла.
file:read (···)
Читает файл file в соответствии с заданными форматами, которые указывают, что читать. Для каждого формата функция возвращает строку или число с прочитанными символами, или fail, если не может прочитать данные с указанным форматом. (В этом последнем случае функция не читает последующие форматы.) При вызове без аргументов используется формат по умолчанию, который читает следующую строку (см. ниже).
Доступные форматы:
"n": читает число и возвращает его как число с плавающей точкой или целое число, следуя лексическим соглашениям Lua. (Число может иметь начальные пробелы и знак.) Этот формат всегда читает самую длинную входную последовательность, которая является допустимым префиксом для числа; если этот префикс не образует допустимого числа (например, пустая строка, "0x" или "3.4e-") или он слишком длинный (более 200 символов), он отбрасывается, и формат возвращает fail."a": читает весь файл, начиная с текущей позиции. В конце файла возвращает пустую строку; этот формат никогда не завершается неудачей."l": читает следующую строку, пропуская конец строки, возвращает fail в конце файла. Это формат по умолчанию."L": читает следующую строку, сохраняя символ конца строки (если он есть), возвращает fail в конце файла.- число: читает строку длиной до этого количества байтов, возвращает
fail в конце файла. Если число равно нулю, ничего не читает и возвращает пустую строку или fail в конце файла.
Форматы "l" и "L" следует использовать только для текстовых файлов.
file:seek ([whence [, offset]])
Устанавливает и получает позицию в файле, измеряемую от начала файла, в позицию, заданную как offset плюс база, указанная строкой whence, следующим образом:
"set": база — позиция 0 (начало файла);"cur": база — текущая позиция;"end": база — конец файла;
В случае успеха seek возвращает конечную позицию в файле, измеренную в байтах от начала файла. Если seek терпит неудачу, он возвращает fail плюс строку с описанием ошибки.
Значение по умолчанию для whence — "cur", а для offset — 0. Поэтому вызов file:seek() возвращает текущую позицию в файле, не изменяя ее; вызов file:seek("set") устанавливает позицию в начало файла (и возвращает 0); а вызов file:seek("end") устанавливает позицию в конец файла и возвращает его размер.
file:setvbuf (mode [, size])
Устанавливает режим буферизации для файла. Доступны три режима:
"no": без буферизации."full": полная буферизация."line": построчная буферизация.
Для последних двух случаев size является подсказкой для размера буфера в байтах. По умолчанию используется подходящий размер.
Конкретное поведение каждого режима непереносимо; для получения дополнительной информации проверьте базовую функцию ISO C setvbuf на вашей платформе.
file:write (···)
Записывает значение каждого из своих аргументов в файл. Аргументы должны быть строками или числами.
В случае успеха эта функция возвращает file. В противном случае возвращает четыре значения: fail, сообщение об ошибке, код ошибки и количество байтов, которое удалось записать.
6.10 – Средства операционной системы
Эта библиотека реализована через таблицу os.
os.clock ()
Возвращает приблизительное количество секунд процессорного времени, использованного программой, как возвращается базовой функцией ISO C clock.
Возвращает строку или таблицу, содержащую дату и время, отформатированные в соответствии с заданной строкой format.
Если аргумент time присутствует, это время, которое должно быть отформатировано (см. описание этого значения в функции os.time). В противном случае date форматирует текущее время.
Если format начинается с '!', то дата форматируется во Всемирном координированном времени (UTC). После этого необязательного символа, если format — строка "*t", то date возвращает таблицу со следующими полями: year, month (1–12), day (1–31), hour (0–23), min (0–59), sec (0–61, из-за високосных секунд), wday (день недели, 1–7, воскресенье — 1), yday (день года, 1–366) и isdst (флаг летнего времени, булево значение). Это последнее поле может отсутствовать, если информация недоступна.
Если format не "*t", то date возвращает дату как строку, отформатированную по тем же правилам, что и функция ISO C strftime.
Если format отсутствует, по умолчанию используется "%c", что дает удобочитаемое представление даты и времени с использованием текущей локали.
На не-POSIX системах эта функция может быть не потокобезопасной из-за зависимости от функций C gmtime и localtime.
os.difftime (t2, t1)
Возвращает разницу в секундах между временем t1 и временем t2 (где времена являются значениями, возвращенными os.time). В POSIX, Windows и некоторых других системах это значение точно равно t2-t1.
os.execute ([command])
Эта функция эквивалентна функции ISO C system. Она передает command для выполнения оболочке операционной системы. Ее первый результат — true, если команда завершилась успешно, или fail в противном случае. После этого первого результата функция возвращает строку и число следующим образом:
"exit": команда завершилась нормально; следующее число — это статус выхода команды."signal": команда была завершена сигналом; следующее число — это сигнал, завершивший команду.
При вызове без команды os.execute возвращает булево значение, которое равно true, если оболочка доступна.
os.exit ([code [, close]])
Вызывает функцию ISO C exit для завершения главной программы. Если code равно true, возвращаемый статус — EXIT_SUCCESS; если code равно false, возвращаемый статус — EXIT_FAILURE; если code — число, возвращаемый статус — это число. Значение по умолчанию для code — true.
Если необязательный второй аргумент close равен true, функция закрывает состояние Lua перед выходом (см. lua_close).
os.getenv (varname)
Возвращает значение переменной окружения процесса varname или fail, если переменная не определена.
os.remove (filename)
Удаляет файл (или пустой каталог в POSIX-системах) с заданным именем. Если эта функция терпит неудачу, она возвращает fail плюс строку с описанием ошибки и код ошибки. В противном случае возвращает true.
os.rename (oldname, newname)
Переименовывает файл или каталог с именем oldname в newname. Если эта функция терпит неудачу, она возвращает fail плюс строку с описанием ошибки и код ошибки. В противном случае возвращает true.
os.setlocale (locale [, category])
Устанавливает текущую локаль программы. locale — это системно-зависимая строка, указывающая локаль; category — необязательная строка, описывающая, какую категорию изменить: "all", "collate", "ctype", "monetary", "numeric" или "time"; категория по умолчанию — "all". Функция возвращает имя новой локали или fail, если запрос не может быть выполнен.
Если locale — пустая строка, текущая локаль устанавливается в определенную реализацией родную локаль. Если locale — строка "C", текущая локаль устанавливается в стандартную локаль C.
При вызове с nil в качестве первого аргумента эта функция только возвращает имя текущей локали для заданной категории.
Эта функция может быть не потокобезопасной из-за зависимости от функции C setlocale.
os.time ([table])
Возвращает текущее местное время при вызове без аргументов или время, представляющее местные дату и время, заданные данной таблицей. Эта таблица должна иметь поля year, month и day и может иметь поля hour (по умолчанию 12), min (по умолчанию 0), sec (по умолчанию 0) и isdst (по умолчанию nil). Другие поля игнорируются. Описание этих полей см. в функции os.date.
При вызове функции значения в этих полях не обязаны находиться внутри своих допустимых диапазонов. Например, если sec равно -10, это означает 10 секунд до времени, указанного другими полями; если hour равно 1000, это означает 1000 часов после времени, указанного другими полями.
Возвращаемое значение — это число, значение которого зависит от вашей системы. В POSIX, Windows и некоторых других системах это число отсчитывает количество секунд с некоторого заданного начального момента времени (“эпохи”). В других системах значение не определено, и число, возвращаемое time, может использоваться только в качестве аргумента для os.date и os.difftime.
При вызове с таблицей os.time также нормализует все поля, задокументированные в функции os.date, так что они представляют то же самое время, что и до вызова, но со значениями внутри допустимых диапазонов.
os.tmpname ()
Возвращает строку с именем файла, которое можно использовать для временного файла. Файл должен быть явно открыт перед использованием и явно удален, когда больше не нужен.
В POSIX-системах эта функция также создает файл с этим именем, чтобы избежать рисков безопасности. (Кто-то другой может создать файл с неправильными разрешениями за время между получением имени и созданием файла.) Вам все равно нужно открыть файл для его использования и удалить его (даже если вы его не используете).
По возможности лучше использовать io.tmpfile, которая автоматически удаляет файл по завершении программы.
6.11 – Библиотека отладки
Эта библиотека предоставляет функциональность отладочного интерфейса (§4.7) программам Lua. Следует проявлять осторожность при использовании этой библиотеки. Некоторые из ее функций нарушают базовые предположения о коде Lua (например, что к локальным переменным функции нельзя получить доступ извне; что метатаблицы пользовательских данных не могут быть изменены кодом Lua; что программы Lua не падают) и, следовательно, могут скомпрометировать в остальном безопасный код. Более того, некоторые функции в этой библиотеке могут быть медленными.
Все функции в этой библиотеке предоставляются внутри таблицы debug. Все функции, работающие с потоком, имеют необязательный первый аргумент — поток, с которым нужно работать. По умолчанию всегда используется текущий поток.
debug.debug ()
Входит в интерактивный режим с пользователем, выполняя каждую строку, которую вводит пользователь. Используя простые команды и другие средства отладки, пользователь может проверять глобальные и локальные переменные, изменять их значения, вычислять выражения и т.д. Строка, содержащая только слово cont, завершает эту функцию, так что вызывающий код продолжает свое выполнение.
Обратите внимание, что команды для debug.debug лексически не вложены ни в какую функцию и поэтому не имеют прямого доступа к локальным переменным.
debug.gethook ([thread])
Возвращает текущие настройки перехватчика (hook) для потока в виде трех значений: текущая функция перехватчика, текущая маска перехватчика и текущий счетчик перехватчика, как установлено функцией debug.sethook.
Возвращает fail, если активного перехватчика нет.
debug.getinfo ([thread,] f [, what])
Возвращает таблицу с информацией о функции. Вы можете передать функцию напрямую или передать число в качестве значения f, что означает функцию, выполняющуюся на уровне f стека вызовов данного потока: уровень 0 — текущая функция (сама getinfo); уровень 1 — функция, вызвавшая getinfo (за исключением хвостовых вызовов, которые не учитываются в стеке); и так далее. Если f — число, превышающее количество активных функций, getinfo возвращает fail.
Возвращаемая таблица может содержать все поля, возвращаемые lua_getinfo, при этом строка what описывает, какие поля следует заполнить. По умолчанию для what запрашивается вся доступная информация, кроме таблицы допустимых строк. Опция 'f' добавляет поле с именем func с самой функцией. Опция 'L' добавляет поле с именем activelines с таблицей допустимых строк, при условии, что функция является Lua-функцией. Если у функции нет отладочной информации, таблица пуста.
Например, выражение debug.getinfo(1,"n").name возвращает имя для текущей функции, если подходящее имя может быть найдено, а выражение debug.getinfo(print) возвращает таблицу со всей доступной информацией о функции print.
debug.getlocal ([thread,] f, local)
Эта функция возвращает имя и значение локальной переменной с индексом local функции на уровне f стека. Эта функция получает доступ не только к явным локальным переменным, но также к параметрам и временным значениям.
Первый параметр или локальная переменная имеет индекс 1, и так далее, в порядке их объявления в коде, при этом учитываются только переменные, активные в текущей области видимости функции. Константы времени компиляции могут не появляться в этом списке, если они были оптимизированы компилятором. Отрицательные индексы относятся к аргументам vararg; -1 — это первый аргумент vararg. Эти отрицательные индексы доступны только тогда, когда таблица vararg была оптимизирована; в противном случае аргументы vararg доступны в таблице vararg.
Функция возвращает fail, если нет переменной с заданным индексом, и вызывает ошибку при вызове с уровнем вне диапазона. (Вы можете вызвать debug.getinfo, чтобы проверить, допустим ли уровень.)
Имена переменных, начинающиеся с '(' (открывающая скобка), представляют переменные без известных имен (внутренние переменные, такие как переменные управления циклом, и переменные из чанков, сохраненных без отладочной информации).
Параметр f также может быть функцией. В этом случае getlocal возвращает только имена параметров функции.
Возвращает метатаблицу данного значения или nil, если у него нет метатаблицы.
debug.getregistry ()
Возвращает таблицу реестра (см. §4.3).
debug.getupvalue (f, up)
Эта функция возвращает имя и значение верхнего значения (upvalue) с индексом up функции f. Функция возвращает fail, если нет верхнего значения с заданным индексом.
(Для Lua-функций верхние значения — это внешние локальные переменные, которые использует функция и которые, следовательно, включены в ее замыкание.)
Для C-функций эта функция использует пустую строку "" в качестве имени для всех верхних значений.
Имя переменной '?' (вопросительный знак) представляет переменные без известных имен (переменные из чанков, сохраненных без отладочной информации).
debug.getuservalue (u, n)
Возвращает n-е пользовательское значение, связанное с пользовательскими данными u, плюс булево значение, false, если пользовательские данные не имеют этого значения.
debug.sethook ([thread,] hook, mask [, count])
Устанавливает заданную функцию в качестве отладочного перехватчика (hook). Строка mask и число count описывают, когда будет вызываться перехватчик. Строка mask может иметь любую комбинацию следующих символов с заданным значением:
'c': перехватчик вызывается каждый раз, когда Lua вызывает функцию;'r': перехватчик вызывается каждый раз, когда Lua возвращается из функции;'l': перехватчик вызывается каждый раз, когда Lua переходит на новую строку кода.
Более того, при count, отличном от нуля, перехватчик вызывается также после каждых count инструкций.
При вызове без аргументов debug.sethook отключает перехватчик.
При вызове перехватчика его первым параметром является строка, описывающая событие, вызвавшее его срабатывание: "call", "tail call", "return", "line" и "count". Для событий "line" перехватчик также получает номер новой строки в качестве второго параметра. Внутри перехватчика вы можете вызвать getinfo с уровнем 2, чтобы получить больше информации о выполняющейся функции. (Уровень 0 — это функция getinfo, а уровень 1 — функция перехватчика.)
debug.setlocal ([thread,] level, local, value)
Эта функция присваивает значение value локальной переменной с индексом local функции на уровне level стека. Функция возвращает fail, если нет локальной переменной с заданным индексом, и вызывает ошибку при вызове с уровнем вне диапазона. (Вы можете вызвать getinfo, чтобы проверить, допустим ли уровень.) В противном случае возвращает имя локальной переменной.
См. debug.getlocal для получения дополнительной информации об индексах и именах переменных.
Устанавливает метатаблицу для данного значения в заданную таблицу (которая может быть nil). Возвращает value.
debug.setupvalue (f, up, value)
Эта функция присваивает значение value верхнему значению (upvalue) с индексом up функции f. Функция возвращает fail, если нет верхнего значения с заданным индексом. В противном случае возвращает имя верхнего значения.
См. debug.getupvalue для получения дополнительной информации о верхних значениях.
debug.setuservalue (udata, value, n)
Устанавливает данное значение в качестве n-го пользовательского значения, связанного с данными udata. udata должны быть полными пользовательскими данными (full userdata).
Возвращает udata или fail, если пользовательские данные не имеют этого значения.
debug.traceback ([thread,] [message [, level]])
Если message присутствует, но не является ни строкой, ни nil, эта функция возвращает message без дальнейшей обработки. В противном случае она возвращает строку с трассировкой стека вызовов. Необязательная строка message добавляется в начало трассировки. Необязательный номер level указывает, с какого уровня начинать трассировку (по умолчанию 1, функция, вызывающая traceback).
debug.upvalueid (f, n)
Возвращает уникальный идентификатор (как легкие пользовательские данные — light userdata) для верхнего значения с номером n из данной функции.
Эти уникальные идентификаторы позволяют программе проверять, разделяют ли разные замыкания верхние значения. Замыкания Lua, которые разделяют верхнее значение (то есть обращаются к одной и той же внешней локальной переменной), вернут идентичные идентификаторы для этих индексов верхних значений.
debug.upvaluejoin (f1, n1, f2, n2)
Делает так, что n1-е верхнее значение Lua-замыкания f1 ссылается на n2-е верхнее значение Lua-замыкания f2.
6 - 7 – Lua как самостоятельное приложение
Использование интерпретатора Lua из командной строки, аргументы, интерактивный режим и переменные окружения.
Оглавление
- Использование интерпретатора
- Несовместимости с предыдущей версией
- Полный синтаксис Lua
7 – Lua как самостоятельное приложение
Хотя Lua был разработан как язык расширения для встраивания в хост-программу на C, он также часто используется как самостоятельный язык. Интерпретатор для Lua как самостоятельного языка, называемый просто lua, поставляется со стандартным дистрибутивом. Автономный интерпретатор включает все стандартные библиотеки. Его использование:
lua [options] [script [args]]
Опции следующие:
-e stat: выполнить строку stat;-i: войти в интерактивный режим после выполнения скрипта;-l mod: выполнить require "mod" и присвоить результат глобальной переменной mod;-l g=mod: выполнить require "mod" и присвоить результат глобальной переменной g;-v: вывести информацию о версии;-E: игнорировать переменные окружения;-W: включить предупреждения;--: прекратить обработку опций;-: выполнить стандартный ввод (stdin) как файл и прекратить обработку опций.
После обработки своих опций lua запускает указанный скрипт. При вызове без аргументов lua ведет себя как lua -v -i, если стандартный ввод (stdin) является терминалом, и как lua - в противном случае.
При вызове без опции -E интерпретатор проверяет переменную окружения LUA_INIT_5_5 (или LUA_INIT, если версионированное имя не определено) перед выполнением любого аргумента. Если содержимое переменной имеет формат @filename, то lua выполняет этот файл. В противном случае lua выполняет саму строку.
При вызове с опцией -E Lua не проверяет никакие переменные окружения. В частности, значения package.path и package.cpath устанавливаются с путями по умолчанию, определенными в luaconf.h. Чтобы сигнализировать библиотекам, что эта опция включена, автономный интерпретатор устанавливает поле "LUA_NOENV" в реестре в истинное значение. Другие библиотеки могут проверять это поле с той же целью.
Опции -e, -l и -W обрабатываются в порядке их появления. Например, вызов вида
$ lua -e 'a=1' -llib1 script.lua
сначала установит a в 1, затем выполнит require для библиотеки lib1 и, наконец, запустит файл script.lua без аргументов. (Здесь $ — приглашение командной оболочки. Ваше приглашение может отличаться).
Перед выполнением любого кода lua собирает все аргументы командной строки в глобальную таблицу arg. Имя скрипта помещается в индекс 0, первый аргумент после имени скрипта — в индекс 1, и так далее. Любые аргументы перед именем скрипта (то есть имя интерпретатора плюс его опции) помещаются в отрицательные индексы. Например, в вызове
$ lua -la b.lua t1 t2
таблица выглядит так:
arg = { [-2] = "lua", [-1] = "-la",
[0] = "b.lua",
[1] = "t1", [2] = "t2" }
Если в вызове нет скрипта, имя интерпретатора помещается в индекс 0, за ним следуют остальные аргументы. Например, вызов
$ lua -e "print(arg[1])"
выведет "-e". Если есть скрипт, скрипт вызывается с аргументами arg[1], ···, arg[#arg]. Как и все чанки в Lua, скрипт компилируется как вариадическая функция.
В интерактивном режиме Lua многократно выводит приглашение и ожидает строку. После чтения строки Lua сначала пытается интерпретировать строку как выражение. Если это удается, он выводит его значение. В противном случае он интерпретирует строку как чанк. Если вы вводите незавершенный чанк, интерпретатор ожидает его завершения, выдавая другое приглашение.
Обратите внимание, что, поскольку каждая полная строка читается как новый чанк, локальные переменные не переживают строки. Чтобы избежать путаницы, интерпретатор выдает предупреждение, если строка начинается с зарезервированного слова local:
> x = 20 -- глобальная 'x'
> local x = 10; print(x)
--> warning: locals do not survive across lines in interactive mode
--> 10
> print(x) -- снова глобальная 'x'
--> 20
> do -- незавершенный чанк
>> local x = 10; print(x) -- '>>' приглашение для завершения строки
>> print(x)
>> end -- чанк завершен
--> 10
--> 10
Если глобальная переменная _PROMPT содержит строку, то ее значение используется в качестве приглашения. Аналогично, если глобальная переменная _PROMPT2 содержит строку, ее значение используется в качестве вторичного приглашения (выдаваемого во время незавершенных инструкций).
В случае незащищенных ошибок в скрипте интерпретатор сообщает об ошибке в стандартный поток ошибок. Если объект ошибки не является строкой, но имеет метаметод __tostring, интерпретатор вызывает этот метаметод для создания итогового сообщения. В противном случае интерпретатор преобразует объект ошибки в строку и добавляет к нему трассировку стека. Когда предупреждения включены, они просто выводятся в стандартный вывод ошибок.
При нормальном завершении интерпретатор закрывает свое главное состояние Lua (см. lua_close). Скрипт может избежать этого шага, вызвав os.exit для завершения.
Чтобы позволить использовать Lua в качестве интерпретатора скриптов в системах Unix, Lua пропускает первую строку файла чанка, если она начинается с #. Поэтому Lua-скрипты можно сделать исполняемыми программами, используя chmod +x и форму #!, как в
#!/usr/local/bin/lua
Конечно, расположение интерпретатора Lua на вашей машине может отличаться. Если lua находится в вашем PATH, то
#!/usr/bin/env lua
является более переносимым решением.
8 – Несовместимости с предыдущей версией
Здесь мы перечисляем несовместимости, с которыми вы можете столкнуться при переходе программы с Lua 5.4 на Lua 5.5.
Вы можете избежать некоторых несовместимостей, скомпилировав Lua с соответствующими опциями (см. файл luaconf.h). Однако все эти опции совместимости будут удалены в будущем. Чаще всего проблемы совместимости возникают именно при удалении этих опций. Поэтому, когда у вас есть возможность, старайтесь тестировать свой код с версией Lua, скомпилированной со всеми отключенными опциями совместимости. Это облегчит переходы на более новые версии Lua.
Версии Lua всегда могут изменять C API способами, которые не подразумевают изменений в исходном коде программы, например, числовые значения констант или реализацию функций в виде макросов. Поэтому никогда не следует предполагать, что двоичные файлы совместимы между разными версиями Lua. Всегда перекомпилируйте клиентов Lua API при использовании новой версии.
Аналогично, версии Lua всегда могут изменять внутреннее представление предварительно скомпилированных чанков; предкомпилированные чанки несовместимы между разными версиями Lua.
Стандартные пути в официальном дистрибутиве могут меняться между версиями.
8.1 – Несовместимости в языке
- Слово
global является зарезервированным словом. Не используйте его как обычное имя. - Управляющая переменная в циклах
for доступна только для чтения. Если вам нужно ее изменить, объявите локальную переменную с тем же именем в теле цикла. - Цепочка метаметодов
__call может содержать не более 15 объектов. - При ошибке
nil в качестве объекта ошибки заменяется строковым сообщением.
8.2 – Несовместимости в библиотеках
- Параметры сборки мусора не устанавливаются опциями
"incremental" и "generational"; вместо этого для этой цели есть новая опция "param". Более того, были внесены некоторые изменения в сами параметры.
8.3 – Несовместимости в API
- В
lua_call и связанных функциях максимальное значение для количества требуемых результатов (nresults) составляет 250. Если вам действительно нужно большее значение, используйте LUA_MULTRET, а затем настройте размер стека. Ранее этот предел не был указан. lua_newstate имеет третий параметр — начальное значение для хеширования строк.- Функция
lua_resetthread устарела; она эквивалентна lua_closethread с from, равным NULL. - Функция
lua_setcstacklimit устарела. Вызовы к ней можно просто удалить. - Функция
lua_dump изменила способ сохранения стека при вызовах функции-писателя. (Это не было указано в предыдущих версиях). Кроме того, она вызывает функцию-писатель один дополнительный раз, чтобы сигнализировать о конце дампа. - Параметры сборки мусора не устанавливаются опциями
LUA_GCINC и LUA_GCGEN; вместо этого для этой цели есть новая опция LUA_GCPARAM. Более того, были внесены некоторые изменения в сами параметры. - Функция
lua_pushvfstring теперь сообщает об ошибках, а не возбуждает их.
9 – Полный синтаксис Lua
Здесь представлен полный синтаксис Lua в расширенной БНФ. Как обычно в расширенной БНФ, {A} означает 0 или более A, а [A] означает необязательное A. (Приоритеты операторов см. в §3.4.8; описание терминалов Name, Numeral и LiteralString см. в §3.1).
chunk ::= block
block ::= {stat} [retstat]
stat ::= ‘;’ |
varlist ‘=’ explist |
functioncall |
label |
break |
goto Name |
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 |
global function Name funcbody |
local attnamelist [‘=’ explist] |
global attnamelist |
global [attrib] ‘*’
attnamelist ::= [attrib] Name [attrib] {‘,’ Name [attrib]}
attrib ::= ‘<’ Name ‘>’
retstat ::= return [explist] [‘;’]
label ::= ‘::’ Name ‘::’
funcname ::= Name {‘.’ Name} [‘:’ Name]
varlist ::= var {‘,’ var}
var ::= Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name
namelist ::= Name {‘,’ Name}
explist ::= exp {‘,’ exp}
exp ::= nil | false | true | Numeral | LiteralString | ‘...’ | functiondef |
prefixexp | tableconstructor | exp binop exp | unop exp
prefixexp ::= var | functioncall | ‘(’ exp ‘)’
functioncall ::= prefixexp args | prefixexp ‘:’ Name args
args ::= ‘(’ [explist] ‘)’ | tableconstructor | LiteralString
functiondef ::= function funcbody
funcbody ::= ‘(’ [parlist] ‘)’ block end
parlist ::= namelist [‘,’ varargparam] | varargparam
varargparam ::= ‘...’ [Name]
tableconstructor ::= ‘{’ [fieldlist] ‘}’
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
fieldsep ::= ‘,’ | ‘;’
binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘//’ | ‘^’ | ‘%’ |
‘&’ | ‘~’ | ‘|’ | ‘>>’ | ‘<<’ | ‘..’ |
‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ |
and | or
unop ::= ‘-’ | not | ‘#’ | ‘~’