Справочник по Lua 5.4
авторы: Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
1 – Введение
Lua — мощный, эффективный, лёгкий встраиваемый скриптовый язык. Он поддерживает процедурное, объектно-ориентированное, функциональное, управляемое данными программирование и описание данных.
Lua сочетает простой процедурный синтаксис с мощными конструкциями описания данных, основанными на ассоциативных массивах и расширяемой семантике. Lua имеет динамическую типизацию, выполняется путём интерпретации байткода с помощью виртуальной машины на основе регистров и имеет автоматическое управление памятью с поколенческой сборкой мусора, что делает его идеальным для конфигурации, скриптинга и быстрого прототипирования.
Lua реализован как библиотека, написанная на чистом C, общем подмножестве стандартов C и C++. Распространение Lua включает программу-хост, называемую lua, которая использует библиотеку Lua для обеспечения полного автономного интерпретатора Lua для интерактивного или пакетного использования. Lua предназначен для использования как мощного, лёгкого встраиваемого скриптового языка для любой программы, которая нуждается в нём, так и как мощный, но лёгкий и эффективный автономный язык.
Как язык расширения, Lua не имеет понятия о программе «main»: он работает встроенным в программу-клиент-хост, называемую программой-встраивателем или просто хостом. (Часто этот хост — автономная lua программа.) Программа-хост может вызывать функции для выполнения фрагмента кода Lua, записывать и читать переменные Lua и регистрировать функции C, которые будут вызываться кодом Lua. С помощью функций C Lua можно расширить, чтобы справиться с широким кругом различных областей, создавая таким образом пользовательские языки программирования, разделяющие синтаксический каркас.
Lua — свободное программное обеспечение, и предоставляется, как обычно, без каких-либо гарантий, как указано в его лицензии. Реализация, описанная в этом руководстве, доступна на официальном веб-сайте Lua, www.lua.org.
Как и любой другой справочник, этот документ местами сухой. Для обсуждения решений, лежащих в основе проектирования Lua, см. технические статьи, доступные на веб-сайте Lua. Для подробного знакомства с программированием на Lua см. книгу Роберто, Программирование на Lua.
2 – Основные понятия
В этом разделе описываются основные понятия языка.
2.1 – Значения и типы
Lua — язык с динамической типизацией. Это означает, что переменные не имеют типов; типы имеют только значения. В языке нет определений типов. Все значения несут свой собственный тип.
Все значения в Lua являются значениями первого класса. Это означает, что все значения могут храниться в переменных, передаваться в качестве аргументов другим функциям и возвращаться в качестве результатов.
В Lua есть восемь основных типов: nil, boolean, number, string, function, userdata, thread и table. Тип nil имеет единственное значение, nil, основное свойство которого — отличаться от любого другого значения; он часто представляет собой отсутствие полезного значения. Тип boolean имеет два значения, false и true. Как nil, так и false делают условие ложным; они вместе называются ложными значениями. Любое другое значение делает условие истинным.
Тип 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, только через API C. Это гарантирует целостность данных, принадлежащих программе-хосту и библиотекам 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).
Индексация таблиц следует определению жёсткого равенства в языке. Выражения a[i] и a[j] обозначают один и тот же элемент таблицы только тогда, когда i и j жёстко равны (то есть равны без метаметодов). В частности, числа с плавающей точкой со значением целого числа равны своим соответствующим целым числам (например, 1.0 == 1). Чтобы избежать неоднозначностей, любое число с плавающей точкой, используемое в качестве ключа, равное целому числу, преобразуется в это целое число. Например, если вы напишете a[2.0] = true, фактический ключ, вставленный в таблицу, будет целым числом 2.
Таблицы, функции, потоки и (полные) значения userdata являются объектами: переменные фактически не содержат эти значения, только ссылки на них. Присваивание, передача параметров и возвращение функций всегда манипулируют ссылками на такие значения; эти операции не подразумевают никаких копий.
Функция библиотеки type возвращает строку, описывающую тип заданного значения (см. type).
2.2 – Окружения и глобальное окружение
Как мы обсудим далее в §3.2 и §3.3.3, любая ссылка на свободное имя (то есть имя, не связанное ни с каким объявлением) var синтаксически преобразуется в _ENV.var. Кроме того, каждый фрагмент компилируется в области видимости внешней локальной переменной с именем _ENV (см. §3.3.2), поэтому _ENV само по себе никогда не является свободным именем в фрагменте.
Несмотря на существование этой внешней _ENV переменной и преобразование свободных имён, _ENV — это совершенно обычное имя. В частности, вы можете определять новые переменные и параметры с этим именем. Каждая ссылка на свободное имя использует _ENV , которое видно в этот момент программы, следуя обычным правилам видимости Lua (см. §3.5).
Любая таблица, используемая в качестве значения _ENV , называется окружением.
Lua сохраняет выделенное окружение, называемое глобальным окружением. Это значение сохраняется в специальном индексе в реестре C (см. §4.3). В Lua глобальная переменная _G инициализируется этим же значением. (_G никогда не используется в коде интерпретатора, поэтому изменение её значения повлияет только на ваш собственный код.)
Когда Lua загружает фрагмент, значение по умолчанию для его _ENV переменной — глобальное окружение (см. load). Следовательно, по умолчанию свободные имена в коде Lua относятся к записям в глобальном окружении и, следовательно, также называются глобальными переменными. Кроме того, все стандартные библиотеки загружаются в глобальное окружение, и некоторые функции там работают с этим окружением. Вы можете использовать load (или loadfile), чтобы загрузить фрагмент с другим окружением. (В C вам нужно загрузить фрагмент, а затем изменить значение его первого дополнительного значения; см. 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", а метаметод — функция, которая выполняет сложение.
Вы можете получить доступ к метатаблице любого значения, используя функцию getmetatable. Lua запрашивает метаметоды в метатаблицах с использованием прямого доступа (см. rawget).
Вы можете заменить метатаблицу таблиц с помощью функции setmetatable. Вы не можете изменить метатаблицу других типов из кода Lua, за исключением использования библиотеки отладки (§6.10).
Таблицы и полные пользовательские данные имеют отдельные метатаблицы, хотя несколько таблиц и пользовательских данных могут совместно использовать свои метатаблицы. Значения всех других типов совместно используют одну единственную метатаблицу на тип; то есть, есть одна единственная метатаблица для всех чисел, одна для всех строк и т. д. По умолчанию значение не имеет метатаблицы, но библиотека строк устанавливает метатаблицу для типа строка (см. §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 попытается найти метаметод только когда сравниваемые значения являются либо обеими таблицами, либо обеими полными пользовательскими данными, и они не являются примитивно равными. Результат вызова всегда преобразуется в булево значение.__lt: операция меньше (<). Поведение аналогично операции сложения, за исключением того, что Lua попытается найти метаметод только когда сравниваемые значения не являются оба числами или обеими строками. Кроме того, результат вызова всегда преобразуется в булево значение.__le: операция меньше или равно (<=). Поведение аналогично операции меньше.__index: Операция индексированияtable[key]. Это событие происходит, когдаtableне является таблицей или когдаkeyне присутствует вtable. Метазначение ищется в метатаблицеtable.Метазначение для этого события может быть либо функцией, таблицей, или любым значением с метаметодом
__index. Если это функция, она вызывается сtableиkeyв качестве аргументов, и результат вызова (отрегулированный до одного значения) — результат операции. В противном случае конечный результат — результат индексирования этого метазначения с помощьюkey. Это индексирование обычное, а не прямое, и, следовательно, может вызвать другой метаметод__index.__newindex: Операция присваивания индексированияtable[key] = value. Подобно событию индексирования, это событие происходит, когдаtableне является таблицей или когдаkeyне присутствует вtable. Метазначение ищется в метатаблицеtable.Как и с индексированием, метазначение для этого события может быть либо функцией, таблицей, или любым значением с метаметодом
__newindex. Если это функция, она вызывается сtable,key, иvalueв качестве аргументов. В противном случае Lua повторяет присваивание индекса по этому метазначению с тем же ключом и значением. Это присваивание обычное, а не прямое, и, следовательно, может вызвать другой метаметод__newindex.Всякий раз, когда вызывается метаметод
__newindex, Lua не выполняет примитивное присваивание. Если это необходимо, сам метаметод может вызватьrawsetдля выполнения присваивания.__call: Операция вызоваfunc(args). Это событие происходит, когда Lua пытается вызвать нефункциональное значение (то есть,funcне является функцией). Метаметод ищется вfunc. Если он присутствует, метаметод вызывается сfuncв качестве первого аргумента, за которым следуют аргументы исходного вызова (args). Все результаты вызова — результаты операции. Это единственный метаметод, который позволяет несколько результатов.
В дополнение к предыдущему списку, интерпретатор также учитывает следующие ключи в метатаблицах: __gc (см. §2.5.3), __close (см. §3.3.8), __mode (см. §2.5.4), и __name. (Запись __name, когда она содержит строку, может использоваться tostring и в сообщениях об ошибках.)
Для унарных операторов (отрицание, длина и побитовое НЕ) метаметод вычисляется и вызывается с фиктивным вторым операндом, равным первому. Этот дополнительный операнд нужен только для упрощения внутренней работы Lua (делая эти операторы похожими на бинарную операцию) и может быть удален в будущих версиях. Для большинства случаев этот дополнительный операнд не имеет значения.
Поскольку метатаблицы — это обычные таблицы, они могут содержать произвольные поля, а не только имена событий, определённые выше. Некоторые функции стандартной библиотеки (например, tostring) используют другие поля в метатаблицах для своих целей.
Хорошей практикой является добавление всех необходимых метаметодов в таблицу перед её назначением в качестве метатаблицы какого-либо объекта. В частности, метаметод __gc работает только при соблюдении этого порядка (см. §2.5.3). Также хорошей практикой является установка метатаблицы объекта сразу после его создания.
2.5 – Уборка мусора
Lua выполняет автоматическое управление памятью. Это означает, что вам не нужно беспокоиться об выделении памяти для новых объектов или освобождении её, когда объекты больше не нужны. Lua автоматически управляет памятью, запуская сборщик мусора для сбора всех мертвых объектов. Вся память, используемая Lua, подлежит автоматическому управлению: строки, таблицы, пользовательские данные, функции, потоки, внутренние структуры и т. д.
Объект считается мертвым, как только сборщик мусора может гарантировать, что к объекту больше не будет доступа во время нормального выполнения программы. («Нормальное выполнение» здесь исключает финализаторы, которые могут возродить мертвые объекты (см. §2.5.3), а также операции с использованием библиотеки отладки.) Обратите внимание, что время, когда сборщик мусора может быть уверен, что объект мертв, может не совпадать с ожиданиями программиста. Единственными гарантиями являются то, что Lua не соберет объект, к которому все еще можно получить доступ при нормальном выполнении программы, и что в конечном итоге он соберет объект, недоступный из Lua. (Здесь недоступность из Lua означает, что ни переменная, ни другой живой объект не ссылаются на объект.) Поскольку Lua не имеет информации о коде C, он никогда не собирает объекты, доступные через реестр (см. §4.3), что включает глобальную среду (см. §2.2).
Сборщик мусора (GC) в Lua может работать в двух режимах: инкрементальном и генерационном.
Режим GC по умолчанию с параметрами по умолчанию подходит для большинства случаев. Однако программы, которые тратят большую часть своего времени на выделение и освобождение памяти, могут извлечь выгоду из других настроек. Имейте в виду, что поведение GC не переносимо как между платформами, так и между различными версиями Lua; следовательно, оптимальные настройки также не переносимы.
Вы можете изменить режим GC и параметры, вызвав lua_gc на C или collectgarbage в Lua. Вы также можете использовать эти функции для непосредственного управления сборщиком мусора (например, для остановки и перезапуска).
2.5.1 – Инкрементальный сбор мусора
В инкрементальном режиме каждый цикл GC выполняет сборку по принципу «помечать и очищать» небольшими шагами, чередующимися с выполнением программы. В этом режиме сборщик мусора использует три числа для управления циклами сбора мусора: пауза сборщика мусора, множитель шага сборщика мусора и размер шага сборщика мусора.
Пауза сборщика мусора определяет, как долго сборщик ждет перед запуском нового цикла. Сборщик запускает новый цикл, когда использование памяти достигает n% от использования после предыдущего сбора. Более высокие значения делают сборщик менее агрессивным. Значения, равные или меньшие 100, означают, что сборщик не будет ждать начала нового цикла. Значение 200 означает, что сборщик ждет удвоения общего использования памяти перед запуском нового цикла. Значение по умолчанию составляет 200; максимальное значение — 1000.
Множитель шага сборщика мусора управляет скоростью сборщика относительно выделения памяти, то есть сколько элементов он помечает или очищает на каждый килобайт выделенной памяти. Более высокие значения делают сборщик более агрессивным, но также увеличивают размер каждого инкрементального шага. Не следует использовать значения меньше 100, так как они делают сборщик слишком медленным и могут привести к тому, что сборщик никогда не завершит цикл. Значение по умолчанию равно 100; максимальное значение — 1000.
Размер шага сборщика мусора управляет размером каждого инкрементального шага, то есть, сколько байтов интерпретатор выделяет перед выполнением шага. Этот параметр является логарифмическим: значение n означает, что интерпретатор выделит 2n байтов между шагами и выполнит эквивалентную работу во время шага. Большое значение (например, 60) делает сборщик «с остановкой мира» (не инкрементальным). Значение по умолчанию равно 13, что означает шаги примерно по 8 Кбайт.
2.5.2 – Генерационный сбор мусора
В генерационном режиме сборщик выполняет частые небольшие сборы, которые обрабатывают только недавно созданные объекты. Если после небольшого сбора использование памяти все еще превышает предел, сборщик выполняет сборку «с остановкой мира» большого размера, обрабатывая все объекты. Генерационный режим использует два параметра: множитель меньшего размера и множитель большего размера.
Множитель меньшего размера управляет частотой небольших сборок. Для множителя x, новый небольшой сбор будет выполнен, когда память станет на x% больше, чем память, используемая после предыдущего большого сбора. Например, для множителя 20, сборщик выполнит небольшой сбор, когда использование памяти увеличится на 20% по сравнению с использованием после предыдущего большого сбора. Значение по умолчанию равно 20; максимальное значение — 200.
Множитель большего размера управляет частотой больших сборок. Для множителя x, новый большой сбор будет выполнен, когда память станет на x% больше, чем память, используемая после предыдущего большого сбора. Например, для множителя 100, сборщик выполнит большой сбор, когда использование памяти станет больше чем вдвое по сравнению с использованием после предыдущего сбора. Значение по умолчанию равно 100; максимальное значение — 1000.
2.5.3 – Меттаметоды сбора мусора
Вы можете установить меттаметоды сборщика мусора для таблиц и, используя API C, для полного пользовательского данных (см. §2.4). Эти меттаметоды, называемые финализаторами, вызываются, когда сборщик мусора обнаруживает, что соответствующая таблица или пользовательские данные являются мертвыми. Финализаторы позволяют согласовать сбор мусора Lua с управлением внешними ресурсами, такими как закрытие файлов, сетевых или баз данных, или освобождение вашей собственной памяти.
Чтобы объект (таблица или пользовательские данные) был финализирован при сборе, вы должны пометить его для финализации. Вы помечаете объект для финализации, когда устанавливаете его меттатаблицу, и эта метта таблица имеет поле, индексированное строкой "__gc". Обратите внимание, что если вы установили меттатаблицу без поля __gc, а затем создали это поле в меттатаблице, объект не будет помечен для финализации.
Когда отмеченный объект становится мертвым, он не собирается сборщиком мусора сразу. Вместо этого Lua помещает его в список. После сбора Lua проходит по этому списку. Для каждого объекта в списке он проверяет меттаметод объекта __gc: если он присутствует, Lua вызывает его с объектом в качестве единственного аргумента.
В конце каждого цикла сбора мусора финализаторы вызываются в обратном порядке, в котором объекты были помечены для финализации, среди тех, которые были собраны в этом цикле; то есть, первый вызываемый финализатор — это финализатор, связанный с объектом, помеченным последним в программе.
Поскольку объект, который собирается, должен по-прежнему использоваться финализатором, этот объект (и другие объекты, доступные только через него) должен быть возрожден Lua. Обычно это возрождение временное, и память объекта освобождается в следующем цикле сбора мусора. Однако, если финализатор сохраняет объект в некотором глобальном месте (например, в глобальной переменной), то возрождение является постоянным. Кроме того, если финализатор помечает объект для финализации еще раз, его финализатор будет вызываться снова в следующем цикле, где объект мертв. В любом случае, память объекта освобождается только в цикле GC, где объект мертв и не помечен для финализации.
При закрытии состояния (см. lua_close), Lua вызывает финализаторы всех объектов, помеченных для финализации, в обратном порядке, в котором они были помечены. Если какой-либо финализатор помечает объекты для сбора во время этой фазы, эти метки не имеют никакого эффекта.
Финализаторы не могут выполнять yield. Кроме этого, они могут делать что угодно, например, генерировать ошибки, создавать новые объекты или даже запускать сборщик мусора. Однако, поскольку они могут работать в непредсказуемые моменты времени, рекомендуется ограничить каждый финализатор минимально необходимыми действиями для надлежащего освобождения связанного с ним ресурса.
Любая ошибка во время выполнения финализатора генерирует предупреждение; ошибка не распространяется.
2.5.4 – Слабые таблицы
Слабая таблица — это таблица, элементы которой являются слабыми ссылками. Слабые ссылки игнорируются сборщиком мусора. Другими словами, если единственными ссылками на объект являются слабые ссылки, то сборщик мусора соберет этот объект.
Слабая таблица может иметь слабые ключи, слабые значения или оба. Таблица со слабыми значениями позволяет собирать ее значения, но препятствует сбору ее ключей. Таблица со слабыми ключами и слабыми значениями позволяет собирать как ключи, так и значения. В любом случае, если ключ или значение собирается, вся пара удаляется из таблицы. Слабость таблицы контролируется полем __mode ее меттатаблицы. Это метазначение, если оно присутствует, должно быть одной из следующих строк: "k" для таблицы со слабыми ключами; "v" для таблицы со слабыми значениями; или "kv" для таблицы со слабыми ключами и значениями.
Таблица со слабыми ключами и сильными значениями также называется эфемеровой таблицей. В эфемеровой таблице значение считается достижимым только если его ключ достижим. В частности, если единственная ссылка на ключ проходит через его значение, пара удаляется.
Любые изменения в слабости таблицы могут вступить в силу только в следующем цикле сбора.
Только объекты, имеющие явное построение, удаляются из слабых таблиц. Значения, такие как числа и лёгкие функции C, не подлежат сбору мусора и, следовательно, не удаляются из слабых таблиц (если не собираются их сопоставленные значения). Хотя строки подлежат сбору мусора, они не имеют явного построения и их равенство по значению; они ведут себя больше как значения, чем как объекты. Следовательно, они не удаляются из слабых таблиц.
Возрождённые объекты (то есть объекты, которые финализируются, и объекты, доступные только через финализируемые объекты) имеют особое поведение в слабых таблицах. Они удаляются из слабых значений до запуска их финализаторов, но удаляются из слабых ключей только в следующем сборе после запуска их финализаторов, когда такие объекты фактически освобождаются. Это поведение позволяет финализатору получить доступ к свойствам, связанным с объектом, через слабые таблицы.
Если слабая таблица входит в число возрождённых объектов в цикле сбора, она может не быть должным образом очищена до следующего цикла.
2.6 – Корутины
Lua поддерживает корутины, также называемые кооперативным многопотоком. Корутина в Lua представляет собой независимую нить выполнения. В отличие от потоков в многопоточных системах, корутина приостанавливает своё выполнение только явно, вызывая функцию yield.
Вы создаёте корутину, вызывая coroutine.create. Единственным аргументом является функция, которая является основной функцией корутины. Функция create только создаёт новую корутину и возвращает дескриптор к ней (объект типа поток); она не запускает корутину.
Вы выполняете корутину, вызывая coroutine.resume. Когда вы впервые вызываете coroutine.resume, передав в качестве первого аргумента поток, возвращённый coroutine.create, корутина начинает выполнение, вызвав свою основную функцию. Дополнительные аргументы, переданные в coroutine.resume, передаются в качестве аргументов этой функции. После запуска корутины, она выполняется до тех пор, пока не завершится или не выполнит yield.
Корутина может завершить своё выполнение двумя способами: нормально, когда её основная функция возвращает значение (явным или неявным образом, после последней инструкции); и аномально, если произошла неохваченная ошибка. В случае нормального завершения, coroutine.resume возвращает true, а также любые значения, возвращённые основной функцией корутины. В случае ошибок, coroutine.resume возвращает false и объект ошибки. В этом случае корутина не разворачивает свою стек, что позволяет инспектировать её после ошибки с помощью API отладки.
Корутина приостанавливается, вызвав 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.
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 goto if in local nil not or repeat return then true until while
Lua — это язык, чувствительный к регистру: and является зарезервированным словом, но And и AND являются двумя различными, допустимыми именами. В качестве соглашения программы должны избегать создания имён, которые начинаются с подчёркивания, за которым следует одна или несколько заглавных букв (например, _VERSION).
Следующие строки обозначают другие токены:
+ - * / % ^ #
& ~ | << >> //
== ~= <= >= < > =
( ) { } [ ] ::
; : , . .. ... Короткий строковый литерал может быть ограничен соответствующими одинарными или двойными кавычками и может содержать следующие escape-последовательности в стиле C: '\a' (звонок), '\b' (ввод), '\f' (перевод страницы), '\n' (перевод строки), '\r' (возврат каретки), '\t' (горизонтальная табуляция), '\v' (вертикальная табуляция), '\\' (обратная косая черта), '\"' (двойная кавычка) и '\'' (одинарная кавычка). Обратная косая черта, за которой следует перевод строки, приводит к переводу строки в строке. Escape-последовательность '\z' пропускает следующий участок пробельных символов, включая переводы строк; она особенно полезна для разбиения и отступа длинной строковой литералы на несколько строк без добавления переводов строк и пробелов в содержимое строки. Короткая строковая литерал не может содержать неэкранированные переводы строк или escape-последовательности, которые не образуют допустимой 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'.
Числовая константа с десятичной точкой или показателем обозначает число с плавающей точкой; в противном случае, если его значение помещается в целое число или это шестнадцатеричная константа, это обозначает целое число; в противном случае (то есть, десятичная целая числовая константа, которая переполняется), это обозначает число с плавающей точкой. Шестнадцатеричные числовые значения без десятичной точки и показателя всегда обозначают целое значение; если значение переполняется, оно переходит, чтобы поместиться в допустимое целое число.
Примеры допустимых целочисленных констант:
3 345 0xff 0xBEBADA
Примеры допустимых констант с плавающей точкой:
3.0 3.1416 314.16e-2 0.31416E1 34e1 0x0.1E 0xA23p-4 0X1.921FB54442D18P+1
Комментарий начинается с двойного дефиса (--) где угодно вне строки. Если текст сразу после -- не является открывающей длинной скобкой, комментарий является коротким комментарием, который продолжается до конца строки. В противном случае это длинный комментарий, который продолжается до соответствующей закрывающей длинной скобки.
3.2 – Переменные
Переменные — это места, которые хранят значения. В Lua есть три вида переменных: глобальные переменные, локальные переменные и поля таблиц.
Одно имя может обозначать глобальную переменную или локальную переменную (или формальный параметр функции, который является особым видом локальной переменной):
var ::= Name
Имя обозначает идентификаторы (см. §3.1).
Любое имя переменной предполагается глобальным, если явно не объявлено как локальное (см. §3.3.7). Локальные переменные имеют лексическую область видимости: локальные переменные могут свободно использоваться функциями, определёнными внутри их области видимости (см. §3.5).
Перед первым присваиванием переменной её значение равно nil.
Квадратные скобки используются для индексирования таблицы:
var ::= prefixexp ‘[’ exp ‘]’
Значение доступа к полям таблицы можно изменить с помощью метатаблиц (см. §2.4).
Синтаксис var.Name — это просто синтаксический сахар для var["Name"]:
var ::= prefixexp ‘.’ Name
Доступ к глобальной переменной x эквивалентен _ENV.x. Из-за того, как компилируются фрагменты, переменная _ENV сама никогда не является глобальной (см. §2.2).
3.3 – Операторы
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 ::= 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.
Перед присваиванием список значений адаптируется к длине списка переменных. Если значений больше, чем необходимо, избыточные значения отбрасываются. Если значений меньше, чем нужно, список дополняется значениями nil. Если список выражений заканчивается вызовом функции, то все значения, возвращённые этим вызовом, попадают в список значений до адаптации (за исключением случаев, когда вызов заключён в скобки; см. §3.4).
Оператор присваивания сначала оценивает все свои выражения и только затем выполняет присваивания. Таким образом, код
i = 3 i, a[i] = i+1, 20
устанавливает a[3] в 20, не влияя на a[4], потому что i в a[i] вычисляется (до 3) прежде, чем ему присваивается 4. Аналогично, строка
x, y = y, x
меняет значения x и y, и
x, y, z = y, z, x
циклически переставляет значения x, y и z.
Присваивание глобальному имени 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
Данный идентификатор (Имя) определяет переменную управления, которая является новой локальной переменной для тела цикла (блока).
Цикл начинается с однократной оценки трёх управляющих выражений. Их значения соответственно называются начальным значением, пределом и шагом. Если шаг отсутствует, он по умолчанию равен 1.
Если и начальное значение, и шаг — целые числа, цикл выполняется с целыми числами; обратите внимание, что предел может не быть целым числом. В противном случае три значения преобразуются в числа с плавающей точкой, и цикл выполняется с числами с плавающей точкой. Будьте осторожны с точностью чисел с плавающей точкой в этом случае.
После этого инициализации тело цикла повторяется со значением переменной управления, проходящей через арифметическую прогрессию, начиная с начального значения, с общим разностью, заданной шагом. Отрицательный шаг создает убывающую последовательность; шаг, равный нулю, вызывает ошибку. Цикл продолжается, пока значение меньше или равно пределу (больше или равно для отрицательного шага). Если начальное значение уже больше предела (или меньше, если шаг отрицательный), тело не выполняется.
Для циклов с целыми числами переменная управления никогда не переполняется; вместо этого цикл завершается в случае переполнения.
Не изменяйте значение переменной управления во время цикла. Если вам нужно её значение после цикла, присвойте его другой переменной перед выходом из цикла.
Обобщённый цикл 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 объявляют переменные цикла, локальные для тела цикла. Первая из этих переменных — переменная управления.
Цикл начинается с оценки explist для получения четырёх значений: функции-итератора, состояния, начального значения для переменной управления и закрывающего значения.
Затем на каждой итерации Lua вызывает функцию-итератор с двумя аргументами: состоянием и переменной управления. Результаты этого вызова затем присваиваются переменным цикла в соответствии с правилами множественного присваивания (см. §3.3.3). Если переменная управления становится nil, цикл завершается. В противном случае выполняется тело и цикл переходит к следующей итерации.
Закрывающее значение ведёт себя как переменная для закрытия (см. §3.3.8), которая может быть использована для освобождения ресурсов при завершении цикла. В противном случае, она не влияет на цикл.
Не изменяйте значение переменной управления во время цикла.
3.3.6 – Вызовы функций как операторы
Для разрешения возможных побочных эффектов вызовы функций могут выполняться как операторы:
stat ::= functioncall
В этом случае все возвращаемые значения отбрасываются. Вызовы функций объяснены в §3.4.10.
3.3.7 – Локальные объявления
Локальные переменные могут быть объявлены где угодно внутри блока. Объявление может включать инициализацию:
stat ::= local attnamelist [‘=’ explist]
attnamelist ::= Name attrib {‘,’ Name attrib}
Если присутствует начальное присваивание, оно имеет ту же семантику, что и множественное присваивание (см. §3.3.3). В противном случае все переменные инициализируются значением nil.
Каждое имя переменной может быть дополнено атрибутом (имя в угловых скобках):
attrib ::= [‘<’ Name ‘>’]
Есть два возможных атрибута: const, который объявляет постоянную переменную, то есть переменную, которой нельзя присвоить значение после её инициализации; и close, который объявляет переменную для закрытия (см. §3.3.8). Список переменных может содержать не более одной переменной для закрытия.
Блок также является блоком (см. §3.3.2), и поэтому локальные переменные могут быть объявлены в блоке вне любого явного блока.
Правила видимости локальных переменных описаны в §3.5.
3.3.8 – Переменные для закрытия
Переменная для закрытия ведёт себя как константная локальная переменная, за исключением того, что её значение закрывается всякий раз, когда переменная выходит из области видимости, включая обычное завершение блока, выход из блока с помощью break/goto/return или выход с ошибкой.
Здесь под закрытием значения подразумевается вызов его __close метаметода. При вызове метаметода само значение передаётся в качестве первого аргумента, а объект ошибки, вызвавшей выход (если таковой был), передаётся как второй аргумент; если ошибки не было, второй аргумент равен nil.
Значение, присваиваемое переменной для закрытия, должно иметь __close метаметод или быть ложным значением. (nil и false игнорируются как значения для закрытия.)
Если несколько переменных для закрытия выходят из области видимости в одном событии, они закрываются в обратном порядке объявления.
Если при выполнении метода закрытия возникает ошибка, эта ошибка обрабатывается как ошибка в обычном коде, где была определена переменная. Однако Lua может вызвать метод ещё раз.
После ошибки другие ожидающие методы закрытия всё ещё будут вызваны. Ошибки в этих методах прерывают соответствующий метод и генерируют предупреждение, но в остальном игнорируются; сообщается только исходная ошибка.
Если корутина приостанавливается и никогда больше не возобновляется, некоторые переменные могут никогда не выйти из области видимости и, следовательно, никогда не будут закрыты. (Эти переменные — те, которые созданы внутри корутины и находятся в области видимости в момент приостановки корутины.) Аналогично, если корутина завершается с ошибкой, она не разворачивает свою стек, поэтому не закрывает никакие переменные. В обоих случаях вы можете либо использовать финализаторы, либо вызвать 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. Выражения с переменным числом аргументов, обозначаемые тремя точками ('...'), могут быть использованы только непосредственно внутри функции с переменным числом аргументов; они описаны в §3.4.11.
Бинарные операторы включают арифметические операторы (см. §3.4.1), побитовые операторы (см. §3.4.2), реляционные операторы (см. §3.4.4), логические операторы (см. §3.4.5) и оператор конкатенации (см. §3.4.6). Унарные операторы включают унарный минус (см. §3.4.1), унарный побитовый НЕ (см. §3.4.2), унарный логический не (см. §3.4.5) и унарный оператор длины (см. §3.4.7).
Как вызовы функций, так и выражения с переменным числом аргументов могут возвращать несколько значений. Если вызов функции используется как оператор (см. §3.3.6), список его возвращаемых значений корректируется на ноль элементов, тем самым отбрасывая все возвращаемые значения. Если выражение используется в качестве последнего (или единственного) элемента списка выражений, корректировка не производится (если выражение не заключено в скобки). Во всех остальных контекстах Lua корректирует список результатов до одного элемента, либо отбрасывая все значения, кроме первого, либо добавляя единственный nil, если значений нет.
Вот несколько примеров:
f() -- adjusted to 0 results
g(f(), x) -- f() is adjusted to 1 result
g(x, f()) -- g gets x plus all results from f()
a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil)
a,b = ... -- a gets the first vararg argument, b gets
-- the second (both a and b can get nil if there
-- is no corresponding vararg argument)
a,b,c = x, f() -- f() is adjusted to 2 results
a,b,c = f() -- f() is adjusted to 3 results
return f() -- returns all results from f()
return ... -- returns all received vararg arguments
return x,y,f() -- returns x, y, and all results from f()
{f()} -- creates a list with all results from f()
{...} -- creates a list with all vararg arguments
{f(), nil} -- f() is adjusted to 1 result Любое выражение, заключенное в скобки, всегда приводит к одному значению. Таким образом, (f(x,y,z)) всегда является единственным значением, даже если f возвращает несколько значений. (Значение (f(x,y,z)) — первое значение, возвращаемое f, или nil, если f не возвращает никаких значений.)
3.4.1 – Арифметические операторы
Lua поддерживает следующие арифметические операторы:
-
+: сложение -
-: вычитание -
*: умножение -
/: деление с плавающей точкой -
//: целочисленное деление -
%: остаток от деления -
^: возведение в степень -
-: унарный минус
За исключением возведения в степень и деления с плавающей точкой, арифметические операторы работают следующим образом: Если оба операнда — целые числа, операция выполняется над целыми числами, и результат — целое число. В противном случае, если оба операнда — числа, они преобразуются в числа с плавающей точкой, операция выполняется в соответствии с правилами машинной арифметики с плавающей точкой (обычно стандарт IEEE 754), и результат — число с плавающей точкой. (Библиотека строк преобразует строки в числа в арифметических операциях; см. §3.4.3 для подробностей.)
Возведение в степень и деление с плавающей точкой (/) всегда преобразуют свои операнды в числа с плавающей точкой, и результат всегда — число с плавающей точкой. Возведение в степень использует функцию ISO C pow, так что она работает и для нецелых показателей степени.
Целочисленное деление (//) — это деление, которое округляет частное до ближайшего целого в сторону минус бесконечности, результат — целая часть частного от деления операндов.
Остаток от деления определяется как остаток от деления, при котором частное округляется до ближайшего целого в сторону минус бесконечности (целочисленное деление).
В случае переполнения в целочисленной арифметике все операции переворачиваются.
3.4.2 – Побитовые операторы
Lua поддерживает следующие побитовые операторы:
-
&: побитовое И -
|: побитовое ИЛИ -
~: побитовое исключающее ИЛИ -
>>: сдвиг вправо -
<<: сдвиг влево -
~: унарный побитовый НЕ
Все побитовые операции преобразуют свои операнды в целые числа (см. §3.4.3), работают со всеми битами этих целых чисел и результатом является целое число.
При сдвигах как вправо, так и влево свободные биты заполняются нулями. Отрицательные смещения сдвигают в другую сторону; смещения с абсолютным значением, равным или превышающим количество битов в целом числе, приводят к нулю (так как все биты сдвигаются наружу).
3.4.3 – Преобразования
Lua обеспечивает некоторые автоматические преобразования между некоторыми типами и представлениями во время выполнения. Побитовые операторы всегда преобразуют операнды с плавающей точкой в целые числа. Возведение в степень и деление с плавающей точкой всегда преобразуют целые операнды в числа с плавающей точкой. Все другие арифметические операции, примененные к смешанным числам (целым и числам с плавающей точкой), преобразуют целые операнды в числа с плавающей точкой. API C также преобразует целые числа в числа с плавающей точкой и числа с плавающей точкой в целые числа, по мере необходимости. Кроме того, конкатенация строк принимает числа в качестве аргументов наряду со строками.
При преобразовании целого числа в число с плавающей точкой, если значение целого числа имеет точное представление в виде числа с плавающей точкой, то это и есть результат. В противном случае преобразование берет ближайшее большее или ближайшее меньшее представимое значение. Такое преобразование никогда не терпит неудачу.
Преобразование числа с плавающей точкой в целое число проверяет, имеет ли число с плавающей точкой точное представление в виде целого числа (то есть число с плавающей точкой имеет целое значение и находится в диапазоне представления целых чисел). Если это так, то это представление и есть результат. В противном случае преобразование терпит неудачу.
В нескольких местах в Lua строки преобразуются в числа при необходимости. В частности, библиотека строк устанавливает метаметоды, которые пытаются преобразовать строки в числа во всех арифметических операциях. Если преобразование терпит неудачу, библиотека вызывает метаметод другого операнда (если он есть) или генерирует ошибку. Обратите внимание, что побитовые операторы не выполняют это преобразование.
Тем не менее, всегда рекомендуется не полагаться на эти неявные преобразования, так как они не всегда применяются; в частности, "1"==1 ложно, а "1"<1 вызывает ошибку (см. §3.4.4). Эти преобразования существуют в основном для совместимости и могут быть удалены в будущих версиях языка.
Строка преобразуется в целое число или число с плавающей точкой в соответствии с ее синтаксисом и правилами лексического анализа Lua. Строка может иметь также ведущие и хвостовые пробелы и знак. Все преобразования строк в числа принимают как точку, так и текущий разделитель десятичных знаков в качестве символа разделителя разрядов. (Однако лексический анализатор Lua принимает только точку.) Если строка не является допустимым числом, преобразование терпит неудачу. Если необходимо, результат этого первого шага затем преобразуется в определенный тип числа, следуя предыдущим правилам преобразования между числами с плавающей точкой и целыми числами.
Преобразование чисел в строки использует неопределенный удобочитаемый формат. Чтобы преобразовать числа в строки каким-либо определенным образом, используйте функцию string.format.
3.4.4 – Операторы сравнения
Lua поддерживает следующие операторы сравнения:
-
==: равенство -
~=: неравенство -
<: меньше -
>: больше -
<=: меньше или равно -
>=: больше или равно
Эти операторы всегда возвращают false или true.
Равенство (==) сначала сравнивает тип своих операндов. Если типы разные, результат — false. В противном случае сравниваются значения операндов. Строки равны, если они имеют одинаковое байтовое содержание. Числа равны, если они обозначают одно и то же математическое значение.
Таблицы, данные пользователя и потоки сравниваются по ссылке: два объекта считаются равными только тогда, когда они являются одним и тем же объектом. Каждый раз, когда вы создаете новый объект (таблицу, данные пользователя или поток), этот новый объект отличается от любого ранее существовавшего объекта. Функция всегда равна сама себе. Функции с любыми обнаруживаемыми различиями (разное поведение, разное определение) всегда различны. Функции, созданные в разное время, но без обнаруживаемых различий, могут быть классифицированы как равные или нет (в зависимости от внутренних подробностей кеширования).
Вы можете изменить способ сравнения 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 используют короткое замыкание; то есть второй операнд вычисляется только при необходимости. Вот несколько примеров:
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 – Оператор длины
Оператор длины обозначается унарным префиксом #.
Длина строки — это количество байтов. (Это обычное значение длины строки, когда каждый символ занимает один байт.)
Оператор длины, применённый к таблице, возвращает границу в этой таблице. Граница в таблице t — это любое натуральное число, удовлетворяющее следующему условию:
(border == 0 or t[border] ~= nil) and t[border + 1] == nil
Другими словами, граница — это любой (натуральный) индекс в таблице, за которым следует отсутствующий индекс (или ноль, если индекс 1 отсутствует).
Таблица с ровно одной границей называется последовательностью. Например, таблица {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) и три дыры (на индексах 1, 4 и 5), поэтому она тоже не является последовательностью. Таблица {} является последовательностью с границей 0. Обратите внимание, что не-натуральные ключи не влияют на то, является ли таблица последовательностью.
Когда t является последовательностью, #t возвращает её единственную границу, что соответствует интуитивному представлению о длине последовательности. Когда t не является последовательностью, #t может вернуть любую её границу. (Точная граница зависит от деталей внутреннего представления таблицы, которые, в свою очередь, могут зависеть от того, как таблица была заполнена, и адресов памяти её не-числовых ключей.)
Вычисление длины таблицы гарантированно имеет наихудшее время O(log n), где n — наибольший натуральный ключ в таблице.
Программа может изменить поведение оператора длины для любого значения, кроме строк, посредством метаметода __len (см. §2.4).
3.4.8 – Приоритет
Приоритет операторов в Lua соответствует следующей таблице, от низшего к высшему:
or and < > <= >= ~= == | ~ & << >> .. + - * / // % unary operators (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" -- 1st exp
t[2] = "y" -- 2nd exp
t.x = 1 -- t["x"] = 1
t[3] = f(x) -- 3rd exp
t[30] = 23
t[4] = 45 -- 4th exp
a = t
end Порядок назначений в конструкторе не определён. (Этот порядок был бы релевантен только при наличии повторяющихся ключей.)
Если последнее поле в списке имеет вид exp и выражение является вызовом функции или выражением vararg, то все значения, возвращаемые этим выражением, входят в список последовательно (см. §3.4.10).
Список полей может иметь необязательный завершающий разделитель для удобства машиночитаемого кода.
3.4.10 – Вызовы функций
Вызов функции в Lua имеет следующий синтаксис:
functioncall ::= prefixexp args
При вызове функции сначала вычисляются prefixexp и args. Если значение prefixexp имеет тип функция, то эта функция вызывается с заданными аргументами. В противном случае, если присутствует, вызывается метаметод prefixexp __call: его первый аргумент — значение 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 вне области действия переменной, которая будет закрыта, называется хвостовым вызовом. Lua реализует правильные хвостовые вызовы (или правильную хвостовую рекурсию): в хвостовом вызове вызываемая функция повторно использует запись стека вызывающей функции. Поэтому нет ограничения на количество вложенных хвостовых вызовов, которые может выполнить программа. Однако хвостовой вызов стирает всю отладочную информацию о вызывающей функции. Обратите внимание, что хвостовой вызов происходит только с определённым синтаксисом, где return имеет один единственный вызов функции в качестве аргумента, и он находится вне области действия любой переменной, которая будет закрыта. Этот синтаксис заставляет вызывающую функцию вернуть ровно возвращаемые значения вызываемой функции без каких-либо промежуточных действий. Таким образом, ни один из следующих примеров не является хвостовым вызовом:
return (f(x)) -- results adjusted to 1 return 2 * f(x) -- result multiplied by 2 return x, f(x) -- additional results f(x); return -- results discarded return x or f(x) -- results adjusted to 1
3.4.11 – Определения функций
Синтаксис для определения функций следующий
functiondef ::= function funcbody funcbody ::= ‘(’ [parlist] ‘)’ block end
Следующий синтаксический сахар упрощает определения функций:
stat ::= function funcname funcbody
stat ::= local function Name funcbody
funcname ::= Name {‘.’ Name} [‘:’ Name]
Оператор
function f () body end
переводится в
f = function () body end
Оператор
function t.a.b.c.f () body end
переводится в
t.a.b.c.f = function () body end
Оператор
local function f () body end
переводится в
local f; f = function () body end
а не в
local f = function () body end
(Это имеет значение только тогда, когда тело функции содержит ссылки на f.)
Определение функции является исполняемым выражением, значение которого имеет тип функция. Когда Lua прекомпилирует блок, все его тела функций также прекомпилируются, но они ещё не созданы. Затем, когда Lua выполняет определение функции, функция инициализируется (или закрывается). Этот экземпляр функции или замыкание — это конечное значение выражения.
Параметры действуют как локальные переменные, которые инициализируются значениями аргументов:
parlist ::= namelist [‘,’ ‘...’] | ‘...’
Когда Lua-функция вызывается, она корректирует свой список аргументов до длины своего списка параметров, если функция не является функцией vararg, что указывается тремя точками ('...') в конце её списка параметров. Функция vararg не корректирует свой список аргументов; вместо этого она собирает все дополнительные аргументы и предоставляет их функции через выражение vararg, которое также записывается как три точки. Значение этого выражения — список всех фактических дополнительных аргументов, аналогично функции с несколькими результатами. Если выражение vararg используется внутри другого выражения или посередине списка выражений, то его список возвратов корректируется до одного элемента. Если выражение используется в качестве последнего элемента списка выражений, то корректировка не выполняется (если только это последнее выражение не заключено в скобки).
В качестве примера рассмотрим следующие определения:
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, ... --> (nothing) g(3, 4) a=3, b=4, ... --> (nothing) g(3, 4, 5, 8) a=3, b=4, ... --> 5 8 g(5, r()) a=5, b=1, ... --> 2 3
Результаты возвращаются с помощью оператора return (см. §3.3.4). Если управление достигает конца функции, не встретив оператора return, то функция возвращается без результатов.
Существует зависящая от системы ограничение на количество значений, которые может вернуть функция. Это ограничение гарантируется большим, чем 1000.
Синтаксис с двоеточием используется для эмуляции методов, добавляя неявный дополнительный параметр self в функцию. Таким образом, оператор
function t.a.b.c:f (params) body end
является синтаксическим сахаром для
t.a.b.c.f = function (self, params) body end
3.5 – Правила видимости
Lua — язык с лексическим охватом. Область видимости локальной переменной начинается с первого оператора после её объявления и длится до последнего непустого оператора самого внутреннего блока, который включает объявление. Рассмотрим следующий пример:
x = 10 -- global variable
do -- new block
local x = x -- new 'x', with value 10
print(x) --> 10
x = x+1
do -- another block
local x = x+1 -- another 'x'
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (the global one) Обратите внимание, что в объявлении, подобном local x = x, новая x ещё не находится в области видимости, поэтому вторая x ссылается на внешнюю переменную.
Из-за правил лексического охвату локальные переменные могут свободно использоваться функциями, определёнными внутри их области видимости. Локальная переменная, используемая внутренней функцией, называется внедренной переменной (или внешней локальной переменной, или просто внешней переменной) внутри внутренней функции.
Обратите внимание, что каждое выполнение оператора local определяет новые локальные переменные. Рассмотрим следующий пример:
a = {}
local x = 20
for i = 1, 10 do
local y = 0
a[i] = function () y = y + 1; return x + y end
end
Цикл создаёт десять замыканий (то есть десять экземпляров анонимной функции). Каждое из этих замыканий использует разные переменные y, в то время как все они разделяют одну и ту же переменную x.
4 – Интерфейс прикладной программы
В этом разделе описан C API для Lua, то есть набор C-функций, доступных программе-хосту для взаимодействия с Lua. Все функции API и связанные типы и константы объявлены в заголовочном файле lua.h.
Даже когда мы используем термин «функция», любое средство в API может быть предоставлено в виде макроса вместо этого. За исключением случаев, когда указано иное, все такие макросы используют каждый из своих аргументов ровно один раз (кроме первого аргумента, который всегда является состоянием Lua), и поэтому не генерируют никаких скрытых побочных эффектов.
Как и в большинстве C-библиотек, функции Lua API не проверяют свои аргументы на валидность или согласованность. Однако вы можете изменить это поведение, скомпилировав Lua с определённым макросом LUA_USE_APICHECK.
Библиотека Lua полностью реентерабельна: у неё нет глобальных переменных. Она хранит всю необходимую информацию в динамической структуре, называемой состоянием Lua.
Каждое состояние Lua имеет один или несколько потоков, которые соответствуют независимым, кооперативным линиям выполнения. Тип 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 – Размер стека
При взаимодействии с API Lua вы несете ответственность за поддержание согласованности. В частности, вы несёте ответственность за предотвращение переполнения стека. Вы можете использовать функцию lua_checkstack, чтобы убедиться, что в стеке достаточно места для добавления новых элементов.
Всякий раз, когда Lua вызывает C, он гарантирует, что в стеке есть место как минимум для LUA_MINSTACK дополнительных элементов; то есть вы можете безопасно добавить до LUA_MINSTACK значений в него. LUA_MINSTACK определён как 20, поэтому обычно вам не нужно беспокоиться о пространстве стека, если только ваш код не содержит циклов, добавляющих элементы в стек.
Когда вы вызываете функцию Lua без фиксированного числа результатов (см. lua_call), Lua гарантирует, что в стеке достаточно места для всех результатов, но не гарантирует дополнительного пространства. Поэтому перед добавлением чего-либо в стек после такого вызова вы должны использовать lua_checkstack.
4.1.2 – Действительные и приемлемые индексы
Любая функция в API, которая получает индексы стека, работает только с действительными индексами или приемлемыми индексами.
Действительный индекс — это индекс, который ссылается на позицию, хранящую изменяемое значение Lua. Он включает индексы стека от 1 до вершины стека (1 ≤ abs(index) ≤ top) плюс псевдоиндексы, которые представляют некоторые позиции, доступные для кода C, но которые не находятся в стеке. Псевдоиндексы используются для доступа к регистру (см. §4.3) и к замыканиям C-функции (см. §4.2).
Функции, которым не нужна конкретная изменяемая позиция, а только значение (например, функции запроса), могут быть вызваны с приемлемыми индексами. Приемлемый индекс может быть любым действительным индексом, но также может быть любым положительным индексом после вершины стека в выделенном для стека пространстве, то есть индексами до размера стека. (Обратите внимание, что 0 никогда не является приемлемым индексом.) Индексы к замыканиям (см. §4.2) больше реального числа замыканий в текущей 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 может освобождать или перемещать внутреннюю память, а затем делать недействительными указатели на внутренние строки. Чтобы позволить безопасное использование этих указателей, API гарантирует, что любой указатель на строку в индексе стека действителен, пока значение в этом индексе не изменяется и не удаляется. Когда индекс является псевдоиндексом (ссылается на замыкание), указатель действителен, пока активен соответствующий вызов, и соответствующее замыкание не изменяется.
Некоторые функции интерфейса отладки также возвращают указатели на строки, а именно lua_getlocal, lua_getupvalue, lua_setlocal и lua_setupvalue. Для этих функций указатель гарантированно действителен, пока активна вызывающая функция и данный замыкание (если оно было передано) находится в стеке.
За исключением этих гарантий, сборщик мусора свободен делать недействительным любой указатель на внутренние строки.
4.2 – C-замыкания
При создании C-функции можно связать с ней некоторые значения, создавая тем самым C-замыкание (см. lua_pushcclosure); эти значения называются замыканиями и доступны функции всякий раз, когда она вызывается.
Всякий раз, когда вызывается C-функция, её замыкания располагаются в определённых псевдоиндексах. Эти псевдоиндексы генерируются макросом lua_upvalueindex. Первое замыкание, связанное с функцией, находится в индексе lua_upvalueindex(1), и так далее. Любой доступ к lua_upvalueindex(n), где n больше числа замыканий текущей функции (но не больше 256, что на единицу больше максимального числа замыканий в замыкании), создаёт приемлемый, но недействительный индекс.
C-замыкание также может изменять значения соответствующих замыканий.
4.3 – Регистр
Lua предоставляет регистр, предопределённую таблицу, которую любой код C может использовать для хранения любых значений Lua, которые ему нужно сохранить. Таблица реестра всегда доступна по псевдоиндексу LUA_REGISTRYINDEX. Любая C-библиотека может сохранять данные в эту таблицу, но должна позаботиться о выборе ключей, отличающихся от тех, которые используются другими библиотеками, чтобы избежать коллизий. Как правило, вы должны использовать в качестве ключа строку, содержащую имя вашей библиотеки, или лёгкий пользовательский тип данных с адресом 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 сталкивается с любой ошибкой, такой как ошибка выделения памяти или ошибка типа, он возбуждает ошибку; то есть он выполняет длинный прыжок. Защищённая среда использует setjmp для задания точки восстановления; любая ошибка переходит к ближайшей активной точке восстановления.
Внутри C-функции вы можете явно возбудить ошибку, вызвав lua_error.
Большинство функций в API могут возбуждать ошибку, например, из-за ошибки выделения памяти. В документации к каждой функции указывается, может ли она возбуждать ошибки.
Если ошибка происходит вне любой защищённой среды, Lua вызывает функцию паники (см. lua_atpanic) и затем вызывает abort, тем самым завершая приложение-хост. Ваша функция паники может предотвратить это завершение, никогда не возвращаясь (например, выполняя длинный прыжок к собственной точке восстановления за пределами Lua).
Функция паники, как следует из её названия, является механизмом последней инстанции. Программы должны избегать её использования. Как общее правило, когда C-функция вызывается Lua с состоянием 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: поток (корутина) уступает. -
LUA_ERRFILE: ошибка, связанная с файлом; например, невозможно открыть или прочитать файл.
Эти константы определены в заголовочном файле lua.h.
4.5 – Обработка уступок в C
Внутренне Lua использует механизм C longjmp для уступки корутины. Следовательно, если C-функция foo вызывает функцию API, и эта функция API уступает (прямо или косвенно, вызывая другую функцию, которая уступает), Lua не может вернуться в foo больше, потому что longjmp удаляет свой кадр из C-стека.
Чтобы избежать этой проблемы, Lua возбуждает ошибку всякий раз, когда пытается уступить вызову API, за исключением трёх функций: lua_yieldk, lua_callk и lua_pcallk. Все эти функции принимают функцию продолжения (в качестве параметра, названного k) для продолжения выполнения после уступки.
Нам нужно установить терминологию для объяснения продолжений. У нас есть функция C, вызываемая из Lua, которую мы будем называть исходной функцией. Эта исходная функция затем вызывает одну из этих трёх функций в C API, которую мы назовём вызываемой функцией, которая затем приостанавливает выполнение текущего потока. Это может произойти, когда вызываемая функция является lua_yieldk, или когда вызываемая функция является либо lua_callk, либо lua_pcallk, и функция, вызываемая ими, приостанавливает выполнение.
Предположим, что работающий поток приостанавливается во время выполнения вызываемой функции. После возобновления потока он, в конечном итоге, завершит выполнение вызываемой функции. Однако вызываемая функция не может вернуться к исходной функции, потому что её кадр в стеке C был уничтожен приостановкой. Вместо этого Lua вызывает функцию продолжения, которая была передана в качестве аргумента вызываемой функции. Как следует из названия, функция продолжения должна продолжить задачу исходной функции.
В качестве иллюстрации рассмотрим следующую функцию:
int original_function (lua_State *L) {
... /* code 1 */
status = lua_pcall(L, n, m, h); /* calls Lua */
... /* code 2 */
}
Теперь мы хотим разрешить коду Lua, выполняемому lua_pcall, приостанавливаться. Сначала мы можем переписать нашу функцию, как показано здесь:
int k (lua_State *L, int status, lua_KContext ctx) {
... /* code 2 */
}
int original_function (lua_State *L) {
... /* code 1 */
return k(L, lua_pcall(L, n, m, h), ctx);
}
В коде выше новая функция k является функцией продолжения (типа lua_KFunction), которая должна выполнить всю работу, которую исходная функция выполняла после вызова lua_pcall. Теперь мы должны сообщить Lua, что она должна вызвать k, если код Lua, выполняемый lua_pcall, прервётся каким-либо образом (ошибки или приостановки), поэтому мы перепишем код, как показано здесь, заменив lua_pcall на lua_pcallk:
int original_function (lua_State *L) {
... /* code 1 */
return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
}
Обратите внимание на внешний явный вызов продолжения: Lua вызовет продолжение только в случае необходимости, то есть в случае ошибок или возобновления после приостановки. Если вызываемая функция возвращается нормально, без приостановки, lua_pcallk (и lua_callk) также вернётся нормально. (Конечно, вместо вызова продолжения в этом случае вы можете выполнить эквивалентную работу непосредственно внутри исходной функции.)
Помимо состояния Lua, функция продолжения имеет ещё два параметра: конечный статус вызова и значение контекста (ctx), которое изначально было передано в lua_pcallk. Lua не использует это значение контекста; она только передаёт это значение из исходной функции в функцию продолжения. Для lua_pcallk статус является тем же значением, которое вернула бы lua_pcallk, за исключением того, что это LUA_YIELD, когда она выполняется после приостановки (вместо LUA_OK). Для lua_yieldk и lua_callk статус всегда равен LUA_YIELD, когда Lua вызывает продолжение. (Для этих двух функций Lua не вызовет продолжение в случае ошибок, поскольку они не обрабатывают ошибки.) Аналогично, при использовании lua_callk вы должны вызвать функцию продолжения со статусом LUA_OK. (Для lua_yieldk мало смысла вызывать напрямую функцию продолжения, поскольку lua_yieldk обычно не возвращается.)
Lua рассматривает функцию продолжения так, как если бы это была исходная функция. Функция продолжения получает тот же стек Lua, что и исходная функция, в том же состоянии, в котором он был бы, если бы вызываемая функция вернулась. (Например, после lua_callk функция и её аргументы удаляются из стека и заменяются результатами вызова.) Она также имеет те же значения upvalues. Всё, что она возвращает, обрабатывается Lua так, как если бы это был возврат исходной функции.
4.6 – Функции и Типы[-o, +p, x]
Здесь мы перечисляем все функции и типы из C API в алфавитном порядке. Каждая функция имеет индикатор, подобный этому:
Первое поле, 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_newstate.
static void *l_alloc (void *ud, void *ptr, size_t osize,
size_t nsize) {
(void)ud; (void)osize; /* not used */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
Обратите внимание, что Стандартный 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 позаботится о том, чтобы возвращаемые значения поместились в пространство стека, но не гарантирует дополнительного места в стеке. Результаты функции помещаются в стек в прямом порядке (сначала помещается первый результат), так что после вызова последний результат находится на вершине стека.
Любая ошибка при вызове и выполнении функции передаётся вверх (с longjmp).
Следующий пример показывает, как хост-программа может выполнить эквивалент этого кода Lua:
a = f("how", t.x, 14)
Вот он на C:
lua_getglobal(L, "f"); /* function to be called */ lua_pushliteral(L, "how"); /* 1st argument */ lua_getglobal(L, "t"); /* table to be indexed */ lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */ lua_remove(L, -2); /* remove 't' from the stack */ lua_pushinteger(L, 14); /* 3rd argument */ lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */ lua_setglobal(L, "a"); /* set global '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, но позволяет вызываемой функции приостанавливаться (см. §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, также может возвращать множество результатов.
В качестве примера, следующая функция получает переменное количество числовых аргументов и возвращает их среднее значение и сумму:
static int foo (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number sum = 0.0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushliteral(L, "incorrect argument");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* first result */
lua_pushnumber(L, sum); /* second result */
return 2; /* number of results */
}
lua_checkstack[-0, +0, –]
int lua_checkstack (lua_State *L, int n);
Обеспечивает, что стек имеет место для как минимум n дополнительных элементов, то есть, что вы можете безопасно поместить до n значений в него. Он возвращает false, если не может выполнить запрос, либо потому, что это приведет к превышению фиксированного максимального размера стека (обычно не менее нескольких тысяч элементов), либо потому, что не может выделить память для дополнительного места. Эта функция никогда не уменьшает стек; если стек уже имеет место для дополнительных элементов, он остается неизменным.
lua_close[-0, +0, –]
void lua_close (lua_State *L);
Закрывает все активные переменные, ожидающие закрытия, в основном потоке, освобождает все объекты в данном состоянии Lua (вызывая соответствующие метаметоды сборки мусора, если таковые имеются) и освобождает всю динамическую память, используемую этим состоянием.
На некоторых платформах вам может не потребоваться вызывать эту функцию, так как все ресурсы естественным образом освобождаются при завершении программы-хоста. С другой стороны, долгоживущие программы, создающие несколько состояний, такие как демоны или веб-серверы, вероятно, должны будут закрывать состояния, как только они больше не нужны.
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 narr, int nrec);
Создает новую пустую таблицу и помещает её в стек. Параметр narr — подсказка о том, сколько элементов будет в таблице как последовательности; параметр 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 для записи их.
Если strip истинно, двоичное представление может не включать всю отладочную информацию о функции, чтобы сэкономить место.
Возвращаемое значение — код ошибки, возвращённый последним вызовом функции-писателя; 0 означает отсутствие ошибок.
Эта функция не удаляет функцию Lua из стека.
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_GCISRUNNING: Возвращает булево значение, указывающее, работает ли сборщик (т.е. не остановлен). -
LUA_GCINC(int pause, int stepmul, stepsize): Изменяет сборщик на инкрементальный режим с заданными параметрами (см. §2.5.1). Возвращает предыдущий режим (LUA_GCGENилиLUA_GCINC). -
LUA_GCGEN(int minormul, int majormul): Изменяет сборщик на генерационный режим с заданными параметрами (см. §2.5.2). Возвращает предыдущий режим (LUA_GCGENилиLUA_GCINC).
LUA_GCSTEP (int stepsize): Выполняет инкрементальную операцию сборки мусора, соответствующую выделению stepsize Кбайт. Для получения более подробной информации об этих опциях см. 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, эта функция может вызывать метаметод для события «индекс» (см. §2.4).
Возвращает тип помещённого значения.
lua_getextraspace[-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, эта функция может вызывать метаметод для события «индекс» (см. §2.4).
Возвращает тип помещённого значения.
lua_getmetatable[-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, эта функция может вызывать метаметод для события «индекс» (см. §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-й пользовательский объект, связанный с полным пользовательским данными по заданному индексу, и возвращает тип помещённого значения.
Если у пользовательских данных нет этого значения, помещает nil и возвращает LUA_TNONE.
lua_insert[-1, +1, –]
void lua_insert (lua_State *L, int index);
Перемещает верхний элемент в заданный допустимый индекс, сдвигая элементы над этим индексом вверх, чтобы освободить место. Эту функцию нельзя вызывать с псевдоиндексом, так как псевдоиндекс не является фактической позицией в стеке.
lua_Integer
typedef ... 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, если данный сопроцесс может быть приостановлен, и 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) и может вызывать метаметод для события "длины" (см. §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".
lua_load использует стек внутри, поэтому функция чтения должна всегда оставлять стек неизменным при возврате.
lua_load может вернуть LUA_OK, LUA_ERRSYNTAX или LUA_ERRMEM. Функция также может вернуть другие значения, соответствующие ошибкам, поднятым функцией чтения (см. §4.4.1).
Если полученная функция имеет upvalues, её первое upvalue устанавливается в значение глобальной среды, хранящейся в индексе LUA_RIDX_GLOBALS в реестре (см. §4.3). При загрузке основных блоков это upvalue будет переменной _ENV (см. §2.2). Другие upvalues инициализируются значением nil.
lua_newstate[-0, +0, –]
lua_State *lua_newstate (lua_Alloc f, void *ud);
Создаёт новый независимый состояние и возвращает его основной поток. Возвращает NULL если не может создать состояние (из-за нехватки памяти). Аргумент f — функция выделения памяти; Lua будет выполнять все выделения памяти для этого состояния через эту функцию (см. lua_Alloc). Второй аргумент, ud, — некое значение, передаваемое Lua выделению памяти в каждом вызове.
lua_newtable[-0, +1, m]
void lua_newtable (lua_State *L);
Создаёт новую пустую таблицу и помещает её в стек. Эквивалентно lua_createtable(L, 0, 0).
lua_newthread[-0, +1, m]
lua_State *lua_newthread (lua_State *L);
Создаёт новый поток, помещает его в стек и возвращает указатель на lua_State, который представляет этот новый поток. Новый поток, возвращаемый этой функцией, разделяет свою глобальную среду с исходным потоком, но имеет независимый стек выполнения.
Потоки подвергаются сборке мусора, как и любые Lua-объекты.
lua_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 и ничего не помещает.
Типичный проход по таблице выглядит так:
/* table is in the stack at index 't' */
lua_pushnil(L); /* first key */
while (lua_next(L, t) != 0) {
/* uses 'key' (at index -2) and 'value' (at index -1) */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* removes 'value'; keeps 'key' for next iteration */
lua_pop(L, 1);
} При проходе по таблице избегайте прямого вызова lua_tolstring для ключа, если вы не знаете, что ключ на самом деле является строкой. Помните, что lua_tolstring может изменить значение в данном индексе; это сбивает с толку следующий вызов lua_next.
Эта функция может вызвать ошибку, если данный ключ не равен nil и не присутствует в таблице. См. функцию next для замечаний по изменению таблицы во время прохода.
lua_Number
typedef ... lua_Number;
Тип чисел с плавающей точкой в Lua.
По умолчанию этот тип — double, но его можно изменить на single 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_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, за исключением того, что она позволяет вызываемой функции приостанавливать выполнение (см. §4.5).
lua_pop[-n, +0, –]
void lua_pop (lua_State *L, int n);
Извлекает n элементов из стека.
lua_pushboolean[-0, +1, –]
void lua_pushboolean (lua_State *L, int b);
Помещает булево значение со значением b в стек.
lua_pushcclosure[-n, +1, m]
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
Помещает новый C-замыкание в стек. Эта функция получает указатель на C-функцию и помещает в стек Lua-значение типа function, которое при вызове вызывает соответствующую C-функцию. Параметр n указывает, сколько вспомогательных значений (upvalues) будет у этой функции (см. §4.2).
Любая функция, которая должна быть вызываема из Lua, должна следовать правильному протоколу получения параметров и возврата результатов (см. lua_CFunction).
При создании C-функции можно ассоциировать с ней некоторые значения, так называемые вспомогательные значения (upvalues); эти вспомогательные значения доступны функции при каждом её вызове. Эта ассоциация называется C-замыканием (см. §4.2). Для создания C-замыкания сначала нужно поместить начальные значения его вспомогательных значений в стек. (Если вспомогательных значений несколько, то первое значение помещается первым.) Затем вызывается lua_pushcclosure для создания и помещения C-функции в стек, с аргументом n, указывающим, сколько значений будет ассоциировано с функцией. lua_pushcclosure также извлекает эти значения из стека.
Максимальное значение для n составляет 255.
Когда n равно нулю, эта функция создает лёгкую C-функцию, которая просто является указателем на C-функцию. В этом случае никогда не возникает ошибка памяти.
lua_pushcfunction[-0, +1, –]
void lua_pushcfunction (lua_State *L, lua_CFunction f);
Помещает C-функцию в стек. Эта функция эквивалентна lua_pushcclosure без вспомогательных значений.
lua_pushfstring[-0, +1, v]
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
Помещает в стек отформатированную строку и возвращает указатель на эту строку (см. §4.1.3). Она похожа на функцию ISO C sprintf, но имеет два важных отличия. Во-первых, вам не нужно выделять место для результата; результат — это Lua-строка, и Lua заботится о выделении (и освобождении) памяти через сборку мусора. Во-вторых, спецификаторы преобразования довольно ограничены. Нет флагов, длин и точности. Спецификаторы преобразования могут быть только '%%' (вставляет символ '%'), '%s' (вставляет нуль-терминированную строку без ограничений по размеру), '%f' (вставляет lua_Number), '%I' (вставляет lua_Integer), '%p' (вставляет указатель), '%d' (вставляет int), '%c' (вставляет int как символ длиной один байт) и '%U' (вставляет long int как последовательность байтов UTF-8).
Эта функция может вызывать ошибки из-за переполнения памяти или некорректного спецификатора преобразования.
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);
Помещает лёгкое пользовательское данные в стек.
Пользовательские данные представляют C-значения в Lua. Лёгкие пользовательские данные представляют указатель, void*. Это значение (как число): вы его не создаёте, у него нет индивидуального метатаблицы и он не собирается (так как никогда не создавался). Лёгкие пользовательские данные равны «любым» лёгким пользовательским данным с тем же C-адресом.
lua_pushliteral[-0, +1, m]
const char *lua_pushliteral (lua_State *L, const char *s);
Этот макрос эквивалентен lua_pushstring, но должен использоваться только когда s — это строковая литерал. (Lua может оптимизировать этот случай.)
lua_pushlstring[-0, +1, m]
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, v]
const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp); Эквивалентно lua_pushfstring, за исключением того, что оно получает va_list вместо переменного числа аргументов.
lua_rawequal[-0, +0, –]
int lua_rawequal (lua_State *L, int index1, int index2);
Возвращает 1, если два значения по индексам index1 и index2 примитивно равны (то есть равны без вызова __eq метаметода). В противном случае возвращает 0. Также возвращает 0, если любой из индексов недействителен.
lua_rawget[-1, +1, –]
int lua_rawget (lua_State *L, int index);
Похоже на lua_gettable, но выполняет прямой доступ (т. е. без метаметодов).
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 представленный как лёгкие пользовательские данные. Доступ прямой; то есть он не использует __index метазначение.
Возвращает тип помещенного значения.
lua_rawlen[-0, +0, –]
lua_Unsigned lua_rawlen (lua_State *L, int index);
Возвращает «длину» значения по заданному индексу (raw «length»): для строк — это длина строки; для таблиц — результат оператора длины ('#') без метаметодов; для пользовательских данных — размер блока памяти, выделенного для пользовательских данных. Для других значений это вызов возвращает 0.
lua_rawset[-2, +0, m]
void lua_rawset (lua_State *L, int index);
Аналогично lua_settable, но выполняет присваивание без метаметодов.
lua_rawseti[-1, +0, m]
void lua_rawseti (lua_State *L, int index, lua_Integer i);
Выполняет эквивалент t[i] = v, где t — таблица по заданному индексу, и v — значение на вершине стека.
Эта функция извлекает значение из стека. Присваивание выполняется без метаметодов.
lua_rawsetp[-1, +0, m]
void lua_rawsetp (lua_State *L, int index, const void *p);
Выполняет эквивалент t[p] = v, где t — таблица по заданному индексу, p закодировано как лёгкие пользовательские данные, и v — значение на вершине стека.
Эта функция извлекает значение из стека. Присваивание выполняется без метаметодов.
lua_Reader
typedef const char * (*lua_Reader) (lua_State *L,
void *data,
size_t *size); Функция чтения, используемая lua_load. Каждый раз, когда lua_load нуждается в новом фрагменте фрагмента, она вызывает функцию чтения, передавая ей свой параметр data. Функция чтения должна вернуть указатель на блок памяти с новым фрагментом фрагмента и установить size на размер блока. Блок должен существовать до тех пор, пока функция чтения не будет вызвана снова. Для сигнализации о конце фрагмента функция чтения должна вернуть NULL или установить size в ноль. Функция чтения может возвращать фрагменты любого размера, большего нуля.
lua_register[-0, +0, e]
void lua_register (lua_State *L, const char *name, lua_CFunction f);
Устанавливает C-функцию f в качестве нового значения глобальной переменной name. Она определена как макрос:
#define lua_register(L,n,f) \
(lua_pushcfunction(L, f), lua_setglobal(L, n))
lua_remove[-1, +0, –]
void lua_remove (lua_State *L, int index);
Удаляет элемент по заданному индексу, смещая элементы, находящиеся выше этого индекса, чтобы заполнить пробел. Эту функцию нельзя вызывать с псевдоиндексом, поскольку псевдоиндекс не является фактической позицией в стеке.
lua_replace[-1, +0, –]
void lua_replace (lua_State *L, int index);
Перемещает верхний элемент в заданный индекс без смещения каких-либо элементов (следовательно, заменяет значение по этому индексу), а затем удаляет верхний элемент.
lua_resetthread[-0, +?, –]
int lua_resetthread (lua_State *L);
Сбрасывает поток, очищая его стек вызовов и закрывая все ожидающие закрытия переменные. Возвращает код состояния: LUA_OK при отсутствии ошибок при закрытии методов или код ошибки в противном случае. В случае ошибки, объект ошибки остается на вершине стека,
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, если корутина приостанавливается, LUA_OK, если корутина завершается без ошибок, или код ошибки в случае ошибок (см. §4.4.1). В случае ошибок, объект ошибки находится на вершине стека.
Для возобновления корутины, вы удаляете *nresults приостановленные значения из её стека, помещаете значения, которые должны быть переданы в качестве результатов от 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-го пользовательского значения, связанного с полным пользовательским данными по заданному индексу. Возвращает 0, если пользовательские данные не содержат это значение.
lua_setmetatable[-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[-?, +?, –]
void lua_settop (lua_State *L, int index);
Принимает любой индекс или 0 и устанавливает вершину стека на этот индекс. Если новая вершина больше старой, новые элементы заполняются nil. Если index равно 0, то все элементы стека удаляются.
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, m]
void lua_toclose (lua_State *L, int index);
Помечает значение по заданному индексу в стеке как «переменную, подлежащую закрытию» (см. §3.3.8). Как и переменная, подлежащая закрытию в Lua, значение по этому индексу в стеке будет закрыто, когда оно выйдет из области видимости. Здесь, в контексте функции C, выход из области видимости означает, что вызывающая функция возвращается в Lua, возникла ошибка или индекс был удалён из стека с помощью lua_settop или lua_pop. Индекс, помеченный как подлежащий закрытию, не должен удаляться из стека никакой другой функцией API, кроме lua_settop или lua_pop.
Эта функция не должна вызываться для индекса, равного или меньшего активного индекса, подлежащего закрытию.
В случае ошибки нехватки памяти значение по заданному индексу сразу закрывается, как если бы оно уже было помечено.
Обратите внимание, что как в случае ошибок, так и в случае обычного возврата, к моменту выполнения метаметода __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. Если len не равно NULL, оно устанавливает *len длиной строки. Значение Lua должно быть строкой или числом; в противном случае функция возвращает NULL. Если значение является числом, то lua_tolstring также изменяет фактическое значение в стеке на строку. (Это изменение вводит путаницу в lua_next, когда lua_tolstring применяется к ключам во время обхода таблицы.)
lua_tolstring возвращает указатель на строку внутри состояния Lua (см. §4.1.3). Эта строка всегда имеет ноль ('\0') после последнего символа (как в C), но может содержать другие нули в своём теле.
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-й замыкающий параметр выполняемой функции (см. §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.
Функция записи возвращает код ошибки: 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); Приостанавливает сопрограмму (поток).
Когда функция C вызывает lua_yieldk, выполняемая сопрограмма приостанавливает своё выполнение, и вызов lua_resume, запустивший эту сопрограмму, возвращается. Параметр nresults - количество значений со стека, которые будут переданы в качестве результатов lua_resume.
Когда сопрограмма возобновляется снова, Lua вызывает заданную функцию продолжения k для продолжения выполнения функции C, которая передала управление (см. §4.5). Эта функция продолжения получает тот же стек, что и предыдущая функция, с удалёнными n результатами, и заменёнными аргументами, переданными lua_resume. Более того, функция продолжения получает значение ctx, которое было передано lua_yieldk.
Обычно эта функция не возвращает значение; когда сопрограмма в конечном итоге возобновляется, она продолжает выполнение функции продолжения. Однако есть один особый случай, когда эта функция вызывается из строки или крючка подсчёта (см. §4.7). В этом случае lua_yieldk должна быть вызвана без продолжения (вероятно, в виде lua_yield) и без результатов, а крючок должен возвращаться немедленно после вызова. Lua передаст управление, и когда сопрограмма возобновится снова, она продолжит нормальное выполнение (Lua) функции, которая вызвала крючок.
Эта функция может генерировать ошибку, если вызывается из потока с ожидающим вызовом C без функции продолжения (так называемый предел вызова C), или вызывается из потока, который не выполняется в рамках возобновления (обычно основной поток).
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) number of upvalues */
unsigned char nparams; /* (u) number of parameters */
char isvararg; /* (u) */
char istailcall; /* (t) */
unsigned short ftransfer; /* (r) index of first value transferred */
unsigned short ntransfer; /* (r) number of transferred values */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
other fields
} lua_Debug; Структура, используемая для передачи различной информации о функции или записи активации. lua_getstack заполняет только частную часть этой структуры для последующего использования. Чтобы заполнить другие поля lua_Debug полезной информацией, необходимо вызвать 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","method","field","upvalue", или""(пустая строка), в зависимости от того, как была вызвана функция. (Lua использует пустую строку, когда ни один другой вариант не подходит.) -
istailcall: true, если вызов этой функции был сделан с помощью хвостового вызова. В этом случае вызывающая функция этого уровня не находится в стеке. -
nups: количество upvalues функции. -
nparams: количество параметров функции (всегда 0 для функций C). -
isvararg: true, если функция является функцией vararg (всегда 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"); /* get global 'f' */
lua_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined); Каждый символ в строке what выбирает некоторые поля структуры ar для заполнения или значение для помещения в стек:
- '
n': заполняет поляnameиnamewhat; - '
S': заполняет поляsource,short_src,linedefined,lastlinedefined, иwhat; - '
l': заполняет полеcurrentline; - '
t': заполняет полеistailcall; - '
u': заполняет поляnups,nparams, иisvararg; - '
f': помещает в стек функцию, выполняющуюся на данном уровне; - '
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 больше, чем количество upvalues.
См. debug.getupvalue для получения дополнительной информации об upvalues.
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 с ненулевым k.
Функции обработчика могут возвращать данные в следующих условиях: только события count и line могут возвращать данные; для возврата функция обработчика должна завершить своё выполнение, вызвав lua_yield с nresults равным нулю (то есть без значений).
lua_setcstacklimit[-0, +0, –]
int (lua_setcstacklimit) (lua_State *L, unsigned int limit);
Устанавливает новый предел для C-стека. Этот предел контролирует, насколько глубокими могут быть вложенные вызовы в Lua, с целью предотвращения переполнения стека. Возвращает старый предел в случае успеха или ноль в случае ошибки. Для получения дополнительных сведений об этой функции, см. debug.setcstacklimit, её эквивалент в стандартной библиотеке.
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.
5 – Вспомогательная библиотека
Вспомогательная библиотека предоставляет несколько удобных функций для взаимодействия C с Lua. В то время как базовый API предоставляет базовые функции для всех взаимодействий между C и Lua, вспомогательная библиотека предоставляет функции более высокого уровня для некоторых общих задач.
Все функции и типы из вспомогательной библиотеки определены в заголовочном файле lauxlib.h и имеют префикс luaL_.
Все функции вспомогательной библиотеки основаны на базовом API, и поэтому они не предоставляют ничего, чего нельзя сделать с этим API. Тем не менее, использование вспомогательной библиотеки обеспечивает больше согласованности в вашем коде.
Несколько функций вспомогательной библиотеки используют внутренне несколько дополнительных слотов стека. Когда функция в вспомогательной библиотеке использует меньше пяти слотов, она не проверяет размер стека; она просто предполагает, что достаточно слотов.
Несколько функций вспомогательной библиотеки используются для проверки аргументов функций C. Поскольку сообщение об ошибке отформатировано для аргументов (например, "bad argument #1"), вы не должны использовать эти функции для других значений стека.
Функции, названные luaL_check* всегда генерируют ошибку, если проверка не выполняется.
5.1 – Функции и Типы
Здесь перечислены все функции и типы из вспомогательной библиотеки в алфавитном порядке.
luaL_addchar[-?, +?, m]
void luaL_addchar (luaL_Buffer *B, char c);
Добавляет байт c в буфер B (см. luaL_Buffer).
luaL_addgsub[-0, +0, 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[-1, +?, 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, +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[-0, +0, –]
void luaL_buffsub (luaL_Buffer *B, int n);
Удаляет n байтов из буфера B (см. luaL_Buffer). Буфер должен иметь не меньше этих байтов.
luaL_callmeta[-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 (который должен быть завершён нулём). Возвращает индекс в массиве, где была найдена строка. Вызывает ошибку, если аргумент не является строкой или строка не найдена.
Если 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))
Возвращает LUA_OK, если ошибок нет, или код ошибки в случае ошибок (см. §4.4.1).
luaL_dostring[-0, +?, –]
int luaL_dostring (lua_State *L, const char *str);
Загружает и выполняет заданную строку. Определяется как следующая макрокоманда:
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
Возвращает LUA_OK, если ошибок нет, или код ошибки в случае ошибок (см. §4.4.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 и т.д.).
luaL_getmetafield[-0, +(0|1), m]
int luaL_getmetafield (lua_State *L, int obj, const char *e);
Помещает на стек поле e из таблицы метаданных объекта по индексу obj и возвращает тип помещённого значения. Если у объекта нет таблицы метаданных или в таблице метаданных нет этого поля, ничего не помещает и возвращает LUA_TNIL.
luaL_getmetatable[-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.
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_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 должен быть фактическим массивом, а не указателем на него.
luaL_newmetatable[-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 с выделением памяти на основе стандартных C-функций выделения памяти, а затем устанавливает функцию обработки предупреждений и функцию обработки паники (см. §4.4), которые выводят сообщения в стандартный поток ошибок.
Возвращает новый стек или NULL, если произошла ошибка выделения памяти.
luaL_openlibs[-0, +0, e]
void luaL_openlibs (lua_State *L);
Открывает все стандартные Lua-библиотеки в заданном стеке.
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, на объект, расположенный на вершине стека (и удаляет объект со стека).
Ссылка — это уникальный целочисленный ключ. Пока вы не добавите целочисленные ключи в таблицу t, функция luaL_ref гарантирует уникальность возвращаемого ключа. Вы можете получить объект, на который ссылается ссылка r, вызвав lua_rawgeti(L, t, r). Функция luaL_unref освобождает ссылку.
Если объект на вершине стека равен nil, luaL_ref возвращает константу LUA_REFNIL. Константа LUA_NOREF гарантированно отличается от любой ссылки, возвращаемой luaL_ref.
luaL_Reg
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg; Тип массивов функций, которые регистрируются с помощью luaL_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] не истинно, вызывает функцию openf со строкой modname в качестве аргумента и устанавливает результат вызова в package.loaded[modname], как если бы эта функция была вызвана через require.
Если glb истинно, также сохраняет модуль в глобальной переменной modname.
Оставляет копию модуля на стеке.
luaL_setfuncs[-nup, +0, m]
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
Регистрирует все функции в массиве l (см. luaL_Reg) в таблице на вершине стека (ниже необязательных дополнительных значений, см. ниже).
Когда nup не равно нулю, все функции создаются с nup дополнительными значениями, инициализированными копиями значений nup , ранее помещенных на стек поверх таблицы библиотеки. Эти значения удаляются со стека после регистрации.
luaL_setmetatable[-0, +0, –]
void luaL_setmetatable (lua_State *L, const char *tname);
Устанавливает метатаблицу объекта на вершине стека в качестве метатаблицы, связанной с именем tname в реестре (см. luaL_newmetatable).
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-функцию, которая будет вызвана для закрытия потока при закрытии или сборке мусора дескриптора; эта функция получает дескриптор файла в качестве единственного аргумента и должна возвращать истинное значение в случае успеха или ложное значение плюс сообщение об ошибке в случае ошибки. После того, как 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]
const char *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);
Освобождает ссылку ref из таблицы по индексу t (см. luaL_ref). Запись удаляется из таблицы, так что ссылаемый объект может быть собран мусором. Ссылка ref также освобождается для повторного использования.
Если ref равно LUA_NOREF или LUA_REFNIL, luaL_unref ничего не делает.
luaL_where[-0, +1, m]
void luaL_where (lua_State *L, int lvl);
Помещает на стек строку, идентифицирующую текущую позицию управления на уровне lvl в стеке вызовов. Обычно эта строка имеет следующий формат:
chunkname:currentline:
Уровень 0 — это выполняемая функция, уровень 1 — функция, которая вызвала выполняемую функцию и так далее.
Эта функция используется для создания префикса сообщений об ошибках.
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.1);
- библиотека сопроцедур (§6.2);
- библиотека пакетов (§6.3);
- обработка строк (§6.4);
- базовая поддержка UTF-8 (§6.5);
- обработка таблиц (§6.6);
- математические функции (§6.7) (sin, log и т.д.);
- ввод и вывод (§6.8);
- функции операционной системы (§6.9);
- средства отладки (§6.10).
За исключением базовой и библиотеки пакетов, каждая библиотека предоставляет все свои функции как поля глобальной таблицы или как методы своих объектов.
Для доступа к этим библиотекам программа на языке C должна вызвать функцию luaL_openlibs, которая открывает все стандартные библиотеки. В качестве альтернативы программа на языке C может открыть их по отдельности, используя luaL_requiref для вызова luaopen_base (для базовой библиотеки), luaopen_package (для библиотеки пакетов), luaopen_coroutine (для библиотеки сопроцедур), luaopen_string (для библиотеки строк), luaopen_utf8 (для библиотеки UTF-8), luaopen_table (для библиотеки таблиц), luaopen_math (для математической библиотеки), luaopen_io (для библиотеки ввода/вывода), luaopen_os (для библиотеки операционной системы) и luaopen_debug (для библиотеки отладки). Эти функции объявлены в lualib.h.
6.1 – Базовые функции
Базовая библиотека предоставляет основные функции для Lua. Если вы не включаете эту библиотеку в своё приложение, вы должны тщательно проверить, нужно ли вам предоставлять реализации некоторых её функций.
assert (v [, message])
Вызывает ошибку, если значение его аргумента v ложно (т.е., nil или false); в противном случае возвращает все свои аргументы. В случае ошибки, message является объектом ошибки; при отсутствии, он по умолчанию равен "assertion failed!".
collectgarbage ([opt [, arg]])
Эта функция является универсальным интерфейсом к сборщику мусора. Она выполняет разные функции в зависимости от своего первого аргумента, opt:
- "
collect": Выполняет цикл полной работы сборщика мусора. Это опция по умолчанию. - "
stop": Останавливает автоматическое выполнение сборщика мусора. Сборщик будет запускаться только при явном вызове, до вызова для его перезапуска. - "
restart": Перезапускает автоматическое выполнение сборщика мусора. - "
count": Возвращает общее количество используемой памяти Lua в Кбайтах. Значение имеет дробную часть, так что его умножение на 1024 даёт точное число байт, используемых Lua. - "
step": Выполняет шаг сборки мусора. Размер шага контролируетсяarg. С нулевым значением сборщик выполнит один базовый (неделимый) шаг. Для ненулевых значений сборщик будет работать так, как если бы это количество памяти (в Кбайтах) было выделено Lua. Возвращает true, если шаг завершил цикл сбора. - "
isrunning": Возвращает булево значение, указывающее, работает ли сборщик (т.е., не остановлен). - "
incremental": Изменяет режим сборщика на инкрементальный. Эта опция может быть дополнена тремя числами: паузой сборщика мусора, множителем шага и размером шага (см. §2.5.1). Ноль означает, что это значение не будет изменено. - "
generational": Изменяет режим сборщика на генерационный. Эта опция может быть дополнена двумя числами: множителем меньшего цикла сборщика мусора и множителем большего цикла (см. §2.5.2). Ноль означает, что это значение не будет изменено.
Смотрите §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 не использует эту переменную; изменение её значения не влияет на среду, и наоборот.
getmetatable (object)
Если у object нет метатаблицы, возвращает nil. В противном случае, если метатаблица объекта имеет поле __metatable, возвращает соответствующее значение. В противном случае возвращает метатаблицу данного объекта.
ipairs (t)
Возвращает три значения (функцию-итератор, таблицу t и 0), так что конструкция
for i,v in ipairs(t) do body end
будет перебирать пары ключ–значение (1,t[1]), (2,t[2]), ..., до первой отсутствующей индекса.
load (chunk [, chunkname [, mode [, env]]])
Загружает фрагмент.
Если chunk является строкой, фрагмент – это эта строка. Если chunk – функция, load вызывает её многократно для получения фрагментов фрагмента. Каждый вызов chunk должен возвращать строку, которая конкатенируется с предыдущими результатами. Возврат пустой строки, nil или отсутствие значения сигнализируют о конце фрагмента.
Если синтаксических ошибок нет, load возвращает скомпилированный фрагмент как функцию; в противном случае возвращает fail плюс сообщение об ошибке.
При загрузке основного фрагмента результирующая функция всегда будет иметь ровно одну переменную, переменную _ENV (см. §2.2). Однако, при загрузке бинарного фрагмента, созданного из функции (см. string.dump), результирующая функция может иметь произвольное количество переменных, и нет гарантии, что её первая переменная будет переменной _ENV. (Функция, не являющаяся основной, может даже не иметь переменной _ENV.)
В любом случае, если результирующая функция имеет какие-либо переменные, её первая переменная устанавливается в значение env, если этот параметр указан, или в значение глобальной среды. Другие переменные инициализируются значением nil. Все переменные являются новыми, то есть они не совместно используются ни с какой другой функцией.
chunkname используется как имя фрагмента для сообщений об ошибках и отладочной информации (см. §4.7). При отсутствии, он по умолчанию равен chunk, если chunk является строкой, или "=(load)" в противном случае.
Строка mode управляет тем, может ли фрагмент быть текстовым или бинарным (то есть, предварительно скомпилированный фрагмент). Это может быть строка "b" (только бинарные фрагменты), "t" (только текстовые фрагменты) или "bt" (и бинарные, и текстовые). По умолчанию это "bt".
Безопасно загружать некорректные бинарные фрагменты; load сигнализирует об соответствующей ошибке. Однако Lua не проверяет согласованность кода внутри бинарных фрагментов; запуск вредоносного байткода может привести к сбою интерпретатора.
loadfile ([filename [, mode [, env]]])
Аналогично load, но получает фрагмент из файла filename или из стандартного ввода, если имя файла не указано.
next (table [, index])
Позволяет программе перебирать все поля таблицы. Его первый аргумент – таблица, а второй – индекс в этой таблице. Вызов next возвращает следующий индекс таблицы и его связанное значение. При вызове с nil в качестве второго аргумента, next возвращает начальный индекс и его связанное значение. При вызове с последним индексом или с nil в пустой таблице, next возвращает nil. Если второй аргумент отсутствует, он интерпретируется как nil. В частности, вы можете использовать next(t) для проверки того, пуста ли таблица.
Порядок перечисления индексов не определён, даже для числовых индексов. (Для перебора таблицы в числовом порядке используйте числовой for.)
Поведение next не определено, если во время обхода вы присваиваете какое-либо значение несуществующему полю в таблице. Вы можете, однако, изменять существующие поля. В частности, вы можете установить существующие поля в 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 перехватывает ошибку и возвращает код состояния. Его первый результат – код состояния (булево значение), которое истинно, если вызов выполняется без ошибок. В таком случае 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 возвращает общее количество дополнительных аргументов, полученных им.
setmetatable (table, metatable)
Устанавливает метатаблицу для данной таблицы. Если metatable равно nil, удаляет метатаблицу данной таблицы. Если исходный метатаблица имеет поле __metatable, генерируется ошибка.
Эта функция возвращает table.
Чтобы изменить метатаблицу других типов из кода Lua, необходимо использовать библиотеку debug (§6.10).
tonumber (e [, base])
При вызове без base, tonumber пытается преобразовать свой аргумент в число. Если аргумент уже является числом или строкой, преобразуемой в число, то tonumber возвращает это число; в противном случае возвращает fail.
Преобразование строк может привести к целым или вещественным числам в соответствии с лексическими правилами Lua (см. §3.1). Строка может иметь ведущие и хвостовые пробелы и знак.
При вызове с base, e должна быть строкой, интерпретируемой как целочисленная цифра в этой системе счисления. Основание может быть любым целым числом от 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.4".
warn (msg1, ···)
Выводит предупреждение с сообщением, составленным путем конкатенации всех своих аргументов (которые должны быть строками).
По соглашению, сообщение из одного куска, начинающееся с '@', предназначено для управления сообщением, которое является сообщением для самой системы предупреждений. В частности, стандартная функция предупреждения в Lua распознаёт управляющие сообщения "@off", чтобы остановить вызов предупреждений, и "@on", чтобы (снова) запустить вызов; она игнорирует неизвестные управляющие сообщения.
xpcall (f, msgh [, arg1, ···])
Эта функция похожа на pcall, за исключением того, что она устанавливает новый обработчик сообщений msgh.
6.2 – Управление корутинами
Эта библиотека содержит операции по управлению корутинами, которые содержатся внутри таблицы coroutine. См. §2.6 для общего описания корутин.
coroutine.close (co)
Закрывает корутину co, то есть закрывает все её ожидающие закрытия переменные и помещает корутину в состояние завершения. Данная корутина должна быть завершена или приостановлена. В случае ошибки при закрытии какой-либо переменной, возвращает false плюс объект ошибки; в противном случае возвращает true.
coroutine.create (f)
Создаёт новую корутину с телом f. f должен быть функцией. Возвращает эту новую корутину, объект с типом "thread".
coroutine.isyieldable ([co])
Возвращает true, когда корутина co может передать управление. По умолчанию для co является текущая корутина.
Корутина может передавать управление, если это не основной поток и она не находится внутри непередаваемой C-функции.
coroutine.resume (co [, val1, ···])
Запускает или продолжает выполнение корутины co. В первый раз при возобновлении корутины, она начинает выполнять своё тело. Значения val1, ... передаются в качестве аргументов функции тела. Если корутина передала управление, resume перезапускает её; значения val1, ... передаются как результаты из передачи управления.
Если корутина выполняется без ошибок, 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.3 – Модули
Библиотека пакетов предоставляет базовые возможности для загрузки модулей в 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_4, или переменную среды LUA_CPATH, или путь по умолчанию, определённый в luaconf.h.
package.loaded
Таблица, используемая функцией require для управления тем, какие модули уже загружены. Когда вы требуете модуль modname и package.loaded[modname] не является ложью, функция require просто возвращает сохранённое там значение.
Эта переменная — только ссылка на реальную таблицу; присваивания этой переменной не изменяют таблицу, используемую функцией require.
package.loadlib (libname, funcname)
Динамически связывает программу-хост с библиотекой C libname.
Если funcname равно "*", то происходит только связывание с библиотекой, делая доступными символы, экспортируемые библиотекой, для других динамически связанных библиотек. В противном случае, функция ищет функцию funcname внутри библиотеки и возвращает эту функцию как функцию C. Поэтому, funcname должна следовать прототипу lua_CFunction (см. lua_CFunction).
Это функция низкого уровня. Она полностью обходит систему пакетов и модулей. В отличие от функции require, она не выполняет поиск по пути и не добавляет расширения автоматически. libname должно быть полным именем файла библиотеки C, включая, при необходимости, путь и расширение. funcname должно быть точным именем, экспортируемым библиотекой C (что может зависеть от используемого компилятора и компоновщика C).
Эта функция не поддерживается стандартным C. Поэтому она доступна только на некоторых платформах (Windows, Linux, Mac OS X, Solaris, BSD, а также другие Unix-системы, поддерживающие стандарт dlfcn).
Эта функция по своей природе небезопасна, поскольку позволяет Lua вызывать любую функцию в любой читаемой динамической библиотеке в системе. (Lua вызывает любую функцию, предполагая, что функция имеет правильный прототип и соблюдает правильный протокол (см. lua_CFunction). Поэтому, вызов произвольной функции в произвольной динамической библиотеке чаще всего приводит к нарушению доступа.)
package.path
Строка с путём, используемым функцией require для поиска Lua загрузчика.
При запуске Lua инициализирует эту переменную значением переменной среды LUA_PATH_5_4 или переменной среды LUA_PATH, или путём по умолчанию, определённым в luaconf.h, если эти переменные среды не определены. ";;" в значении переменной среды заменяется путём по умолчанию.
package.preload
Таблица для хранения загрузчиков для определённых модулей (см. require).
Эта переменная — только ссылка на реальную таблицу; присваивания этой переменной не изменяют таблицу, используемую функцией require.
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 в одну библиотеку, при этом каждый подмодуль сохраняет свою исходную функцию открытия.
Все поисковые функции, кроме первой (preload), возвращают в качестве дополнительного значения путь к файлу, где был найден модуль, как возвращает функция 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.4 – Обработка строк
Эта библиотека предоставляет общие функции для работы со строками, такие как поиск и извлечение подстрок и сопоставление с шаблоном. При индексировании строки в Lua первый символ имеет позицию 1 (а не 0, как в C). Индексы могут быть отрицательными и интерпретируются как обратный отсчёт от конца строки. Таким образом, последний символ имеет позицию -1 и так далее.
Библиотека строк предоставляет все свои функции внутри таблицы string. Она также устанавливает метатаблицу для строк, где поле __index указывает на таблицу string. Поэтому вы можете использовать функции строк в объектно-ориентированном стиле. Например, string.byte(s,i) можно записать как s:byte(i).
Библиотека строк предполагает кодировки символов с одним байтом.
string.byte (s [, i [, j]])
Возвращает внутренние числовые коды символов s[i], s[i+1], ..., s[j]. Значение по умолчанию для i равно 1; значение по умолчанию для j равно i. Эти индексы корректируются по тем же правилам, что и функция string.sub. Числовые коды не обязательно являются переносимыми между платформами.
string.char (···)
Принимает ноль или более целых чисел. Возвращает строку длиной, равной количеству аргументов, в которой каждый символ имеет внутренний числовой код, равный соответствующему аргументу. Числовые коды не обязательно являются переносимыми между платформами.
string.dump (function [, strip])
Возвращает строку, содержащую двоичное представление (двоичный фрагмент) заданной функции, так что последующее применение load к этой строке возвращает копию функции (но с новыми значениями замыканий). Если strip имеет истинное значение, двоичное представление может не включать всю отладочную информацию о функции, чтобы сохранить место.
Функции с замыканиями сохраняют только количество своих замыканий. При (пере)загрузке эти замыкания получают свежие экземпляры. (См. функцию load для получения подробностей о том, как инициализируются эти замыкания. Вы можете использовать библиотеку отладки для сериализации и перезагрузки замыканий функции таким способом, который подходит для ваших потребностей.)
string.find (s, pattern [, init [, plain]])
Ищет первое вхождение pattern (см. §6.4.1) в строке s. Если совпадение найдено, то find возвращает индексы s, где это вхождение начинается и заканчивается; в противном случае возвращает fail. Третий, необязательный числовой аргумент init указывает, где начать поиск; его значение по умолчанию — 1, и оно может быть отрицательным. Значение true в качестве четвёртого, необязательного аргумента plain отключает средства сопоставления с шаблоном, поэтому функция выполняет обычный поиск подстроки без того, чтобы символы в pattern рассматривались как магические.
Если шаблон имеет захват, то при успешном совпадении захваченные значения также возвращаются после двух индексов.
string.format (formatstring, ···)
Возвращает отформатированную версию своих аргументов, следующих описанию, заданному в первом аргументе, который должен быть строкой. Форматная строка следует тем же правилам, что и функция ISO C sprintf. Единственные отличия заключаются в том, что спецификаторы и модификаторы преобразования *, h, L, l, и n не поддерживаются, и есть дополнительный спецификатор, q.
Спецификатор 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.4.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.4.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.4"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
--> x="lua-5.4.tar.gz"
string.len (s)
Принимает строку и возвращает её длину. Пустая строка "" имеет длину 0. Вложенные нули учитываются, поэтому "a\000bc\000" имеет длину 5.
string.lower (s)
Принимает строку и возвращает копию этой строки, в которой все заглавные буквы заменены на строчные. Все другие символы остаются неизменными. Определение того, что является заглавной буквой, зависит от текущей локали.
string.match (s, pattern [, init])
Ищет первое совпадение шаблона pattern (см. §6.4.1) в строке s. Если он находит совпадение, то match возвращает захваченные подстроки из шаблона; в противном случае он возвращает fail. Если pattern не указывает никаких захватов, то возвращается весь совпавший фрагмент. Третий, необязательный числовой аргумент init указывает, где начать поиск; его значение по умолчанию равно 1, и оно может быть отрицательным.
string.pack (fmt, v1, v2, ···)
Возвращает двоичную строку, содержащую значения v1, v2, и т. д., сериализованные в двоичном виде (упакованные) в соответствии с форматом строки fmt (см. §6.4.2).
string.packsize (fmt)
Возвращает размер строки, полученной в результате вызова string.pack с данным форматом. Строка формата не может содержать опции переменной длины 's' или 'z' (см. §6.4.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.4.2). Необязательный pos обозначает, с какой позиции в s начать чтение (по умолчанию — 1). После чтения значений функция также возвращает индекс первого непрочитанного байта в s.
string.upper (s)
Принимает строку и возвращает копию этой строки, в которой все строчные буквы заменены на заглавные. Все остальные символы остаются неизменными. Определение того, что является строчной буквой, зависит от текущей локали.
6.4.1 – Шаблоны
Шаблоны в 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]: представляет класс, который является объединением всех символов в множестве. Диапазон символов может быть задан, разделяя крайние символы диапазона, в порядке возрастания, символом '-'. Все классы%x, описанные выше, также могут использоваться в качестве компонентов в множестве. Все остальные символы в множестве представляют сами себя. Например,[%w_](или[_%w]) представляет все буквенно-цифровые символы плюс знак подчёркивания,[0-7]представляет восьмеричные цифры, а[0-7%l%-]представляет восьмеричные цифры плюс строчные буквы плюс символ '-'.Вы можете поместить закрывающую квадратную скобку в множество, поместив её как первый символ в множестве. Вы можете поместить дефис в множество, поместив его как первый или последний символ в множестве. (Вы также можете использовать escape для обоих случаев.)
Взаимодействие между диапазонами и классами не определено. Поэтому шаблоны, такие как
[%a-z]или[a-%%]не имеют смысла. -
[^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], шаблон границы; такой элемент соответствует пустой строке в любой позиции, такой что следующий символ принадлежит набору, а предыдущий символ не принадлежит набору. Набор набор интерпретируется, как описано ранее. Начало и конец темы обрабатываются так, как если бы они были символом '\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.4.2 – Строки формата для Pack и Unpack
Первый аргумент для string.pack, string.packsize и string.unpack – это строка формата, которая описывает расположение структуры, создаваемой или считываемой.
Строка формата – это последовательность опций преобразования. Опции преобразования следующие:
-
<: устанавливает порядок байтов little endian -
>: устанавливает порядок байтов big endian -
=: устанавливает порядок байтов по умолчанию -
![n]: устанавливает максимальное выравнивание доn(по умолчанию используется родное выравнивание) -
b: подписанный байт (char) -
B: беззнаковый байт (char) -
h: подписанное целое (родной размер) -
H: беззнаковое целое (родной размер) -
l: подписанное целое (родной размер) -
L: беззнаковое целое (родной размер) -
j:lua_Integer -
J:lua_Unsigned -
T:size_t(родной размер) -
i[n]: подписанное целое сnбайтами (по умолчанию используется родной размер) -
I[n]: беззнаковое целое сnбайтами (по умолчанию используется родной размер) -
f:float(родной размер) -
d:double(родной размер) -
n:lua_Number -
cn: строка фиксированной длины сnбайтами -
z: строка с нулевым завершением -
s[n]: строка, предваряемая её длиной, закодированной как беззнаковое целое сnбайтами (по умолчанию используется родной размер) -
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.5 – Поддержка 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.4.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])
Возвращает позицию (в байтах), где начинается кодировка %%%CODE_BLOCK_2271%%-го символа s (считая с позиции i). Отрицательное значение n указывает на символы перед позицией i. По умолчанию для i значение 1, когда n неотрицательно, и другое значение в противном случае, так что utf8.offset(s, -n) получает смещение %%%CODE_BLOCK_2280%%-го символа с конца строки. Если указанный символ не находится ни в теме, ни сразу после её конца, функция возвращает fail.
В качестве особого случая, когда n равно 0, функция возвращает начало кодировки символа, содержащего %%%CODE_BLOCK_2282%%-й байт s.
Эта функция предполагает, что s является допустимой строкой UTF-8.
6.6 – Обработка таблиц
Эта библиотека предоставляет общие функции для обработки таблиц. Все её функции находятся внутри таблицы 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.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.
Возвращает целевую таблицу 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.7 – Математические функции
Эта библиотека предоставляет базовые математические функции. Все её функции и константы находятся внутри таблицы math. Функции с пометкой "integer/float" возвращают целочисленные результаты для целочисленных аргументов и плавающие результаты для нецелочисленных аргументов. Функции округления math.ceil, math.floor и math.modf возвращают целое число, если результат помещается в диапазон целых чисел, или плавающее число в противном случае.
math.abs (x)
Возвращает максимальное значение между x и -x. (целое/дробное)
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 (предполагается, что в радианах).
math.deg (x)
Преобразует угол x из радиан в градусы.
math.exp (x)
Возвращает значение ex (где e — основание натуральных логарифмов).
math.floor (x)
Возвращает наибольшее целое значение, меньшее или равное x.
math.fmod (x, y)
Возвращает остаток от деления x на y, который округляет частное к нулю. (целое/дробное)
math.huge
Вещественное значение HUGE_VAL, значение, большее любого другого числового значения.
math.log (x [, base])
Возвращает логарифм x по заданному основанию. Значение по умолчанию для 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 объединяются в 128-битный seed, который используется для повторной инициализации генератора псевдослучайных чисел; одинаковые семена дают одинаковые последовательности чисел. Значение по умолчанию для y — ноль.
При вызове без аргументов Lua генерирует семя со слабой попыткой случайности.
Эта функция возвращает два компонента семени, которые были фактически использованы, так что повторная установка этих значений повторяет последовательность.
Для обеспечения необходимого уровня случайности в начальном состоянии (или, наоборот, для получения детерминированной последовательности, например, при отладке программы), необходимо вызвать math.randomseed с явными аргументами.
math.sin (x)
Возвращает синус x (предполагается, что в радианах).
math.sqrt (x)
Возвращает квадратный корень из x. (Вы также можете использовать выражение x^0.5 для вычисления этого значения.)
math.tan (x)
Возвращает тангенс x (предполагается, что в радианах).
math.tointeger (x)
Если значение x может быть преобразовано в целое число, возвращает это целое число. В противном случае возвращает fail.
math.type (x)
Возвращает "integer", если x целое число, "float", если оно с плавающей точкой, или fail, если x не число.
math.ult (m, n)
Возвращает булево значение, true, если и только если целое число m меньше целого числа n при сравнении их как беззнаковых целых чисел.
6.8 – Средства ввода и вывода
Библиотека ввода/вывода предоставляет два разных стиля для работы с файлами. Первый использует неявные дескрипторы файлов; то есть, есть операции для установки файла по умолчанию для ввода и файла по умолчанию для вывода, и все операции ввода/вывода выполняются с этими файлами по умолчанию. Второй стиль использует явные дескрипторы файлов.
При использовании неявных дескрипторов файлов все операции предоставляются таблицей io. При использовании явных дескрипторов файлов операция io.open возвращает дескриптор файла, а затем все операции предоставляются как методы дескриптора файла.
Таблица метаданных для дескрипторов файлов предоставляет метаметоды для __gc и __close, которые пытаются закрыть файл при вызове.
Таблица io также предоставляет три предопределенных дескриптора файлов с их обычным значением из C: io.stdin, io.stdout и io.stderr. Библиотека ввода-вывода никогда не закрывает эти файлы.
Если не указано иное, все функции ввода-вывода возвращают ошибку при ошибке, а также сообщение об ошибке в качестве второго результата и системно-зависимый код ошибки в качестве третьего результата, а некоторое значение, отличное от ложного, — при успехе. В не-POSIX системах вычисление сообщения об ошибке и кода ошибки в случае ошибок может быть не потокобезопасным, так как оно опирается на глобальную переменную C errno.
io.close ([file])
Эквивалентно file:close(). Без file, закрывает файл вывода по умолчанию.
io.flush ()
Эквивалентно io.output():flush().
io.input ([file])
При вызове с именем файла открывает указанный файл (в текстовом режиме) и устанавливает его дескриптор как дескриптор файла ввода по умолчанию. При вызове с дескриптором файла просто устанавливает этот дескриптор как дескриптор файла ввода по умолчанию. При вызове без аргументов возвращает текущий дескриптор файла ввода по умолчанию.
В случае ошибок эта функция вызывает ошибку вместо возврата кода ошибки.
io.lines ([filename, ···])
Открывает указанный файл в режиме чтения и возвращает функцию-итератор, которая работает как file:lines(···) над открытым файлом. Когда функция-итератор не может прочитать значение, она автоматически закрывает файл. Помимо функции-итератора, io.lines возвращает еще три значения: два значения nil в качестве заглушек и созданный дескриптор файла. Поэтому при использовании в общем цикле for файл закрывается также в случае прерывания цикла ошибкой или break.
Вызов io.lines() (без имени файла) эквивалентен io.input():lines("l"); то есть итерируется по строкам файла ввода по умолчанию. В этом случае итератор не закрывает файл по завершении цикла.
В случае ошибок при открытии файла эта функция вызывает ошибку вместо возврата кода ошибки.
io.open (filename [, mode])
Эта функция открывает файл в режиме, указанном в строке mode. В случае успеха она возвращает новый дескриптор файла.
Строка mode может быть любой из следующих:
- "
r": режим чтения (по умолчанию); - "
w": режим записи; - "
a": режим добавления; - "
r+": режим обновления, все предыдущие данные сохраняются; - "
w+": режим обновления, все предыдущие данные удаляются; - "
a+": режим добавления и обновления, предыдущие данные сохраняются, запись разрешена только в конце файла.
Строка mode также может иметь в конце '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 — закрытый дескриптор файла, или ошибка, если obj — не дескриптор файла.
io.write (···)
Эквивалентно io.output():write(···).
file:close ()
Закрывает file. Обратите внимание, что файлы автоматически закрываются при сборе мусора их дескрипторов, но это занимает непредсказуемое количество времени.
При закрытии дескриптора файла, созданного с помощью io.popen, file:close возвращает те же значения, что и os.execute.
file:flush ()
Сохраняет все записанные данные в file.
file:lines (···)
Возвращает функцию-итератор, которая при каждом вызове считывает файл в соответствии с заданными форматами. Если формат не задан, используется "l" по умолчанию. Например, конструкция
for c in file:lines(1) do body end
будет итерировать по всем символам файла, начиная с текущей позиции. В отличие от io.lines, эта функция не закрывает файл по завершении цикла.
file:read (···)
Считывает файл file, согласно заданным форматам, которые определяют, что нужно считать. Для каждого формата функция возвращает строку или число с прочитанными символами или ошибку, если она не может прочитать данные в заданном формате. (В последнем случае функция не читает последующие форматы.) При вызове без аргументов используется формат по умолчанию, который считывает следующую строку (см. ниже).
Доступные форматы
- "
n": считывает число и возвращает его как число с плавающей точкой или целое число, следуя лексическим соглашениям Lua. (Число может иметь ведущие пробелы и знак.) Этот формат всегда читает самую длинную последовательность ввода, являющуюся допустимым префиксом для числа; если этот префикс не образует допустимого числа (например, пустая строка, "0x" или "3.4e-") или он слишком длинный (более 200 символов), он отбрасывается, и формат возвращает ошибку. - "
a": считывает весь файл, начиная с текущей позиции. В конце файла возвращает пустую строку; этот формат никогда не завершается ошибкой. - "
l": считывает следующую строку, пропуская символ конца строки, возвращая ошибку в конце файла. Это формат по умолчанию. - "
L": считывает следующую строку, сохраняя символ конца строки (если он есть), возвращая ошибку в конце файла. -
число: считывает строку длиной до этого числа байтов, возвращая ошибку в конце файла. Если
numberравно нулю, ничего не считывается и возвращается пустая строка или ошибка в конце файла.
Форматы "l" и "L" следует использовать только для текстовых файлов.
file:seek ([whence [, offset]])
Устанавливает и получает позицию файла, измеряемую с начала файла, в позицию, заданную значением offset плюс основание, заданное строкой whence, следующим образом:
- "
set": основание — позиция 0 (начало файла); - "
cur": основание — текущая позиция; - "
end": основание — конец файла;
В случае успеха seek возвращает конечную позицию файла, измеряемую в байтах с начала файла. Если seek завершается ошибкой, возвращает ошибку, плюс строку, описывающую ошибку.
Значение по умолчанию для 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. Аргументы должны быть строками или числами.
В случае успеха эта функция возвращает file.
6.9 – Средства операционной системы
Эта библиотека реализована через таблицу os.
os.clock ()
Возвращает приблизительное значение затраченного процессорного времени программы в секундах, как возвращает подлежащая функция ISO C clock.
os.date ([format [, time]])
Возвращает строку или таблицу, содержащую дату и время, отформатированные в соответствии с заданной строкой format.
Если аргумент time присутствует, это время для форматирования (см. функцию os.time для описания этого значения). В противном случае date форматирует текущее время.
Если format начинается с '!', то дата форматируется в координированном универсальном времени. После этого необязательного символа, если format является строкой "*t", то date возвращает таблицу со следующими полями: year, month (1–12), day (1–31), hour (0–23), min (0–59), sec (0–61, из-за секунд високосного года), wday (день недели, 1–7, воскресенье — 1), yday (день года, 1–366) и isdst (флаг летнего времени, булево значение). Последнее поле может отсутствовать, если информация недоступна.
Если format не равно "*t", то date возвращает дату в виде строки, отформатированной по тем же правилам, что и функция ISO C strftime.
Если format отсутствует, по умолчанию используется "%c", что дает удобочитаемое представление даты и времени с использованием текущего языка.
В не-POSIX системах эта функция может быть не потокобезопасной из-за зависимости от C функции gmtime и C функции localtime.
os.difftime (t2, t1)
Возвращает разницу, в секундах, между временем t1 и временем t2 (где время — значения, возвращаемые функцией os.time). В POSIX, Windows и некоторых других системах это значение точно равно t2-t1.
os.execute ([command])
Эта функция эквивалентна функции ISO C system. Она передаёт command для выполнения оболочкой операционной системы. Её первый результат — true, если команда завершилась успешно, или fail в противном случае. После этого первого результата функция возвращает строку и число следующим образом:
- "
exit": команда завершилась нормально; следующее число — код завершения команды. - "
signal": команда была завершена сигналом; следующее число — сигнал, который завершил команду.
При вызове без command, os.execute возвращает булево значение, равное true, если оболочка доступна.
os.exit ([code [, close]])
Вызывает функцию ISO C exit для завершения программы-хоста. Если code равно true, возвращаемый код — EXIT_SUCCESS; если code равно false, возвращаемый код — EXIT_FAILURE; если code — число, возвращаемый код — это число. Значение по умолчанию для code равно true.
Если необязательный второй аргумент close равен true, закрывает состояние Lua перед выходом.
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.10 – Библиотека отладки
Эта библиотека предоставляет функциональность интерфейса отладки (§4.7) для программ Lua. Будьте осторожны при использовании этой библиотеки. Некоторые её функции нарушают основные предположения о коде Lua (например, что переменные, локальные для функции, недоступны извне; что метатаблицы userdata не могут быть изменены кодом Lua; что программы Lua не терпят сбоев) и поэтому могут нанести ущерб в противном случае безопасному коду. Кроме того, некоторые функции этой библиотеки могут быть медленными.
Все функции этой библиотеки предоставляются внутри таблицы debug. Все функции, работающие с потоком, имеют необязательный первый аргумент, который представляет поток для работы. По умолчанию всегда используется текущий поток.
debug.debug ()
Входит в интерактивный режим с пользователем, выполняя каждую введённую строку. Используя простые команды и другие средства отладки, пользователь может просматривать глобальные и локальные переменные, изменять их значения, вычислять выражения и т. д. Строка, содержащая только слово cont завершает эту функцию, так что вызывающая функция может продолжить своё выполнение.
Обратите внимание, что команды для debug.debug не вложены лексически внутри какой-либо функции и поэтому не имеют прямого доступа к локальным переменным.
debug.gethook ([thread])
Возвращает текущие настройки хука потока в виде трёх значений: текущую функцию хука, текущую маску хука и текущий счётчик хука, установленные функцией 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 с таблицей допустимых строк.
Например, выражение debug.getinfo(1,"n").name возвращает имя текущей функции, если можно найти разумное имя, а выражение debug.getinfo(print) возвращает таблицу со всей доступной информацией о функции print.
debug.getlocal ([thread,] f, local)
Эта функция возвращает имя и значение локальной переменной с индексом local функции на уровне f стека. Эта функция обращается не только к явным локальным переменным, но и к параметрам и временным значениям.
Первый параметр или локальная переменная имеют индекс 1 и так далее, следуя порядку объявления в коде, учитывая только переменные, активные в текущем объёме функции. Переменные времени компиляции могут отсутствовать в этом списке, если они были оптимизированы компилятором. Отрицательные индексы относятся к аргументам vararg; -1 — это первый аргумент vararg. Функция возвращает fail, если нет переменной с данным индексом, и выдаёт ошибку при вызове с недопустимым уровнем. (Вы можете вызвать debug.getinfo для проверки, является ли уровень допустимым.)
Имена переменных, начинающиеся с '(' (открывающая скобка), представляют переменные без известных имён (внутренние переменные, такие как переменные управления циклами и переменные из блоков, сохранённых без отладочной информации).
Параметр f также может быть функцией. В этом случае getlocal возвращает только имена параметров функции.
debug.getmetatable (value)
Возвращает метатаблицу данного value или nil, если у него нет метатаблицы.
debug.getregistry ()
Возвращает таблицу реестра (см. §4.3).
debug.getupvalue (f, up)
Эта функция возвращает имя и значение upvalue с индексом up функции f. Функция возвращает fail, если нет upvalue с заданным индексом.
(Для функций Lua upvalue — это внешние локальные переменные, которые использует функция, и которые, следовательно, включены в её замыкание.)
Для функций C эта функция использует пустую строку "" как имя для всех upvalue.
Имя переменной '?' (вопросительный знак) представляет переменные без известных имён (переменные из блоков, сохранённых без отладочной информации).
debug.getuservalue (u, n)
Возвращает n-ое значение пользователя, связанное с userdata u, плюс булево значение, false, если userdata не имеет этого значения.
debug.setcstacklimit (limit)
Устанавливает новый предел для стека C. Этот предел контролирует глубину вложенных вызовов в Lua с целью предотвращения переполнения стека. Слишком маленький предел бессмысленно ограничивает рекурсивные вызовы; слишком большой предел подвергает интерпретатор аварийным завершениям из-за переполнения стека. К сожалению, нет способа заранее узнать максимальный безопасный предел для платформы.
Каждый вызов из кода Lua считается за одну единицу. Другие операции (например, вызовы из C в Lua или возобновление сопрограммы) могут иметь более высокую стоимость.
У этой функции есть следующие ограничения:
- Она может быть вызвана только из основной сопрограммы (потока);
- Она не может быть вызвана во время обработки ошибки переполнения стека;
-
limitдолжно быть меньше 40000; -
limitне может быть меньше объёма используемого стека C.
Если вызов не соблюдает какое-либо ограничение, он возвращает значение false. В противном случае вызов возвращает старое ограничение.
debug.sethook ([thread,] hook, mask [, count])
Устанавливает заданную функцию в качестве отладчика. Строка mask и число count описывают, когда будет вызвана функция. Строка маски может содержать любую комбинацию следующих символов со следующим значением:
- '
c': отладчик вызывается каждый раз, когда Lua вызывает функцию; - '
r': отладчик вызывается каждый раз, когда Lua возвращается из функции; - '
l': отладчик вызывается каждый раз, когда Lua входит в новую строку кода.
Кроме того, при значении count отличном от нуля, отладчик вызывается также после каждой count инструкции.
При вызове без аргументов, debug.sethook отключает отладчик.
Когда вызывается отладчик, его первый параметр — это строка, описывающая событие, которое вызвало его вызов: "call", "tail call", "return", "line", и "count". Для событий строк отладчик также получает новый номер строки в качестве второго параметра. Внутри отладчика вы можете вызвать getinfo с уровнем 2, чтобы получить больше информации о выполняемой функции. (Уровень 0 — это функция getinfo, а уровень 1 — функция отладчика.)
debug.setlocal ([thread,] level, local, value)
Эта функция присваивает значение value локальной переменной с индексом local функции на уровне level стека. Функция возвращает fail, если локальная переменная с заданным индексом отсутствует, и генерирует ошибку, если вызывается с level вне диапазона. (Вы можете вызвать getinfo для проверки того, что уровень допустим.) В противном случае она возвращает имя локальной переменной.
См. debug.getlocal для получения дополнительной информации об индексах и именах переменных.
debug.setmetatable (value, table)
Устанавливает таблицу метаданных для данного value в заданную table (которая может быть nil). Возвращает value.
debug.setupvalue (f, up, value)
Эта функция присваивает значение value вспомогательной переменной с индексом up функции f. Функция возвращает fail, если вспомогательная переменная с данным индексом отсутствует. В противном случае она возвращает имя вспомогательной переменной.
См. debug.getupvalue для получения дополнительной информации о вспомогательных переменных.
debug.setuservalue (udata, value, n)
Устанавливает заданное value в качестве n-го пользовательского значения, связанного с данным udata. udata должно быть полным пользовательским данными.
Возвращает udata, или fail, если у пользовательских данных нет этого значения.
debug.traceback ([thread,] [message [, level]])
Если message присутствует, но не является строкой и не равно nil, эта функция возвращает message без дальнейшей обработки. В противном случае она возвращает строку с отслеживанием стека вызовов. Необязательная строка message добавляется в начало отслеживания. Необязательное число level указывает, с какого уровня начать отслеживание (по умолчанию 1, функция, вызывающая traceback).
debug.upvalueid (f, n)
Возвращает уникальный идентификатор (в виде лёгких пользовательских данных) для вспомогательной переменной с номером n от заданной функции.
Эти уникальные идентификаторы позволяют программе проверять, разделяют ли различные замыкания вспомогательные переменные. Lua-замыкания, которые разделяют вспомогательную переменную (то есть, которые обращаются к одной и той же внешней локальной переменной), будут возвращать идентичные идентификаторы для этих индексов вспомогательных переменных.
debug.upvaluejoin (f1, n1, f2, n2)
Заставляет n1-ю вспомогательную переменную Lua-замыкания f1 ссылаться на n2-ю вспомогательную переменную Lua-замыкания f2.
7 – Lua Standalone
Хотя Lua был разработан как язык расширений, для встраивания в программу на языке C, он также часто используется как самостоятельный язык. Интерпретатор для Lua как самостоятельного языка, называемый просто lua, поставляется в стандартном дистрибутиве. Самостоятельный интерпретатор включает все стандартные библиотеки. Его использование:
lua [options] [script [args]]
Опции:
-
-e stat: выполнить строку stat; -
-i: войти в интерактивный режим после выполнения script; -
-l mod: "require" mod и назначить результат глобальной переменной mod; -
-v: вывести информацию о версии; -
-E: игнорировать переменные среды; -
-W: включить предупреждения; -
--: прекратить обработку опций; -
-: выполнитьstdinкак файл и прекратить обработку опций.
После обработки опций, lua выполняет заданный script. При вызове без аргументов, lua ведет себя как lua -v -i когда стандартный ввод (stdin) — терминал, и как lua - в противном случае.
Когда вызывается без опции -E, интерпретатор проверяет переменную среды LUA_INIT_5_4 (или LUA_INIT, если имя с версией не определено) перед выполнением аргументов. Если содержимое переменной имеет формат @filename, то lua выполняет файл. В противном случае, lua выполняет саму строку.
При вызове с опцией -E, Lua не обращается к переменным среды. В частности, значения package.path и package.cpath устанавливаются с помощью путей по умолчанию, определенных в luaconf.h.
Опции -e, -l, и -W обрабатываются в порядке их появления. Например, вызов
$ lua -e 'a=1' -llib1 script.lua
сначала установит a в 1, затем потребует библиотеку 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, скрипт компилируется как функция vararg.
В интерактивном режиме Lua многократно запрашивает и ждёт строку. После чтения строки Lua сначала пытается интерпретировать строку как выражение. Если это удается, он выводит его значение. В противном случае он интерпретирует строку как оператор. Если вы пишете неполный оператор, интерпретатор ждёт его завершения, выдав другое приглашение.
Если глобальная переменная _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.3 в Lua 5.4.
Вы можете избежать некоторых несовместимостей, скомпилировав Lua с соответствующими опциями (см. файл luaconf.h). Однако все эти опции совместимости будут удалены в будущем. Чаще всего проблемы совместимости возникают, когда эти опции совместимости удаляются. Поэтому, всякий раз, когда у вас есть возможность, вы должны попытаться протестировать свой код с версией Lua, скомпилированной без всех опций совместимости. Это облегчит переход к более новым версиям Lua.
Версии Lua всегда могут изменять API C таким образом, который не предполагает изменений исходного кода в программе, например, числовые значения констант или реализацию функций как макросы. Поэтому вы никогда не должны предполагать, что двоичные файлы совместимы между различными версиями Lua. Всегда перекомпилируйте клиенты API Lua при использовании новой версии.
Аналогично, версии Lua всегда могут изменять внутреннее представление предварительно скомпилированных блоков; предварительно скомпилированные блоки несовместимы между различными версиями Lua.
Стандартные пути в официальном дистрибутиве могут изменяться между версиями.
8.1 – Несовместимости в Языке
- Принудительное преобразование строк в числа в арифметических и побитовых операциях было удалено из основного языка. Библиотека строк выполняет аналогичную работу для арифметических (но не для побитовых) операций, используя метаметоды строк. Однако, в отличие от предыдущих версий, новая реализация сохраняет неявный тип числа в строке. Например, результат
"1" + "2"теперь является целым числом, а не числом с плавающей точкой. - Литеральные десятичные целые константы, которые выходят за пределы диапазона, читаются как числа с плавающей точкой, вместо того, чтобы «обходить» предел. Вы можете использовать шестнадцатеричную запись для таких констант, если хотите сохранить старое поведение (чтение их как целых чисел с обходом предела).
- Использование метаметода
__ltдля эмуляции__leбыло удалено. При необходимости этот метаметод должен быть явно определен. - Семантика числового цикла for по целым числам изменилась в некоторых деталях. В частности, переменная управления никогда не «обходит» пределы.
- Метка для оператора goto не может быть объявлена там, где видна метка с тем же именем, даже если эта другая метка объявлена в содержащем блоке.
- При финализации объекта Lua не игнорирует метаметоды
__gc, которые не являются функциями. Любое значение будет вызвано, если присутствует. (Невызываемые значения сгенерируют предупреждение, как и любая другая ошибка при вызове финализатора.)
8.2 – Несовместимости в библиотеках
- Функция
printне вызываетtostringдля форматирования своих аргументов; вместо этого она имеет эту функциональность встроенной. Вы должны использовать__tostringдля изменения способа печати значений. - Псевдослучайный генератор, используемый функцией
math.random, теперь запускается со случайным начальным значением. Кроме того, он использует другой алгоритм. - По умолчанию функции декодирования в библиотеке
utf8не принимают суррогаты как допустимые кодовые точки. Дополнительный параметр в этих функциях делает их более допускающими. - Параметры "
setpause" и "setstepmul" функцииcollectgarbageустарели. Вы должны использовать новый параметр "incremental" для их установки. - Функция
io.linesтеперь возвращает четыре значения, а не одно. Это может быть проблемой, когда она используется в качестве единственного аргумента другой функции с необязательными параметрами, например, вload(io.lines(filename, "L")). Чтобы исправить эту проблему, можно обернуть вызов в скобки, чтобы изменить количество возвращаемых результатов на одно.
8.3 – Несовместимости в API
- Полные пользовательские данные (userdata) теперь имеют произвольное количество связанных пользовательских значений. Поэтому функции
lua_newuserdata,lua_setuservalue, иlua_getuservalueбыли заменены наlua_newuserdatauv,lua_setiuservalue, иlua_getiuservalue, которые имеют дополнительный аргумент.Для совместимости старые имена по-прежнему работают как макросы, предполагая одно единственное пользовательское значение. Однако обратите внимание, что пользовательские данные с нулевыми пользовательскими значениями более эффективны с точки зрения памяти.
- Функция
lua_resumeимеет дополнительный параметр. Этот выходной параметр возвращает количество значений на вершине стека, которые были переданы или возвращены корутиной. (В предыдущих версиях эти значения были всем стеком.) - Функция
lua_versionвозвращает номер версии, а не адрес номера версии. Ядро Lua должно корректно работать с библиотеками, использующими свои собственные статические копии того же ядра, поэтому нет необходимости проверять, используют ли они одно и то же адресное пространство. - Константа
LUA_ERRGCMMбыла удалена. Ошибки в финализаторах больше не передаются; вместо этого они генерируют предупреждение. - Параметры
LUA_GCSETPAUSEиLUA_GCSETSTEPMULфункцииlua_gcустарели. Вы должны использовать новый параметрLUA_GCINCдля их установки.
9 – Полный синтаксис Lua
Вот полный синтаксис Lua в расширенном BNF. Как обычно в расширенном BNF, {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 |
local attnamelist [‘=’ explist]
attnamelist ::= 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 [‘,’ ‘...’] | ‘...’
tableconstructor ::= ‘{’ [fieldlist] ‘}’
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
fieldsep ::= ‘,’ | ‘;’
binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘//’ | ‘^’ | ‘%’ |
‘&’ | ‘~’ | ‘|’ | ‘>>’ | ‘<<’ | ‘..’ |
‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ |
and | or
unop ::= ‘-’ | not | ‘#’ | ‘~’
© 1994–2020 Lua.org, PUC-Rio.
Licensed under the MIT License.
https://www.lua.org/manual/5.4/manual.html