Справочное руководство по языку Lua 5.1

Lua 5.1 - Справочное руководство

Авторы: Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes

Copyright © 2006-2007 Lua.org, PUC-Rio. В свободном доступе в соответствии с Lua license.

содержание · индекс

1 - Введение

Lua является типичным процедурным языком программирования. Он предоставляет широкие возможности для объектно-ориентированной и функциональной разработки. Lua создавался как мощный и простой язык, обладающий всеми необходимыми выразительными средствами. Библиотека функций языка Lua написана на языке С (точнее на подмножестве ANSI C и C++).

Будучи расширяемым языком, Lua не имеет понятия "main" программы: он работает в среде исполнения, сокращенно называемой хост. Хост-программа позволяет запускать части кода, написанные на Lua, модифицировать переменные Lua и регистрировать С-функции для использования непосредственно в коде Lua. Благодаря возможности расширения с помощью С-функций, Lua может применяться для решения широкого круга задач. Таким образом, мы имеем возможность создавать специализированные библиотеки, использование которых ничем не отличается от использования стандартных средств языка. В поставку включена простая хост-программа lua, которая использует библиотеку Lua и представляет из себя полную и автономную реализацию интерпретатора языка.

Lua является свободно распространяемым программным средством, поэтому предоставляется без каких либо гарантий в соответствии с лицензией. Версия lua 5.1, которая описана в данном Руководстве, доступна на официальном сайте Lua www.lua.org.

Как и многие подобные Руководства, этот документ написан в формальном стиле. Для получения более подробной информации об особенностях применения языка рекомендуем обратиться к технической документации, доступной на официальном сайте Lua. Хорошим подспорьем в работе может оказаться книга Роберта Иерусалимского (Roberto Ierusalimschy) «Программирование на Lua», второе издание (Programming in Lua (Second Edition)).

2 - Описание языка

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

Конструкции языка будут вводится с использованием расширенной BNF, где запись {a} означает 0 или более элементов a, а запись [a] означает его необязательное вхождение. Нетерминальные символы отображаются обычным шрифтом, ключевые слова выделяются жирным шрифтом kword, все остальные терминальные символы заключаются в апострофы `=´. Полное описание синтаксиса языка Lua дано в конце Руководства.

2.1 - Лексические соглашения

Именами (идентификаторами) в Lua могут быть любые строки из букв, цифр и символа подчеркивания, не начинающиеся с цифры. Это правило типично для большинства языков программирования. (Понятие буквы зависит от текущей локали: любой символ из алфавита текущей локали может быть использован в составе идентификатора). Идентификаторы используются для именования переменных и таблиц значений (table fields).

Следующие ключевые слова зарезервированы и не могут быть использованы в именах:

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

Lua является языком, чувствительным к регистру символов: and – ключевое слово, тогда как And и AND – два разных допустимых идентификатора. По соглашению, имена, начинающиеся с символа подчеркивания и записанные в верхнем регистре (например _VERSION), зарезервированы для использования в качестве внутренних глобальных переменных, используемых Lua.

В следующих строках показаны другие допустимые символы:

     +     -     *     /     %     ^     #
     ==    ~=    <=    >=    <     >     =
     (     )     {     }     [     ]
     ;     :     ,     .     ..    ...

Литеральные строки должны быть заключены в одинарные или двойные кавычки и могут содержать следующие С-подобные escape-поледовательности: '\a' (звонок), '\b' (забой), '\f' (перевод страницы), '\n' (перевод на новую строку), '\r' (возврат каретки), '\t' (горизонтальная табуляция), '\v' (вертикальная табуляция), '\\' (обратный слэш), '\"' (двойная кавычка), и '\'' (апостроф [одинарная кавычка]). Кроме того, обратный слеш ставится перед концом строки в редакторе, когда для удобства набора длинные непрерывные строки записываются в несколько строк. Символ в строке также может быть представлен своим кодом с помощью escape-последовательности \ddd, где ddd - последовательность из не более чем трех цифр. (Заметим, что если после символа, записанного с помощью своего кода, должна идти цифра, то код символа в escape-последовательности должен содержать ровно три цифры). Строки в Lua могут содержать любые 8-битные значения, включая ноль, который записывается как '\0'.

Чтобы разместить в строке, ограниченной двойными кавычками, символы двойной (и одинарной) кавычки, символ новой строки, обратный слеш , или внедренный ноль, Вы должны использовать escape-последовательность. Любой другой символ может быть непосредственно вставлен в строку. (Некоторые управляющие символы могут причинить проблемы файловой системе, но сам Lua не имеет с ними никаких проблем.)

Литеральные строки могут также быть определены с использованием формата, обозначаемого длинными скобками (long brackets). Открывающаяся длинная скобка n-ной вложенности представляет собой открывающуюся квадратную скобку, сопровождаемую n-ным количеством одинаковых символов (индикаторов уровня вложенности), в конце которых размещается такая же открывающаяся квадратная скобка. Так открывающаяся длинная скобка 0 уровня вложенности будет выглядеть как [[, открывающаяся длинная скобка 1 уровня вложенности будет выглядеть как [=[, и так далее. Закрывающиеся длинные скобки записываются аналогично; так, например, закрывающаяся длинная скобка уровня 4 будет выглядеть как ]====]. Длинная строка начинается с открывающейся длинной скобки любого уровня и заканчивается на первой закрывающейся длинной скобке того же самого уровня. Литералы в этой заключенной в скобки форме могут размещаться в нескольких строках, не воспринимая никаких управляющих последовательностей, и игнорируя вложенные длинные скобки любого другого уровня. Они могут содержать что угодно кроме закрывающей скобки своего уровня.

Обычно, для удобства, открывающаяся длинная скобка сопровождается переводом строки. Символ перевода строки не будет включен в эту строку. В качестве примера, в системе использующей ASCII (в котором символ 'a' имеет код 97, символ перевода строки - 10, и символ '1' имеет код 49), пять строковых переменных ниже задают одну и ту же строку:

     a = 'alo\n123"'
     a = "alo\n123\""
     a = '\97lo\10\04923"'
     a = [[alo
     123"]]
     a = [==[
     alo
     123"]==]

Числовая константа может быть задана как с целой так и с дробной частью. Допустимо применение экспоненциальной формы записи. Lua также понимает целые шестнадцатеричные константы, при их записи с префиксом 0x. Примеры допустимой записи числовых констант

     3   3.0   3.1416   314.16e-2   0.31416E1   0xff   0x56

Комментарий начинается с двойного дефиса (--) расположенного где угодно, но только не внутри заключенного в кавычки стринга. Весь текст, расположенный после этих символов и до конца строки не выполняется как код и называется коротким комментарием. Если после -- стоит открывающаяся длинная скобка, то это - длинный комментарий, который действует до закрывающейся длинной скобки. Длинные комментарии часто используются, чтобы временно отключить участок кода.

2.2 - Значения и типы

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

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

В Lua восемь основных типов: nil (неопределенный), boolean (логический), number (числовой), string (строковый), function (функция), userdata (пользовательские данные), thread (поток), и table (таблица). Nil - это тип значения nil [пустое значение], главное свойство которого – отличаться от всех остальных значений и обозначать отсутствие пригодного значения. К типу Boolean относятся значения false (ложь) и true (истина). Значения nil и false считаются ложными, любое другое значение считается истинным. К типу Number относятся вещественные числа (двойной точности с плавающей запятой). (Легко можно сделать сборку интерпретатора Lua с другим внутренним представлением чисел, достаточно изменить определение в файле luaconf.h.). Тип String обозначает массивы символов. Строки Lua могут содержать любые 8 битные символы, включая ноль ('\0') (смотреть §2.1).

В Lua можно использовать функции, написанные на Lua и на C (смотреть §2.5.8).

Тип userdata (пользовательские данные) позволяет хранить любые данных из C в переменных Lua. Значение этого типа является ссылкой на блок физической памяти и не имеет предопределенных операций в Lua, за исключением присваивания и проверки на равенство. Однако, используя метатаблицы, программист может определить операции над значениями этого типа (смотрите §2.8). Значения типа userdata не могут быть созданы или изменены непосредственно в Lua, это возможно только с помощью C API. Такой подход гарантирует целостность данных, принадлежащих ведущей программе.

Тип thread (поток) обозначает независимый поток исполнения и используется при реализации механизма сопрограмм (смотрите §2.11). Нельзя отождествлять потоки Lua с потоками операционной системы. Lua поддерживает подпрограммы даже в тех системах, где потоки на уровне операционной системы не поддерживаются.

Тип table (таблица) определяет ассоциативные массивы. Такие массивы могут индексироваться не только числами, но и любыми значениями (за исключением nil). Таблица может гетерогенной, т.е. содержать значения сразу нескольких типов (кроме nil). Таблицы представляют собой единственный механизм структурирования данных в Lua; они могут использоваться как простые массивы, таблицы символов, множества, поля записей, деревья и так далее. Для представления словарей Lua использует имя поля в качестве индекса таблицы. Представление в виде a.name считается тождественным представлению a["name"]. В Lua есть несколько способов создания таблиц (смотреть §2.5.7).

Индексы и значения полей таблицы могут быть любого типа (кроме nil). В частности, так как функции являются значениями встроенного типа, поля таблицы могут содержать и функции. Таким образом, таблицы могут хранить методы methods (смотреть §2.5.9).

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

Библиотечная функция type возвращает строку, описывающую тип данного значения.

2.2.1 - Приведение типов

Lua обеспечивает автоматическое преобразование между строковыми и числовыми значениями в процессе выполнения. Любая арифметическая операция, применяемая к строке, пытается преобразовать эту строку в соответствующее число по обычным правилам приведения. Когда же число используется там, где ожидается строка, это число преобразуется в строку в произвольном подходящем формате. Так что для получения какого-то конкретного представления числа в строке необходимо использовать функцию format из библиотеки работы со строками (смотрите string.format).

2.3 - Переменные

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

Отдельный идентификатор может обозначать глобальную или локальную переменную (либо формальный параметр функции, что является частным случаем локальной переменной):

    var ::= Name

Где Name – идентификатор, определяемый в соответствии с §2.1.

Любая переменная считается глобальной, если она явно не объявлена как локальная (смотрите §2.4.7). Локальные переменные существуют в лексическом контексте: локальные переменные доступны функциям, определенным внутри этого контекста (смотрите §2.6).

До первого явного присвоения значением переменной является nil.

Квадратные скобки используются для доступа к элементу таблицы по индексу:

    var ::= prefixexp `[´ exp `]´

Способ доступа к глобальным переменным и полям таблицы может быть изменен с помощью мететаблиц. Доступ к переменной t[i] эквивалентен вызову gettable_event(t,i). (Полное описание функции gettable_event смотрите в §2.8. Эта функция недоступна в коде Lua, мы упомянули ее здесь в качестве примера).

Запись var.Name аналогична записи var["Name"]:

    var ::= prefixexp `.´ Name

Все глобальные переменные являются полями в обычных таблицах Lua, называемых таблицами окружения или кратко окружениями (смотреть §2.9). Каждая функция имеет ссылку на свое собственное окружение, и все глобальные переменные внутри этой функции ссылаются на данную таблиц. В момент создания функция наследует окружение вызывающей функции. Для получения таблицы окружения функции Lua можно вызвать функцию getfenv. Для перезаписи таблицы используется setfenv. (Вы можете манипулировать окружением C функций только с помощью отладочной библиотеки (смотрите §5.9).)

Обращение к глобальной переменной x эквивалентно _env.x, а также

     gettable_event(_env, "x")

где _env – окружение выполняющейся функции. (Полное описание функции gettable_event смотрите в §2.8. Эта функция недоступна в коде Lua, мы упомянули ее здесь в качестве примера).

2.4 - Операторы

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

2.4.1 - Порции

Единица исполнения Lua называется chunk (порция). Порция – это любая последовательность операторов Lua. Операторы в порции могут разделяться запятыми:

    chunk ::= {stat [`;´]}

Пустого оператора в языке нет, поэтому выражение ';;' не допустимо.

Lua воспринимает порцию как неименованную функцию с произвольным набором параметров (смотрите §2.5.9). Порция может определять локальные переменные и возвращать значения.

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

Порции могут быть компилированы в бинарный вид; подробнее в описании программы luac. Текстовые файлы с кодом и двоичные прекомпилированные части кода равноправны; Lua автоматически определяет тип файла и действует соответственно.

2.4.2 - Блоки

Блок это список операторов; синтаксически блок тождественно равен порции (chunk):

    block ::= chunk

Блок операторов может быть явно ограничен, таким образом представляется составной оператор:

    stat ::= do block end

С помощью составных операторов можно ограничивать области видимости локальных переменных. В составные операторы могут быть добавлены директивы return или break для выхода из середины блока (смотрите §2.4.4).

2.4.3 - Присваивание

Lua поддерживает параллельное присваивание. В общем случае, оператор присваивания выглядит как список переменных, символ ‘=’ и список выражений. Элементы списков указываются через запятую:

    stat ::= varlist `=´ explist
    varlist ::= var {`,´ var}
    explist ::= exp {`,´ exp}

Выражения рассмотрены в §2.5.

Перед выполнением присваивания список переменных согласовывается по длине со списком выражений. Если список справа длиннее, то его лишние элементы просто отбрасываются. Если короче, то недостающие позиции дополняются значениями nil. Если список операторов оканчивается вызовом функции, то перед согласованием все возвращаемые оттуда значения вставляются в правый список (за исключением случаев, когда вызов взят в скобки; смотрите §2.5).

Перед выполнением присваивания вычисляется значение всех выражений. Код

     i = 3
     i, a[i] = i+1, 20

означает, что переменной a[3] присваивается значение 20, потому что i в выражении a[i] имеет то же самое значение, что и в момент вычисления выражения i+1. Аналогично, строка

     x, y = y, x

является простым способом обмена значениями двух переменных x и y.(при "традиционном" способе требуется дополнительная переменная)

Действие операции присваивания для глобальных переменных и полей таблиц может быть переопределено посредством метатаблиц. Присваивание индексной переменной t[i] = val эквивалентно вызову settable_event(t,i,val). (Полное описание функции settable_event смотрите в §2.8. Эта функция недоступна в коде Lua, мы упомянули ее здесь в качестве примера.)

Присваивание к глобальной переменной x = val эквивалентно присваиванию _env.x = val, то же самое произойдет при вызове

     settable_event(_env, "x", val)

где _env окружение запущенной функции. (Переменная _env недоступна в Lua, мы приводим ее здесь в качестве примера.)

2.4.4 - Управляющие конструкции

Операторы if, while, и repeat имеют обычное значение и знакомый синтаксис:

    stat ::= while exp do block end
    stat ::= repeat block until exp
    stat ::= if exp then block {elseif exp then block} [else block] end

В Lua также имеется выражение for в двух вариантах (смотрите §2.4.5).

Логическое выражение в управляющих конструкциях может возвращать любое значение. Значения false и nil считаются ложными. Все остальные значения считаются истинными (в том числе значение 0 и пустая строка !).

Цикл repeat–until оканчивается условием, идущим следом за until, поэтому в условии можно ссылаться на локальные переменные, описанные внутри цикла.

Выражение return используется для того, чтобы возвратить значения из функции или порции. Синтаксис оператора return позволяет функции или порции вернуть несколько значений:

    stat ::= return [explist]

Оператор break используется для досрочного выхода из циклов while, repeat, или for:

    stat ::= break

break прерывает цикл, в теле которого встречается; внешние циклы продолжают выполнение.

Операторы return и break должны быть последними в блоке (иначе следующие за ним операторы никогда не выполнятся). Если действительно необходимо вставить return или break в середину блока, то следует применить составной оператор, например do return end или do break end.

2.4.5 - Оператор For

Оператор for допускает простую и расширенную формы записи.

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

    stat ::= for Name `=´ exp `,´ exp [`,´ exp] do block end

block повторяется для переменной цикла name начиная со значения первого выражения exp, до тех пор пока выполняется второе выражение exp с шагом третьего выражения exp.
Таким образом, запись

     for v = e1, e2, e3 do block end

эквивалентна коду:

     do
       local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
       if not (var and limit and step) then error() end
       while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
         local v = var
         block
         var = var + step
       end
     end

Обратите внимание, что:

  • Все три логических выражения вычисляются только один раз перед началом цикла, причем полученные значения должны быть числами.
  • var, limit, и step неявные переменные, мы условно именовали их здесь для объяснения логики работы.
  • Если выражение step (шаг) отсутствует, то по умолчанию используется 1.
  • Для выхода из цикла for используйте break.
  • Переменная v является локальной для цикла; вы не сможете использовать ее значение после выхода из цикла for. Если вам необходимо значение этой переменной, присвойте его другой переменной перед выходом из цикла

Расширенная форма оператора for реализована с использованием функций итераторов. На каждом обороте для получения нового значения переменной цикла вызывается итератор. Цикл заканчивается, когда итератор вернет nil. Синтаксис расширенного оператора for:

    stat ::= for namelist in explist do block end
    namelist ::= Name {`,´ Name}

Запись

     for var_1, ···, var_n in explist do block end

можно представить как:

     do
       local f, s, var = explist
       while true do
         local var_1, ···, var_n = f(s, var)
         var = var_1
         if var == nil then break end
         block
       end
     end

Заметим, что:

  • explist вычисляется только однажды. Его результатом является функция итератор, таблица состояний и начальное значение индекса.
  • f, s, и var неявные переменные, именованные здесь для примера.
  • Выйти из цикла можно с помощью оператора break.
  • Переменная var_i является локальной; вы не сможете использовать ее значение после выхода из for. Если вам необходимо ее значение, заранее сохраните его в другой переменной.

2.4.6 - Вызов функции

Для создания побочных эффектов может быть полезен вызов функций, используемый в качестве оператора:

    stat ::= functioncall

В этом случае все возвращаемые значения отбрасываются. Вызовы функций рассматриваются в §2.5.8.

2.4.7 - Локальные объявления

Локальные переменные могут быть объявлены где угодно внутри блока. Объявление может включать инициализацию:

    stat ::= local namelist [`=´ explist]

Инициализация обладает всеми свойствами операции присваивания (в том числе параллельностью) (смотрите §2.4.3). По умолчанию все переменные инициализируются значением nil.

Порция является блоком (смотрите §2.4.1), поэтому локальные переменные могут быть объявлены вне любого явно заданного блока. Областью действия таких локальных переменных являются границы порции.

Правила видимости для локальных переменных рассмотрены в §2.6.

2.5 - Выражения

Выражениями в Lua являются следующие конструкции:

    exp ::= prefixexp
    exp ::= nil | false | true
    exp ::= Number
    exp ::= String
    exp ::= function
    exp ::= tableconstructor
    exp ::= `...´
    exp ::= exp binop exp
    exp ::= unop exp
    prefixexp ::= var | functioncall | `(´ exp `)´

Числа и символьные строки рассмотрены в §2.1;
переменные - в §2.3;
описания функций - в §2.5.9;
вызовы функций §2.5.8;
конструкторы таблиц - в §2.5.7.
Неявные аргументы, обозначаемые ('...'), могут использоваться только внутри соответственно заданной функции; смотрите §2.5.9.

К бинарным операциям (binop в формальном определении выражения) относятся арифметические (смотрите §2.5.1), операции сравнения (§2.5.2), булевские (§2.5.3), и операции конкатенации (§2.5.4). Унарными являются унарный минус (§2.5.1), отрицание not (§2.5.3), и операция получения длины # (§2.5.5).

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

Далее несколько примеров:

     f()                -- результат функции отбрасывается
     g(f(), x)          -- берется первое значение из списка - результата вызова f()
     g(x, f())          -- g получает x и все значения, полученные из f()
     a,b,c = f(), x     -- берется первый элемент результата вызова f()(и c получает nil)
     a,b = ...          -- a получает первый параметр из ..., b - второй
                        -- причем а и b могут получить nil, если
                        -- в качестве неявных параметров ничего не передано)

     a,b,c = x, f()     -- 2 результата из f()
     a,b,c = f()        -- 3 результата из f()
     return f()         -- возвращает все значения из f()
     return ...         -- возвращает все полученные неявные аргументы
     return x,y,f()     -- вернет x, y и все, что вернет f()
     {f()}              -- создаст список со всем результатами вызова f()
     {...}              -- создаст список со всеми неявными параметрами
     {f(), nil}         -- 1 результат из f()

Выражение, заключенное в скобки всегда возвращает только одно значение. Таким образом, (f(x,y,z)) всегда даст единственное значение, даже если f возвращает несколько. (Значение (f(x,y,z)) это первое значение, полученное из f или nil, если f не возвращает значений.)

2.5.1 - Арифметические операции

Lua поддерживает обычные арифметические операции: двоичные + (сложение), - (вычитание), * (умножение), / (деление), % (остаток от деления), и ^ (возведение в степень); а также унарный минус - (изменение знака числа). Если операнды являются числами или строками (которые могут быть преобразованы в числа §2.2.1), то операции выполняются обычным образом . Возведение в степень работает для любого показателя степени. Например, x^(-0.5) подсчитывает величину, обратную квадратному корню из x. Остаток от деления определен как

     a % b == a - math.floor(a/b)*b

То есть это - остаток от деления, который округляет частное к минус бесконечность.

2.5.2 - Операции сравнения

Операции сравнения в Lua:

     ==    ~=    <     >     <=    >=

Эти операции всегда возвращают false или true.

Сравнение на равенство (==) сначала сравнивает типы операндов. Если типы различны, то результатом будет false. Иначе сравниваются значения операндов. Числа и строки сравниваются обычным способом. Объекты (таблицы, пользовательские данные, потоки и функции) сравниваются по ссылке: два объекта считаются равными, только если они являются одним и тем же объектом. Создаваемый объект (таблица, пользовательские данные, поток или функция) не может быть равен ни одному из уже существующих.

Вы можете изменить способ, которым Lua сравнивает таблицы и пользовательские данные, используя метаметод "eq" (см. §2.8).

Правила преобразования из §2.2.1 не работают в сравнениях на равенство. Например, "0"==0 вернет false, а t[0] и t["0"] обозначают различные записи в таблице.

Оператор ~= прямо противоположен оператору равенства (==).

Операторы сравнения на больше-меньше работают следующим образом. Если оба параметра - числа, то они сравниваются как обычно. Если оба параметра строки, то их значения сравниваются в соответствии с лексикографическим порядком. Во всех остальных ситуациях будет вызван метаметод "lt" или "le" (см. §2.8).

2.5.3 - Логические операции

В Lua это операции and, or, и not. Так же, как и в управляющих конструкциях (§2.4.4), все логические операции рассматривают false и nil как ложь, а все остальное как истину.

Операция отрицания not всегда возвращает false или true. Операция конъюнкции and возвращает свой первый параметр, если его значение false или nil; в противном случае, and возвращает второй параметр. Оператор дизъюнкции or возвращает первый параметр, если его значение отлично от nil и false; в противном случае, or возвращает второй параметр. И and и or вычисляют второй операнд только в случае необходимости. Примеры:

     10 or 20            --> 10
     10 or error()       --> 10
     nil or "a"          --> "a"
     nil and 10          --> nil
     false and error()   --> false
     false and nil       --> false
     false or nil        --> nil
     10 and 20           --> 20

(В данном руководстве, --> указывает на результат предшествующего выражения.)

2.5.4 - Конкатенация

Оператор конкатенации (соединения) строк в Lua обозначается двумя точками ('..'). Если оба операнда являются строками или числами, то они будут преобразованы в строки согласно правилам §2.2.1. Иначе будет вызван метаметод "concat" (см. §2.8).

2.5.5 - Получение длины

Операция получения длины обозначается унарным #. В результате применения операции к строке возвращается количество байт (в обычном понимании это длина строки, в которой каждый символ занимает 1 байт).

Длиной таблицы t считается любой целый индекс n такой, что t[n] не равен nil, а t[n+1] равно nil. Кроме того, если t[1] равен nil, то #t = 0. Для регулярных массивов от 1 до n, не содержащих значений nil, длиной является n, то есть индекс последнего значения. Если в массиве присутствуют "дыры" (т.е., значения nil между ненулевыми значениями), то значением #t является индекс элемента, непосредственно предшествующего элементу nil (поэтому любое значение nil по сути означает конец массива).

2.5.6 - Приоритет операций

Приоритет операций Lua показан на таблице ниже. Самым высоким приоритетом обладает операция возведения в степень, далее по убыванию:

     or
     and
     <     >     <=    >=    ~=    ==
     ..
     +     -
     *     /     %
     not   #     - (unary)
     ^

Как обычно, для изменения порядка вычисления выражений вы можете использовать скобки. Конкатенация ('..') и возведение в степень ('^') правоассоциативные операторы. Все остальные бинарные операторы левоассоциативные.

2.5.7 - Конструкторы таблиц

Конструкторы таблиц тоже относятся к выражениям. Обработка любого встречающегося в коде конструктора ведет к созданию новой таблицы. С помощью конструкторов можно создать как пустые, так и частично либо полностью заполненные таблицы. Полное описание синтаксиса конструкторов:

    tableconstructor ::= `{´ [fieldlist] `}´
    fieldlist ::= field {fieldsep field} [fieldsep]
    field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
    fieldsep ::= `,´ | `;´

Каждое поле вида [exp1] = exp2 добавляет в новую таблицу значение exp2 с ключом exp1. Поле вида name = exp эквивалентно ["name"] = exp. Поле вида exp эквивалентно [i] = exp, где i – целочисленный автоинкрементный счетчик, начинающийся с 1. Поля в других форматах не оказывают влияния на этот счетчик. Например,

     a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }

эквивалентно

     do
       local t = {}
       t[f(1)] = g
       t[1] = "x"         -- 1st exp
       t[2] = "y"         -- 2nd exp
       t.x = 1            -- t["x"] = 1
       t[3] = f(x)        -- 3rd exp
       t[30] = 23
       t[4] = 45          -- 4th exp
       a = t
     end

Если последнее поле в списке задано в форме exp и это вызов функции или неопределенный список параметров, то все значения, возвращаемые этим выражением, последовательно включаются в этот список (см. §2.5.8). Чтобы этого избежать, необходимо заключить вызов функции (или список неопределенных параметров) в скобки (см. §2.5).

Список полей может оканчиваться разделителем, что улучшает читабельность машинно-генерируемого кода.

2.5.8 - Вызовы функций

Вызовы функций в Lua имеют следующий синтаксис:

    functioncall ::= prefixexp args

В вызове функции сначала вычисляются префиксное выражение и аргументы. Если значение префиксного выражения имеет тип function, то эта функция будет вызвана с указанными аргументами. В противном случае вызывается метаметод “call”, параметрами которого будет значение префиксного выражения, за которым следуют первоначальные аргументы (см. §2.8).

Форма записи

    functioncall ::= prefixexp `:´ Name args

может использоваться для вызова "методов". Запись v:name(args) синтаксически аналогична записи v.name(v,args), только v вычисляется один раз.

Аргументы описываются следующим образом:

    args ::= `(´ [explist] `)´
    args ::= tableconstructor
    args ::= String

Все выражения вычисляются перед вызовом. Вызов в форме f{fields} синтаксически аналогичен f({fields}); то есть список аргументов является по сути новой таблицей. Вызов в форме f'string' (или f"string" или f[[string]]) синтаксически равен f('string'); в данном случае список аргументов - единственная символьная строка.

Исключением в довольно свободном синтаксисе Lua является правило, по которому нельзя переходить на новую строку непосредственно перед символом '(' в вызове функции. Это ограничение позволяет избежать некоторой двусмысленности в языке. Если вы напишите

     a = f
     (g).x(a)

Lua трактует эту запись как выражение a = f(g).x(a). Поэтому, если вам нужно 2 выражения, вы должны добавить точку с запятой между ними. Если вы действительно хотите вызвать f, то необходимо убрать переход на новую строку перед (g).

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

     return (f(x))        -- список-результат обрезается до 1
     return 2 * f(x)      -- удвоение результата функции
     return x, f(x)       -- возвращается несколько значений
     f(x); return         -- результат вызова отбрасывается
     return x or f(x)     -- список-результат обрезается до 1

2.5.9 - Объявление функций

Синтаксис объявления функций:

    function ::= function funcbody
    funcbody ::= `(´ [parlist] `)´ block end

Или в упрощенном виде:

    stat ::= function funcname funcbody
    stat ::= local function Name funcbody
    funcname ::= Name {`.´ Name} [`:´ Name]

Выражение

     function f () body end

транслируется в

     f = function () body end

Выражение

     function t.a.b.c.f () body end

транслируется в

     t.a.b.c.f = function () body end

Выражение

     local function f () body end

транслируется в

     local f; f = function () body end

а не в

     local f = function () body end

(Разница проявится в том случае, если в теле функции используется имя этой функции, например при рекурсивном вызове f.)

Объявление функции является выполняемым выражением, его результатом будет значение типа function. Когда Lua прекомпилирует порцию, тела всех упоминающихся в ней функций также прекомпилируются. Таким образом, всякий раз, когда Lua обрабатывает объявление функции, функция уже конкретизирована (или замкнута). Этот конкретный экземпляр функции (или замыкание) и является конечным значением выражения «объявление функции». Различные экземпляры одной и той же функции могу ссылаться на различные внешние локальные переменные и иметь различные таблицы окружения.

Параметры функции фактически являются локальными переменными, которые инициализированы входными значениями:

    parlist ::= namelist [`,´ `...´] | `...´

В момент вызова функции длина списка передаваемых параметров приводится в соответствие спецификации, если это не функция с неопределенным количеством параметров. Для функций с неопределенным количеством параметров такая коррекция не проводится; все входные параметры попадают в функцию в виде неопределенного выражения, которое также обозначается с тремя точками ('...'). Значением этого выражения является список всех полученных входных параметров, как в случае множественного результата функции. Если неопределенное выражение используется внутри другого выражения или в середине списка выражений, то его значение-список урезается до одного элемента. Если это выражение стоит в конце списка выражений, урезания не происходит (если конечно вызов не заключен в круглые скобки).

Рассмотрим следующие объявления:

     function f(a, b) end
     function g(a, b, ...) end
     function r() return 1,2,3 end

Пример отображения входных значений на параметры функции:

     ВЫЗОВ            ПАРАМЕТРЫ

     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, ... -->  (ничто)
     g(3, 4)          a=3, b=4,   ... -->  (ничто)
     g(3, 4, 5, 8)    a=3, b=4,   ... -->  5  8
     g(5, r())        a=5, b=1,   ... -->  2  3

Результаты возвращаются из функции оператором return (см. §2.4.4). Если управление достигает конца функции не сталкиваясь с директивой return, тогда функция возвращается без результатов.

Синтаксис с двоеточием используется для определения методов. Эти функций неявно получают параметр self в качестве первого аргумента. Таким образом, выражение

     function t.a.b.c:f (params) body end

аналогично

     t.a.b.c.f = function (self, params) body end

2.6 - Области видимости

Lua - язык с лексическим разграничением областей видимости. Область видимости переменной начинается первым выражением после ее объявления и действует до конца блока, в котором это объявление встречается. Рассмотрим следующий пример:

     x = 10                -- глобальная переменная variable
     do                    -- начало блока
       local x = x         -- объявление локальной переменной 'x', она будет равна 10
       print(x)            --> 10
       x = x+1
       do                  -- начало вложенного блока
         local x = x+1     -- другая локальная 'x'
         print(x)          --> 12
       end
       print(x)            --> 11
     end
     print(x)              --> 10  (глобальная переменная)

Отметим, что в объявлении local x = x, локальная переменная x объявляется еще не в области своей видимости, поэтому x присваивается именно внешняя переменная.

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

Обработка каждого объявления local ведет к созданию новой локальной переменной. Рассмотрим следующий пример:

     a = {}
     local x = 20
     for i=1,10 do
       local y = 0
       a[i] = function () y=y+1; return x+y end
     end

Цикл создает 10 экземпляров функции, в которых используются различные переменные y и один и тот же x.

2.7 - Обработка ошибок

Поскольку Lua является языком расширений, работа Lua начинаются с момента вызова в C-коде базовой программы функции из Lua-библиотеки (lua_pcall). При возникновении ошибки в процессе компиляции или выполнения Lua управление возвращается в C-программу, где и осуществляется ее обработка (например вывод сообщения о ошибке).

Lua-код может явно генерировать ошибку, вызывая функцию error. Если вам нужно перехватывать ошибки в самом Lua, вы можете использовать функцию pcall.

2.8 - Метатаблицы

Любое значение в Lua может иметь метатаблицу. Метатаблица – это обычная таблица Lua, в которой определены допустимые операции над значением. Вы можете изменить действие некоторых операции над значением путем задания соответствующих полей в его метатаблице. Для экземпляров классов, например когда к нечисловым значениям применяется операция сложения, Lua ищет реализацию этой операции в поле "__add" его метатаблицы. Если реализация найдена, Lua запускает эту операцию для выполнения сложения.

Ключевые поля в метатаблице мы называем событиями, а значения - метаметодами. В рассмотренном примере событием является "add" а метаметодом является функция сложения.

Получить метатаблицу любого значения можно с помощью функции getmetatable.

Вы можете заменить метатаблицу с помощью функции setmetatable. Вы не можете изменить метатаблицу другим способом (of other types – других типов???) (за исключением случаев использования отладочной библиотеки), для этого требуется воспользоваться C API.

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

В метатаблице могут быть заданы правила выполнения арифметических операций над объектом, порядок сравнения, конкатенации, способ вычисления длины и индексирования. Также в метатаблице может быть определена функция «сборки мусора». Для каждой из этих операций в Lua определен специальный ключ, называемый событие. В момент, когда Lua выполняет одну из этих операций над значением, проверяется, есть ли в метатаблице значение с соответствующим событием. Если оно найдено, значение по этому ключу (метаметод) и определяет способ выполнения операции.

Далее рассмотрим управление операциями с помощью метатаблиц. Каждая операция идентифицируется по своему имени. Ключ каждой операции представляет из себя строку из имени и двух нижних подчеркиваний '__' перед ним. Для экземпляра – ключом операции “add” будет строка "__add". Для лучшего понимания мы в терминах Lua покажем запуск операции интерпретатором.

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

     metatable(obj)[event]

Это следует читать как

     rawget(getmetatable(obj) or {}, event)

Таким образом, при получении доступа к метаметоду другие метаметоды не используются, поэтому доступ к объекту без метатаблицы не приводит к ошибке (мы просто получим nil).

  • "add": операция сложения +.

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

         function getbinhandler (op1, op2, event)
       return metatable(op1)[event] or metatable(op2)[event]
     end

    С помощью этой функции поведение конструкции op1 + op2 выглядит как

         function add_event (op1, op2)
       local o1, o2 = tonumber(op1), tonumber(op2)
       if o1 and o2 then  -- операнды являются числами?
         return o1 + o2   -- '+' здесь – стандартная операция сложения
       else  -- когда хотя бы один из операндов нечисловой
         local h = getbinhandler(op1, op2, "__add")
         if h then
           -- вызов функции с операндами по указателю
           return h(op1, op2)
         else  -- указатель не найден: обработка ошибки
           error(···)
         end
       end
     end

  • "sub": операция -. Обработка аналогична "add".
  • "mul": операция *. Обработка аналогична "add".
  • "div": операция /. Обработка аналогична "add".
  • "mod": операция %. Обработка похожа на "add", только o1 - floor(o1/o2)*o2 подставляется вместо стандартной операции.
  • "pow": операция ^ (экспонента). Обработка похожа на "add", только вместо стандартной операции подставляется функция pow (из математической библиотеки C).
  • "unm": операция "унарный минус".
         function unm_event (op)
       local o = tonumber(op)
       if o then  -- операнд является числом?
         return -o  -- '-' здесь – стандартый оператор
       else  -- операнд нечисловой.
         -- Попытка получить указатель на функцию по операнду
         local h = metatable(op).__unm
         if h then
           -- вызов функции с операндом на входе
           return h(op)
         else  -- указатель не найден: обработка ошибки
           error(···)
         end
       end
     end

  • "concat": Операция конкатенации ...
         function concat_event (op1, op2)
       if (type(op1) == "string" or type(op1) == "number") and
          (type(op2) == "string" or type(op2) == "number") then
         return op1 .. op2  -- стандартная конкатенация строк
       else
         local h = getbinhandler(op1, op2, "__concat")
         if h then
           return h(op1, op2)
         else
           error(···)
         end
       end
     end

  • "len": Операция #.
         function len_event (op)
       if type(op) == "string" then
         return strlen(op)         -- стандартная функция
       elseif type(op) == "table" then
         return #op                -- стандартная функция для таблиц
       else
         local h = metatable(op).__len
         if h then
           -- вызов функции по указателю
           return h(op)
         else  -- указатель не найден: обработка ошибки
           error(···)
         end
       end
     end

    Смотрите §2.5.5 с описанием функции вычисления длины таблицы.

  • "eq": Операция ==. Функция getcomphandler определяет, как Lua выбирает метаметод для сравнения операторов. Метаметод вызывается, только если сравниваются объекты одного типа, и метаметоды объектов для этой операции равны.
         function getcomphandler (op1, op2, event)
       if type(op1) ~= type(op2) then return nil end
       local mm1 = metatable(op1)[event]
       local mm2 = metatable(op2)[event]
       if mm1 == mm2 then return mm1 else return nil end
     end

    Событие "eq" определяется следующим образом:

         function eq_event (op1, op2)
       if type(op1) ~= type(op2) then  -- типы различны?
         return false   -- объекты не равны
       end
       if op1 == op2 then   -- стандартное сравнение истинно?
         return true   -- объекты равны
       end
       -- попытка получения метаметода
       local h = getcomphandler(op1, op2, "__eq")
       if h then
         return h(op1, op2)
       else
         return false
       end
     end

    a ~= b означает отрицание not (a == b).

  • "lt": Операция <.
         function lt_event (op1, op2)
       if type(op1) == "number" and type(op2) == "number" then
         return op1 < op2   -- числовое сравнение
       elseif type(op1) == "string" and type(op2) == "string" then
         return op1 < op2   -- лексическое сравнение
       else
         local h = getcomphandler(op1, op2, "__lt")
         if h then
           return h(op1, op2)
         else
           error(···);
         end
       end
     end

    a > b эквивалентно b < a.

  • "le": Операция <=.
         function le_event (op1, op2)
       if type(op1) == "number" and type(op2) == "number" then
         return op1 <= op2   -- числовое сравнение
       elseif type(op1) == "string" and type(op2) == "string" then
         return op1 <= op2   -- лексическое сравнение
       else
         local h = getcomphandler(op1, op2, "__le")
         if h then
           return h(op1, op2)
         else
           h = getcomphandler(op1, op2, "__lt")
           if h then
             return not h(op2, op1)
           else
             error(···);
           end
         end
       end
     end

    a >= b эквивалентно b <= a. Заметим, что при отсутствии метаметода "le" , Lua пытается применить метаметод "lt", полагая, что a a <= b эквивалентно отрицанию not (b < a).

  • "index": Доступ по индексу table[key].
         function gettable_event (table, key)
       local h
       if type(table) == "table" then
         local v = rawget(table, key)
         if v ~= nil then return v end
         h = metatable(table).__index
         if h == nil then return nil end
       else
         h = metatable(table).__index
         if h == nil then
           error(···);
         end
       end
       if type(h) == "function" then
         return h(table, key)      -- вызов по указателю
       else return h[key]          -- или рекурсивный вызов операции
       end
     end

  • "newindex": Индексированное присваивание table[key] = value.
         function settable_event (table, key, value)
       local h
       if type(table) == "table" then
         local v = rawget(table, key)
         if v ~= nil then rawset(table, key, value); return end
         h = metatable(table).__newindex
         if h == nil then rawset(table, key, value); return end
       else
         h = metatable(table).__newindex
         if h == nil then
           error(···);
         end
       end
       if type(h) == "function" then
         return h(table, key,value)    -- вызов по указателю
       else h[key] = value             -- или рекурсивный вызов операции
       end
     end

  • "call": вызывается, когда Lua запускает функцию.
         function function_event (func, ...)
       if type(func) == "function" then
         return func(...)   -- стандартный вызов
       else
         local h = metatable(func).__call
         if h then
           return h(func, ...)
         else
           error(···)
         end
       end
     end

2.9 - Окружение

Кроме метатаблиц, объекты типа thread, function и userdata обладают дополнительными таблицами, которые называют окружением. Подобно метатаблицам, окружения являются регулярными таблицами и множество объектов могут совместно использовать одно окружение.

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

Окружения, относящиеся к типу threads, называют глобальными окружениями. Они используются как окружения по умолчанию для потоков и невложенных функций, созданных в потоке (с помощью loadfile, loadstring или load) и могут использоваться непосредственно в С-коде (смотрите §3.3).

Окружения, ассоциированные с C-функциями, могут непосредственно использоваться в C-коде (смотрите §3.3). Они используются как окружения по умолчанию для других С-функций, созданных на базе этой.

Окружения, ассоциированные со стандартными функциями Lua, используются для доступа к глобальным переменным из любой функции (смотрите §2.3). Они используются по умолчанию для других функций Lua, построенных на базе этих.

Вы можете изменять окружение функций Lua или запускать потоки при помощи вызова setfenv. Вы можете получить окружение Lua-функции или запущенного потока с помощью getfenv. Доступ к окружению других объектов (типа userdata, функций C, потоков) возможен посредством C API.

2.10 - Сборщик мусора

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

В Lua реализован инкрементный сборщик по принципу пометить-очистить. Цикл работы сборщика мусора зависит от двух параметров: пауза сборки мусора и коэффициент шага сборки.

Паузой определяется время между запусками циклов сборки. Большие значения этого параметра делают сборку мусора менее активной. Значения меньше 1 означают, что между запусками циклов сборки паузы нет. При значении 2 сборщик перед следующим запуском ждет удвоения объема использованной памяти.

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

Вы можете менять эти параметры посредством вызова lua_gc в C или collectgarbage в Lua. В обоих случаях в качестве аргументов берутся проценты (т.е. аргумент 100 означает значение параметра 1).Этими функциями вы можете непосредственно управлять сборкой (например, останавливать ее или рестартовать).

2.10.1 - Метаметоды сборщика мусора

Используя C API, мы можем определить метаметоды сборщика для данных типа userdata (смотрите §2.8). Эти метаметоды также называются файнолайзерами. Файнолайзер позволяет вам координировать работу сборщика мусора Lua с внешними менеджерами ресурсов (например при закрытии файлов, сетевых подключений и подключений к базам данных, или же при освобождении собственной памяти).

Данные сборщика мусора с полем __gc в собственной метатаблице не хранятся непосредственно в нем. Вместо этого Lua сохраняет их в списке. После сбора мусора Lua выполняет над этими данными функцию, эквивалентную:

     function gc_event (udata)
       local h = metatable(udata).__gc
       if h then
         h(udata)
       end
     end

После каждого цикла сбора, финализаторы каждого элемента данных вызываются в порядке, обратном порядку их создания в цикле. Таким образом, первый файнолайзер будет вызван для объекта, созданного последним.

2.10.2 - Таблицы «слабых» ссылок

Таблицы этого типа используются для хранения «слабых» ссылок (weak references). Сборщик мусора игнорирует «слабые» ссылки. Другими словами, если единственной ссылкой на объект является «слабая» ссылка, то сборщик мусора сохраняет этот объект в такой таблице.

Таблица «слабых» ссылок может содержать «слабые» ключи, «слабые» значения, а также и то, и другое. Таблица со «слабыми» ключами позволяет хранить эти ключи, но не допускает хранение их значений. Таблица со «слабыми» ключами и «слабыми» значениями соответственно позволяет хранить и ключи, и значения. Таким образом, если ключ или значение сохранены, то соответствующая пара удаляется из таблицы. «Слабость» в таблице контролируется полем __mode ее метатаблицы. Если поле __mode это строка, содержащая символ 'k', то ключи в таблице «слабые». Если __mode содержит 'v', то в таблице хранятся «слабые» значения.

После использования таблицы как метатаблицы вы не можете изменить поле __mode. Таким образом, «слабое» поведение таблицы, за которое отвечает метатаблица, переопределить нельзя.

2.11 - Подпрограммы

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

Подпрограммы создаются вызовом coroutine.create. Единственным аргументом является имя главной функции подпрограммы. Функция create только создает новую подпрограмму и возвращает указатель на нее (объект типа thread), запуск подпрограммы не выполняется.

При вызове функции coroutine.resume и передаче ей в качестве первого аргумента результата вызова coroutine.create, процедура запускается на выполнение с первого оператора ее главной функции. Остальные параметры из вызова coroutine.resume передаются в основную функцию подпрограммы. После запуска подпрограмма выполняется до завершения либо до вызова yields.

Подпрограмма останавливается только в двух случаях: нормально, когда осуществляется возврат (явно или неявно) из главной функции; или аварийно в случае необработанной ошибки. При нормальном завершении coroutine.resume возвращает true.

Для приостановки выполнения подпрограммы используется функция coroutine.yield. При вызове yields соответствующий coroutine.resume возвращает управление немедленно, точно так же, как если бы вызов yield произошел во вложенном вызове функции (т.е. не в главной функции, а в функции, вызванной непосредственно или опосредованно из нее). При вызове yield функция coroutine.resume также возвращает true плюс все входные параметры, переданные в coroutine.yield. В следующий раз, когда подпрограмма продолжит работу, ее выполнение начнется с оператора, следующего за yield, соответственно из coroutine.yield вернутся параметры, переданные в coroutine.resume.

Функция coroutine.create создает подпрограмму и осуществляет ее запуск. Параметры, переданные в нее в качестве дополнительных аргуметров, попадают в неявный вызов coroutine.resume. Вызов coroutine.wrap возвращает те же значения, что и coroutine.resume, за исключением первого (булевского кода ошибки). В отличие от coroutine.resume, coroutine.wrap не перехватывает ошибки – все ошибки попадают на уровень вызывающей функции.

Рассмотрим в качестве примера следующий код:

     function foo (a)
       print("foo", a)
       return coroutine.yield(2*a)
     end

     co = coroutine.create(function (a,b)
           print("co-body", a, b)
           local r = foo(a+1)
           print("co-body", r)
           local r, s = coroutine.yield(a+b, a-b)
           print("co-body", r, s)
           return b, "end"
     end)

     print("main", coroutine.resume(co, 1, 10))
     print("main", coroutine.resume(co, "r"))
     print("main", coroutine.resume(co, "x", "y"))
     print("main", coroutine.resume(co, "x", "y"))

При запуске на экран выведется:

     co-body 1       10
     foo     2

     main    true    4
     co-body r
     main    true    11      -9
     co-body x       y
     main    true    10      end
     main    false   cannot resume dead coroutine

3 - Интерфейс программирования приложений (API)

В этой главе рассматривается C API языка Lua. С помощью этого набора C-функций хост-программа может осуществлять доступ к среде и функциональности Lua. Все функции API и соответствующие типы и константы описаны в заголовочном файле lua.h.

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

Как и большинство C-библиотек, функции API Lua не проверяют свои входные параметры на допустимость и непротиворечивость. Однако, вы можете добавить такую проверку, изменив макрос luai_apicheck, в файле luaconf.h.

3.1 - Стек

В Lua используется виртуальный стек для обмена данными с С-кодом. Каждый элемент этого стека представлен в Lua значением (nil, число, строка и т.п.).

Когда из Lua вызывается C-код, вызываемая функция получает новый стек, независимый от предыдущих стеков и стека С-функций. Изначально стек содержит все аргументы для С-функции, вызывающая программа получает результат вызова также из стека (смотрите lua_CFunction).

Для простоты, большинство вызовов API не придерживаются строгого алгоритма работы со стеком (последний вошел – первый вышел). Напротив, любой элемент стека доступен по индексу: положительное значение индекса обозначает абсолютную позицию в стеке (начинающуюся с 1); отрицательное значение – смещение относительно вершины стека. То есть, если в стеке n элементов, то индекс равный 1 означает первый элемент (тот, который попал в стек первым), а индекс равный n – последний. Индекс -1 также указывает на последний элемент стека, а индекс -n - первый. Индекс является допустимым, если удовлетворяет условию: 1 ≤ abs(index) ≤ top.

3.2 - Размер стека

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

Для вызова из Lua кода на C необходимо иметь в наличии свободной памяти по крайней мере на LUA_MINSTACK позиций стека. LUA_MINSTACK по умолчанию равно 20. Таким образом, вам не придется заботится о стеке (если только ваш код не помещает туда значения в цикле).

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

     (index < 0 && abs(index) <= top) ||
     (index > 0 && index <= stackspace)

Заметим, что 0 не является допустимым индексом.

3.3 - Псевдо-индексы

За исключением особых случаев, любая параметризованная функция Lua может быть вызвана с псевдо-индексами. (Так как параметры передаются в функции через стек, каждому входному параметру соответствует индекс стека. Здесь речь идет и мнимых индексах стека – фактически это специальные переменные Lua, с которыми можно работать как с элементами стека). Это переменные Lua, доступные из С-кода, но не находящиеся в стеке. Псевдо-индексы используются для доступа к окружению потока, окружению функции, регистру и внешним значениям (§3.4).

Окружение потока (пространство жизни глобальных переменных) всегда доступно посредством псевдо-индекса LUA_GLOBALSINDEX. Окружение запущенной С-функции – это всегда псевдо-индекс LUA_ENVIRONINDEX.

Для доступа и изменения значения глобальных переменных вы можете использовать обычную таблицу операций над таблицей окружения. Например, доступа к значению глобальной переменной:

     lua_getfield(L, LUA_GLOBALSINDEX, varname);

3.4 - C - включения

С С-функцией можно ассоциировать некоторые значения, это делается с помощью механизма С-включений. Такие значения называются внешними значениям и доступны в функции независимо от того, где она вызвана (смотрите lua_pushcclosure).

Откуда бы C-функция не вызывалась, эти внешние значения доступны через специальные псевдо-индексы. Их можно получить с помощью lua_upvalueindex. Первое ассоциированное с функцией значение доступно по индексу lua_upvalueindex(1), и так далее. В случае вызова lua_upvalueindex(n), где n больше количества внешних значения этой функции, вернется допустимый с точки зрения стека индекс (но он будет указывать неизвестно на что).

3.5 - Реестр

В Lua реализован реестр – предопределенная таблица, которую можно использовать в любом С-коде для хранения нужных значений Lua. Эта таблица всегда доступна по индексу LUA_REGISTRYINDEX. Любая C-библиотека может хранить данные в реестре, поэтому нужно следить за уникальностью собственных ключей для предотвращения коллизий. Обычно, для этого в имя ключа включают название своей библиотеки или небольшой блок данных, относящийся к вашему С-коду.

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

3.6 - Обработка ошибок в C

Внутренняя реализация Lua для обработки ошибок использует механизм сохранения и возврата контекста языка C (longjmp). (Также вы можете использовать исключения, если пишете на C++; смотрите файл luaconf.h.) Когда Lua обрабатывает ошибку (выделения памяти, несоответствия типов, синтаксическую или времени выполнения), выполняется вызов long jump. Защищенное окружение использует вызов setjmp для установки точек сохранения; любая ошибка ведет к передаче управления на ближайшую точку восстановления.

Почти в любая функция API может генерировать ошибочную ситуацию, например при ошибке выделения памяти. Следующие функции работают в защищенном режиме (они создают защищенное окружение для работы), поэтому ошибочных ситуаций не генерируют: lua_newstate, lua_close, lua_load, lua_pcall, и lua_cpcall.

В своей C-функции вы можете генерировать ошибку с помощью lua_error.

3.7 - Функции и типы

В этом разделе описаны все функции и типы из C API в алфавитном порядке. Каждая функция имеет индикатор подобно этому: [-o, +p, x]

Первое поле, o, - показывает сколько элементов функция выталкивает из стека. Второе поле, p, - показывает сколько элементов функция помещает в стек. (Любая функция всегда возвращает свои результаты после того когда данные были помещены в нее.) Поле x|y означает, что функция может поместить (или вытолкнуть) x или y элементы, в зависимости от ситуации; Знак вопроса '?' означает, что зная только параметры функции, мы не можем с точностью сказать сколько элементов функция выталкивает/помещает (например, это может зависеть от того, что находится в стеке). Третье поле, x, показывает может ли функция возбуждать ошибки: '-' означает, что функция никогда не возбуждает никаких ошибок; 'm' означает, что функция может возбудить ошибку только из-за недостаточного количества памяти; 'e' означает, что функция может возбудить другие виды ошибок; 'v' означает, что функция может возбудить ошибку специально.

lua_Alloc

typedef void * (*lua_Alloc) (void *ud,
                             void *ptr,
                             size_t osize,
                             size_t nsize);

Тип функции выделения памяти, используемый Lua. Функция выделения должна предоставлять функционал, схожий с realloc, но не точно такой же. Ее аргументы: ud, непрозрачный (opaque) указатель, передаваемый lua_newstate, ptr, указатель на блок block выделенной, перевыделенной или освобожденной памяти; osize, исходный размер блока; nsize, новый размер блока. ptr равен NULL тогда и только тогда когда osize нулевой. Когда nsize равен нулю, процедура выделения памяти (allocator) должна вернуть NULL; если osize не ноль, она должна освободить блок, на который указывает ptr. Когда nsize не ноль, процедура возвращает NULL тогда и только тогда она не может выполнить запрос. Если nsize не ноль и osize ноль, процедура должна вести себя как malloc. Если nsize и osize не ноль, процедура ведят себя как realloc. Луа предполагает, что такая процедура никогда не приводит к ошибочной ситуации при osize >= nsize.

Вот пример реализации простой функции выделения памяти. Он используется во вспомогательной библиотеке состоянием luaL_newstate.

     static void *l_alloc (void *ud, void *ptr, size_t osize,
                                                size_t nsize) {
       (void)ud;  (void)osize;  /* not used */
       if (nsize == 0) {
         free(ptr);
         return NULL;
       }
       else
         return realloc(ptr, nsize);
     }

Этот код предполагает что NULL не имеет эффекта и что realloc(NULL, size) эквивалентна malloc(size). ANSI C соответствует обоим поведениям.

lua_atpanic

[-0, +0, -]

lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);

Устанавливает новую panic function и возвращает старую.

Если происходит ошибка вне любого protected environment, Lua вызывает panic function, а затем exit(EXIT_FAILURE), таким образом выходя из приложения. Ваша panic function может предотвратить выход из программы, если не будет оканчиваться (e.g., при помощи long jump).

Panic function может осуществлять доступ к сообщению об ошибке на вершине стека.

lua_call

[-(nargs + 1), +nresults, e]

void lua_call (lua_State *L, int nargs, int nresults);

Вызывает функцию.

Для вызова функции вы должны использовать следующую последовательность: первое, функция, которая должны быть вызвана помещается на вершину стека; затем, аргументы функции помещаются (push) в прямом порядке; т.о., первый аргумент помещается первым. Затем вы вызываете lua_call; nargs это количество аргументов которые вы поместили в стек. Все аргументы и значение функции выбираются(pop) из стека когда вызывается функция. Результаты функции помещаются в стек по окончании вызова. Количество результатов соответствует nresults, если nresults не LUA_MULTRET. В противном случае, все результаты, возвращенные функцией помещаются в стек. Lua заботится о том чтобы возвращенные значения поместились в стек. Результаты функции помещаются в стек в прямом порядке (первый результат - первым), т.о. после вызова последний результат оказывается на вершине стека.

Любая ошибка внутри вызванной функции распространяется вверх (при помощи longjmp).

Эквивалентный код в Lua:

     a = f("how", t.x, 14)

То же в C:

     lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */
     lua_pushstring(L, "how");                        /* 1st argument */
     lua_getfield(L, LUA_GLOBALSINDEX, "t");   /* table to be indexed */
     lua_getfield(L, -1, "x");        /* push result of t.x (2nd arg) */
     lua_remove(L, -2);                  /* remove 't' from the stack */
     lua_pushinteger(L, 14);                          /* 3rd argument */
     lua_call(L, 3, 1);     /* call 'f' with 3 arguments and 1 result */
     lua_setfield(L, LUA_GLOBALSINDEX, "a");        /* set global 'a' */

Заметьте что код "сбалансирован": в его конце стек возвращается в исходную конфигурацию. Это считается хорошей практикой программирования.

lua_CFunction

typedef int (*lua_CFunction) (lua_State *L);

Тип для функций C.

Для правильной связи с Lua, функция C должна использовать следующую последовательность действий, которая определяет, как параметры передаются параметры и результаты: функция C получает аргументы из Lua через стек в прямом порядка (первый аргумент помещается в стек первым). Поэтому, когда функция начинает исполняться, lua_gettop(L) возвращает количество аргументов полученных функцией. Первый аргумент (если он существует) имеет индекс 1, а последний - lua_gettop(L). Для возвращения значений в Lua, функция C просто помещает их в стек, в прямом порядке, и возвращает количество результатов. Любое другое значение в стеке ниже результатов будет проигнорировано Lua. Также как и функция Lua, функция C, вызванная из Lua может также возвращать множество результатов

В качестве примера, следующая функция получает переменное число аргументов (числовых) и возвращает из среднее значение и сумму:

     static int foo (lua_State *L) {
       int n = lua_gettop(L);    /* number of arguments */
       lua_Number sum = 0;
       int i;
       for (i = 1; i <= n; i++) {
         if (!lua_isnumber(L, i)) {
           lua_pushstring(L, "incorrect argument");
           lua_error(L);
         }
         sum += lua_tonumber(L, i);
       }
       lua_pushnumber(L, sum/n);        /* first result */
       lua_pushnumber(L, sum);         /* second result */
       return 2;                   /* number of results */
     }

lua_checkstack

[-0, +0, -]

int lua_checkstack (lua_State *L, int extra);

Проверяет что существует, по крайней мере, extra свободных слотов стека. Функция возвращает false, если не может увеличить стек до требуемого размера. Эта функция никогда не уменьшает размер стека; если стек уже больше, чем требуемый новый размер, он остается неизменным

lua_close

[-0, +0, -]

void lua_close (lua_State *L);

Уничтожает все объекты в заданном состоянии Lua (Lua state) (вызывая соответствующие garbage-collection метаметоды, если таковые есть) и освобождает всю динамическую память, используемую этим состоянием (state). На некоторых платформах, вам может не понадобиться вызывать эту функцию, т.к. все ресурсы освобождаются автоматически, когда закрывается программа (host program). С другой стороны, долго работающие программы, такие как демоны или веб-сервера, могут потребовать освобождения состояний, как только они не нужны, для избежания слишком сильного разрастания.

lua_concat

[-n, +1, e]

void lua_concat (lua_State *L, int n);

Конкатенирует n значений на вершине стека, выталкивает(pop) их, и оставляет результат на вершине. Если n равен 1, результатом является единственная строка в стеке (т.о., функция ничего не делает); если n равен 0, результатом является пустая строка. Конкатенация производится в соответствии с обычной семантикой Lua (см. §2.5.4).

lua_cpcall

[-0, +(0|1), -]

int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);

Вызывает функцию C func в защищенном режиме (protected mode). func запускается с единственным значением в ее стеке, пользовательскими данными, содержащими ud. В случае ошибок, lua_cpcall возвращает аналогичные коды ошибок как lua_pcall, а также error object на вершине тека; в противном случае, она возвращает 0, и не изменяет стек. Все значения, возвращаемые func игнорируются.

lua_createtable

[-0, +1, m]

void lua_createtable (lua_State *L, int narr, int nrec);

Создает новую пустую таблицу, и вставляет (push) ее в стек. Под новую таблицу выделяется место для narr элементов массива и nrec элементов не массива (non-array elements). Это выделение удобно когда вы знаете точное количество элементов, которое будет помещено в таблицу. В противном случае, вы можете использовать функцию lua_newtable.

lua_dump

[-0, +0, m]

int lua_dump (lua_State *L, lua_Writer writer, void *data);

Выгружает функцию в бинарном формате (binary chunk). Получает функцию Lua с вершины стека и создает binary chunk, который, если будет загружен вновь, дает функцию, эквивалентную выгруженной. В процессе генерации частей chunk, lua_dump вызывает функцию writer (см. lua_Writer) с соответствующими данными для записи.

Возвращает значение, соответствующее коду ошибки (error code), возвращенному последним обращением к writer; 0 обозначает отсутствие ошибок.

Эта функция не выталкивает функцию Lua из стека.

lua_equal

[-0, +0, e]

int lua_equal (lua_State *L, int index1, int index2);

Возвращает 1 если два значения с индексами (acceptable indices) index1 и index2 эквивалентны, в соответствии с семантикой Lua оператора == (т.е., может вызывать метаметоды). В противном случае возвращает 0. Также возвращает 0 если любой из индексов ошибочен.

lua_error

[-1, +0, v]

int lua_error (lua_State *L);

Генерирует ошибку Lua. Сообщение об ошибке (которое может быть любым значением Lua любого типа) должно быть на вершине стека. Эта функция делает long jump, и т.о. никогда не заканчивается. (см. luaL_error).

lua_gc

[-0, +0, e]

int lua_gc (lua_State *L, int what, int data);

Контролирует сборщик мусора.

Эта функция выполняет несколько задач, в соответствии с значением параметра what:

  • LUA_GCSTOP: останавливает сборщик.
  • LUA_GCRESTART: перезапускает сборщик.
  • LUA_GCCOLLECT: производит полный цикл сборки мусора.
  • LUA_GCCOUNT: возвращает текущее значение объема памяти (в Kbytes), которое используется Lua.
  • LUA_GCCOUNTB: возвращает остаток деления текущего количества байт памяти, используемого Lua на 1024.
  • LUA_GCSTEP: выполняет инкрементальный шаг сбора мусора. Размер шага "size" контролируется значением data (большие значения означают большее количество шагов), но нет прямого соответствия между значением этого параметра и объемом освобождаемой памяти. Если вы хотите контролировать размер шага вам нужно экспериментально подобрать размер data. Эта функция возвращает 1 если шаг закончил цикл сборки мусора
  • LUA_GCSETPAUSE: выставляет data/100 новым значением для параметра pause сборщика мусора (см. §2.10). Функция возвращает предыдущее значение данного параметра
  • LUA_GCSETSTEPMUL: выставляет data/100 как новое значение step multiplier сборщика (см. §2.10). Функция возвращает предыдущее значение данного параметра

lua_getallocf

[-0, +0, -]

lua_Alloc lua_getallocf (lua_State *L, void **ud);

Возвращает функцию выделения памяти данного состояния (state). Если ud не равен NULL, Lua сохраняет в *ud непрозрачный (opaque) указатель передаваемый в lua_newstate.

lua_getfenv

[-0, +1, -]

void lua_getfenv (lua_State *L, int index);

Вставляет (Push) в стек таблицу окружения (environment table) значения заданного индекса.

lua_getfield

[-0, +1, e]

void lua_getfield (lua_State *L, int index, const char *k);

Вставляет (Push) в стек значение t[k], где t – это значение заданного валидного индекса index. Так же, как в Lua, эта функция может вызывать (trigger) метаметод для события индекса ("index" event) (см. §2.8).

lua_getglobal

[-0, +1, e]

void lua_getglobal (lua_State *L, const char *name);

Вставляет (Push) в стек значение глобальной переменной (value of the global name). Эта функция определяется как следующий макрос:

     #define lua_getglobal(L,s)  lua_getfield(L, LUA_GLOBALSINDEX, s)

lua_getmetatable

[-0, +(0|1), -]

int lua_getmetatable (lua_State *L, int index);

Вставляет в стек метатаблицу (metatable) значения в заданном валидном индексе (acceptable index). Если индекс не валиден, или значение не имеет метатаблицы, функция возвращает 0 и ничего не вставляет в стек.

lua_gettable

[-1, +1, e]

void lua_gettable (lua_State *L, int index);

Вставляет в стек значение t[k], где t – это значение в указанном валидном индексе index и k – это значение на вершине стека.

Эта функция выталкивает ключ из стека (вставляет результат на его место). Также как в Lua, эта функция может вызывать (trigger) метаметод для события индекса (см. §2.8).

lua_gettop

[-0, +0, -]

int lua_gettop (lua_State *L);

Возвращает индекс на значения, находящегося на вершине стека. Т.к. индексы начинаются с 1, это значение равно количеству элементов в стеке (и т.о. 0 обозначает пустой стек).

lua_insert

[-1, +1, -]

void lua_insert (lua_State *L, int index);

Перемещает верхний элемент в заданный валидный индекс, сдвигая вверх все элементы, находящиеся выше заданного индекса. Процедура не может быть вызвана с псевдо-индексом (pseudo-index), т.к. псевдо-индекс (pseudo-index) не содержит реального положения в стеке.

lua_Integer

typedef ptrdiff_t lua_Integer;

Данный тип используется Lua API для представления целых чисел.

По умолчанию ptrdiff_t, который соответствует наибольшему целому типу со знаком поддерживается "без проблем".

lua_isboolean

[-0, +0, -]

int lua_isboolean (lua_State *L, int index);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе имеет тип boolean, и 0 в противном случае.

lua_iscfunction

[-0, +0, -]

int lua_iscfunction (lua_State *L, int index);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе – функция C, и 0 в противном случае.

lua_isfunction

[-0, +0, -]

int lua_isfunction (lua_State *L, int index);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе – функция (C или Lua), и 0 в противном случае.

lua_islightuserdata

[-0, +0, -]

int lua_islightuserdata (lua_State *L, int index);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе – это пользовательские данные (light userdata), и 0 в противном случае.

lua_isnil

[-0, +0, -]

int lua_isnil (lua_State *L, int index);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе – 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 если значение в заданном допустимом (acceptable) индексе – число или строка, конвертируемая в число, и 0 в противном случае.

lua_isstring

[-0, +0, m]

int lua_isstring (lua_State *L, int index);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе – строка или число (которое всегда можно сконвертировать в строку), и 0 в противном случае.

lua_istable

[-0, +0, -]

int lua_istable (lua_State *L, int index);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе – таблица, и 0 в противном случае.

lua_isthread

[-0, +0, -]

int lua_isthread (lua_State *L, int index);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе – нить (поток, thread), и 0 в противном случае.

lua_isuserdata

[-0, +0, -]

int lua_isuserdata (lua_State *L, int index);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе – пользовательские данные (userdata) (full или light), и 0 в противном случае.

lua_lessthan

[-0, +0, e]

int lua_lessthan (lua_State *L, int index1, int index2);

Возвращает 1 если значение в заданном допустимом (acceptable) индексе index1 меньше чем значение в допустимом индексе index2, в соответствии с семантикой оператора < Lua (т.о., может вызывать метаметоды). В противном случае возвращает 0. Также возвращает 0 если любой из индексов не валиден.

lua_load

[-0, +1, -]

int lua_load (lua_State *L,
              lua_Reader reader,
              void *data,
              const char *chunkname);

Загружает chunk Lua. Если нет ошибок, lua_load вставляет (push) скомпилированный chunk как Lua функцию на вершину стека. В противном случае, функция вставляет сообщение об ошибке. Возвращаемые значения lua_load:

  • 0: нет ошибок;
  • LUA_ERRSYNTAX: ошибка синтаксиса;
  • LUA_ERRMEM: ошибка выделения памяти.

Эта функция только загружает chunk; но не запускает.

lua_load автоматически определяет, является ли chunk текстовым или бинарным, и соответствующе его загружает (см. программу luac).

Функция lua_load использует предоставленную пользователем функцию reader для чтения chunk (см. lua_Reader). Аргумент data – непрозрачное (opaque) значение, передаваемое в функцию reader.

Аргумент chunkname дает имя chunk, которое может быть использовано для обработки сообщений об ошибках и получения отладочной информации (см. §3.8).

lua_newstate

[-0, +0, -]

lua_State *lua_newstate (lua_Alloc f, void *ud);

Создает новое независимое состояние (state). Возвращает NULL, если не удается создать состояние (из-за недостатка памяти). Аргумент f – функция выделения памяти; Lua совершает все выделения памяти для этого состояния через эту функцию. Второй аргумент, ud – это непрозрачный указатель (opaque pointer), который 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);

Создает новую нить (thread), вставляет ее в стек, и возвращает указатель на lua_State, который представляет (represents) эту новую нить. Новое состояние (state), возвращенное функцией разделяет с исходным (original) состоянием все глобальные объекты (такие как tables), но обладает независимым стеком выполнения.

Не существует непосредственно функции, закрывающей или уничтожающей нить. Нити – это забота сборщика мусора, как и любой другой объект Lua.

lua_newuserdata

[-0, +1, m]

void *lua_newuserdata (lua_State *L, size_t size);

Эта функция выделяет новый блок памяти с заданного размера, вставляет в стек новую пользовательскую полную информацию (full userdata) с адресом блока, и возвращает этот адрес.

Пользовательская информация (userdata) представляет значения C в Lua. Полная пользовательская информация (full userdata) представляет блок памяти. Это - объект (такой же как таблица): вы должны создать его, он может обладать собственной метатаблицей, и вы можете определить, когда она будет собрана (collected). Полная пользовательская информация (full userdata) равна только самой себе (в соответствии с «сырым» сравнением (under raw equality)).

Когда Lua собирает полную пользовательскую информацию (full userdata) с использованием метаметода gc, Lua вызывает метаметод и помечает пользовательскую информацию как finalized. Когда эта пользовательская информация собирается снова, то Lua освобождает соответствующую память.

lua_next

[-1, +(2|0), e]

int lua_next (lua_State *L, int index);

Выталкивает (Pop) ключ из стека, и вставляет пару ключ-значение из таблицы по заданному индексу ("следующую" пару после заданного ключа). Если больше не существует элементов в таблицы, то lua_next возвращает 0 (и ничего не вставляет в стек).

Типичный обход (traversal) выглядит следующим образом:

     /* 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 непосредственно для ключа, если не уверенны точно, что ключ действительно является строкой. Повторный вызов (Recall) lua_tolstring изменяет значение по заданному индесу; это «сбивает с толку» (confuses) следующий вызов lua_next.

lua_Number

typedef double lua_Number;

Тип чисел в Lua. По умолчанию – double, но это можно изменить в luaconf.h.

В конфигурационном файле вы можете изменить настройки Lua так, чтобы оперировать другими типами чисел (напр., float или long).

lua_objlen

[-0, +0, -]

size_t lua_objlen (lua_State *L, int index);

Возвращает длину данных, расположенных по заданному допустимому индексу:
для строк, возвращает длину строки;
для таблиц – результат выполнения оператора длины ('#');
для пользовательских данных – размер блока данных, выделенных для пользовательских данных;
для других типов – 0.

lua_pcall

[-(nargs + 1), +(nresults|1), -]

int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);

Вызывает функцию в защищенном режиме.

Параметры nargs и nresults имеют значение, аналогичное lua_call. Во время вызова не произошло ошибок, lua_pcall ведет себя в точности как lua_call. Однако, если встретились ошибки, lua_pcall перехватывает их, вставляет в стек сообщение об ошибке, и возвращает код ошибки. Также как и lua_call, lua_pcall всегда удаляет функцию и ее аргументы из стека.

Если errfunc равен 0, то сообщение об ошибке, возвращенное через стек – это исходное (original) сообщение об ошибке. В противном случае, errfunc – это индекс стека функции-обработчика ошибок. (В текущей реализации, этот индекс не может быть псевдо-индексом.) В случае ошибок времени выполнения, эта функция будет вызвана с сообщением об ошибке и возвращенное ею значение и будет сообщением, возвращенным через стек lua_pcall.

Чаще всего, функция обработки ошибок (error handler function) используется для добавления дополнительной отладочной информации в сообщение об ошибке, такой как stack traceback. Такая информация не может быть собрана после возврата из lua_pcall, т.к. в этот момент стек был уже изменен (unwound).

Функция lua_pcall возвращает 0 в случае успешного завершения или один из следующих кодов ошибок (определенных в lua.h):

  • LUA_ERRRUN: ошибка времени выполнения.
  • LUA_ERRMEM: ошибка выделения памяти. Для таких ошибок, Lua не вызвает функию-обработчик ошибок.
  • LUA_ERRERR: ошибка во время выполнения функции-обработчика ошибок.

lua_pop

[-n, +0, -]

void lua_pop (lua_State *L, int n);

Выталкивает n элементов из стека.

lua_pushboolean

[-0, +1, -]

void lua_pushboolean (lua_State *L, int b);

Вставляет булеву переменную со значением b в стек.

lua_pushcclosure

[-n, +1, m]

void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);

Вставляет новый экземпляр функции C в стек.

Когда функция C создана, есть возможность ассоциировать с ней некоторые значения, т.о. создавая экземпляр функции C (C closure) (см. §3.4); эти значения затем доступны функции во время ее вызова. Для того чтобы ассоциировать значения с функцией C, сначала эти значения должны быть вставлены в стек (если есть несколько значений, первое вставляется первым). Затем lua_pushcclosure вызовется для того, чтобы создать и вставить функцию C в стек, с аргументом n, соответствующем количеству ассоциируемых значений. lua_pushcclosure также выталкивает эти значения из стека.

lua_pushcfunction

[-0, +1, m]

void lua_pushcfunction (lua_State *L, lua_CFunction f);

Вставляет функцию C в стек. Эта функция получает указатель на функцию C и вставляет в стек значение Lua типа function, которое, будучи вызванным, передает управление функции C.

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

lua_pushcfunction определена следующим макросом:

     #define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)

lua_pushfstring

[-0, +1, m]

const char *lua_pushfstring (lua_State *L, const char *fmt, ...);

Вставляет в стек отформатированную строку и возвращает указатель на эту строку. Эта функция аналогична функции C sprintf, но обладает некоторыми важными отличиями:

  • Вам не нужно выделять память для результата: результат – строка Lua и Lua позаботится о выделении памяти (и освобождении, в процессе сборки мусора).
  • Символы замены довольно ограничены. Не существует флагов, длин, или точностей. Символы замены могут быть только '%%' (вставляет '%' в строку), '%s' (вставляет строку, оканчивающуюся 0, без ограничений на длину), '%f' (вставляет lua_Number), '%p' (вставляет указатель в шестнадцатеричном формате), '%d' (вставляет целое число), и '%c' (вставляет целое число как символ).

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);

Вставляет light пользовательские данные в стек.

Пользовательские данные представляют значения C в Lua. Light пользовательские данные представляют собой указатель. Это – значение (как число): вы не создаете его, оно не имеет метатаблицы, и оно никогда не собирается сборщиком мусора (т.к.никогда не было создано). Light пользовательские данные эквивалентны любым light пользовательским данным с таким же адресом C.

lua_pushlstring

[-0, +1, m]

void lua_pushlstring (lua_State *L, const char *s, size_t len);

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

lua_pushnil

[-0, +1, -]

void lua_pushnil (lua_State *L);

Вставляет значение nil в стек.

lua_pushnumber

[-0, +1, -]

void lua_pushnumber (lua_State *L, lua_Number n);

Вставляет число со значением n в стек.

lua_pushstring

[-0, +1, m]

void lua_pushstring (lua_State *L, const char *s);

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

lua_pushthread

[-0, +1, -]

int lua_pushthread (lua_State *L);

Вставляет нить L в стек. Возвращает 1 если данная нить – основная в данном состоянии.

lua_pushvalue

[-0, +1, -]

void lua_pushvalue (lua_State *L, int index);

Вставляет копию элемента в стек по заданному валидному индексу.

lua_pushvfstring

[-0, +1, m]

const char *lua_pushvfstring (lua_State *L,
                              const char *fmt,
                              va_list argp);

Эквивалентна lua_pushfstring, за исключением того, что получает va_list вместо переменного количества аргументов.

lua_rawequal

[-0, +0, -]

int lua_rawequal (lua_State *L, int index1, int index2);

Возвращает 1 если два значения по допустимым индексам index1 и index2 базово равны (т.е., без вызова метаметодов). В противном случае возвращает 0. Также возвращает 0 если любой из индексов не является валидным.

lua_rawget

[-1, +1, -]

void lua_rawget (lua_State *L, int index);

Аналогична lua_gettable, но совершает «сырой» доступ (т.е., без метаметодов).

lua_rawgeti

[-0, +1, -]

void lua_rawgeti (lua_State *L, int index, int n);

Вставляет в стек значение t[n], где t – это значение в заданном валидном индексе index. Доступ «сырой», т.е. метаметоды не вызыаются.

lua_rawset

[-2, +0, m]

void lua_rawset (lua_State *L, int index);

Аналогична lua_settable, но совершает «сырое» присваивание (т.е., без метаметодов).

lua_rawseti

[-1, +0, m]

void lua_rawseti (lua_State *L, int index, int n);

Выполняет действия, аналогичные t[n] = v, где t – это значение по валидному индексу index, а v – значение на вершине стека.

Эта функция выталкивает значение из стека. Присваивание – «сырое»; т.е., не вызывает метаметодов.

lua_Reader

typedef const char * (*lua_Reader) (lua_State *L,
                                    void *data,
                                    size_t *size);

Функция чтения, используемая lua_load. Каждый раз, когда требуется новая часть chunk, lua_load вызывает функцию чтения, передавая параметр data. Функция чтения должна возвращать указатель на блок памяти с новой частью chunk и выставлять size в значение размера блока. Блок должен существовать до тех пор пока функция не будет вызвана еще раз. Для того, чтобы сигнализировать об окончании chunk, функция чтения должна возвращать NULL. Функция чтения может возвращать части любого размера, большего ноля.

lua_register

[-0, +0, m]

void lua_register (lua_State *L,
                   const char *name,
                   lua_CFunction f);

Выставляет функцию C f новым значением global name. Функция определена как макрос:

     #define lua_register(L,n,f) \
            (lua_pushcfunction(L, f), lua_setglobal(L, n))

lua_remove

[-1, +0, -]

void lua_remove (lua_State *L, int index);

Удаляет элемент по данному валидному индексу, сдвигая вниз элементы над этим индексом. Не может быть вызвана с псевдо-индексом, т.к. псевдо-индекс не является реальной позицией в стеке.

lua_replace

[-1, +0, -]

void lua_replace (lua_State *L, int index);

Копирует верхний элемент в соответствующую позицию (и выталкивает верхний элемент), без сдвига элементов (т.о. замещая значение в соответствующей позиции).

lua_resume

[-?, +?, -]

int lua_resume (lua_State *L, int narg);

Запускает и восстанавливает сопрограмму в данной нити.

Для запуска сопрограммы, вы сначала должны создать новую нить (см. lua_newthread); затем вы вставляете в ее стек главную функцию плюс любые аргументы; затем вы вызываете lua_resume, с narg равным количеству аргументов. Эта функция закончит работу тогда, когда сопрограмма остановится (suspend) или закончит свое исполнение. Когда она остановится, стек будет содержать все значения, переданные lua_yield, или все значения, возвращенный функцией. lua_resume возвращает LUA_YIELD если сопрограмма уступает ресурсы, 0 если сопрограмма заканчивает свое выполнение без ошибок, или код ошибки в случае ошибочной ситуации (см. lua_pcall). В случае ошибок, стек не очищается (unwound), т.о. вы можете использовать API отладки для его анализа. Сообщение об ошибке находится на вершине стека. Для перезапуска сопрограммы, вы передаете в ее стек только значения, которые должны быть переданы как результаты yield, и затем вызываете lua_resume.

lua_setallocf

[-0, +0, -]

void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);

Изменяет функцию распределения (allocator function) данного состояния на f с пользовательскими данными ud.

lua_setfenv

[-1, +0, -]

int lua_setfenv (lua_State *L, int index);

Выталкивает таблицу из стека из стека и выставляет ей новое окружение для значения по заданному индексу. Если значение по данному индексу не является функцией, нитью или пользовательскими данными, lua_setfenv возвращает 0. Иначе, она возвращает 1.

lua_setfield

[-1, +0, e]

void lua_setfield (lua_State *L, int index, const char *k);

Выполняет действие, аналогичное t[k] = v, где t – значение по заданному валидному индексу index и v – значение на вершине стека.

Эта функция выталкивает значение из стека. Также как в Lua, эта функция сожжет вызывать метаметод для события "новый индекс" (см. §2.8).

lua_setglobal

[-1, +0, e]

void lua_setglobal (lua_State *L, const char *name);

Выталкивает значение из стека и приравнивает его глобальной переменной (global) name. Определена как макрос:

     #define lua_setglobal(L,s)   lua_setfield(L, LUA_GLOBALSINDEX, s)

lua_setmetatable

[-1, +0, -]

int lua_setmetatable (lua_State *L, int index);

Выталкивает таблицу из стека и приравнивает ее метатаблице значения по заданному допустимому индексу.

lua_settable

[-2, +0, e]

void lua_settable (lua_State *L, int index);

Выполняет аналогичные t[k] = v действия, где t – это значение по заданному валидному индексу index, v – это значение на вершин стека, и k – это значение, находящееся на одно ниже вершины стека.

Эта функция выталкивает ключ и значение из стека. Также как в Lua, эта функция может вызывать метаметод для события "новый индекс" (см. §2.8).

lua_settop

[-?, +?, -]

void lua_settop (lua_State *L, int index);

Принимает любой допустимый индекс, или 0, и ставит вершину стека в этот индекс. Если новая вершина выше, чем старая, то новые элементы заполняются nil. Если index равен 0, то все значения стека очищаются.

lua_State

typedef struct lua_State lua_State;

Непроницаемая (Opaque) структура, которая содержит полное состояние интерпретатора Lua. Библиотека Lua полностью реентерабельна: она не содержит глобальных переменных. Вся информация о состоянии содержится в этой структуре.

Указатель на это состояние должен передаваться как первый аргумент любой функции в библиотеке, кроме lua_newstate, которая создает новое состояние Lua.

lua_status

[-0, +0, -]

int lua_status (lua_State *L);

Возвращает состояние нити L.

Состояние может быть 0 для обычной нити, кодом ошибки, если нить завершила выполнение с ошибкой, или LUA_YIELD если нить остановлена.

lua_toboolean

[-0, +0, -]

int lua_toboolean (lua_State *L, int index);

Конвертирует значение Lua по указанному допустимому индексу в булево значение C (0 или 1). Как и все тесты в Lua, lua_toboolean возвращает 1 для любого значения Lua отличного от false и nil; в противном случае возвращает 0. Также возвращает 0 когда вызывается с не валидным индексом. (Если вы хотите получать только настоящие булевы значения, используйте lua_isboolean для проверки типа.)

lua_tocfunction

[-0, +0, -]

lua_CFunction lua_tocfunction (lua_State *L, int index);

Конвертирует значение по заданному допустимому индексу в функцию C. Значение должно быть функцией C; иначе, она возвращает NULL.

lua_tointeger

[-0, +0, -]

lua_Integer lua_tointeger (lua_State *L, int index);

Конвертирует значение Lua по заданному допустимому индексу в целый тип со знаком lua_Integer. Значение Lua должно быть числом или строкой, конвертируемой в число (см. §2.2.1); в противном случае, lua_tointeger возвращает 0.

Если число не целое, оно обрубается каким-то неопределенным способом (it is truncated in some non-specified way).

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 возвращает fully aligned pointer на строку в состоянии Lua. Эта строка всегда имеет ноль ('\0') после последнего символа (как в C), но может содержать также другие нули. Т.к. Lua обладает сборщиком мусора, нет гарантии что указатель, возвращенный lua_tolstring будет валиден после удаления соответствующего значения из стека.

lua_tonumber

[-0, +0, -]

lua_Number lua_tonumber (lua_State *L, int index);

Конвертирует значение Lua по данному допустимому индексу в тип C lua_Number (см. lua_Number). Значение Lua должно быть числом или строкой, конвертируемой в число (см. §2.2.1); иначе, lua_tonumber возвращает 0.

lua_topointer

[-0, +0, -]

const void *lua_topointer (lua_State *L, int index);

Конвертирует значение по заданному допустимому индексу в безтиповой указатель C (void*). Значение может быть различных типов: пользовательские данные, таблица, нить, или функция; в противном случае, lua_topointer возвращает NULL. Различные объекты дадут различные указатели. Не существует способа сконвертировать указатель назад, в исходное значение.

Обычно эту функцию используют для получения отладочной информации.

lua_tostring

[-0, +0, m]

const char *lua_tostring (lua_State *L, int index);

Эквивалентна lua_tolstring с длиной len равной NULL.

lua_tothread

[-0, +0, -]

lua_State *lua_tothread (lua_State *L, int index);

Конвертирует значение в указанном допустимом индексе в нить Lua (представленную как lua_State*). Это значение должно быть нитью; иначе, функция возвращает NULL.

lua_touserdata

[-0, +0, -]

void *lua_touserdata (lua_State *L, int index);

Если значение по указанному допустимому индексу – это full пользовательские данные, возвращает их адрес блока. Если значение – это light пользовательские данные, возвращает их указатель. В противном случае, возвращает NULL.

lua_type

[-0, +0, -]

int lua_type (lua_State *L, int index);

Возвращает тип значения по указанному допустимому индексу, или LUA_TNONE для не валидного индекса (т.е., для индекса "пустой" ячейки стека). Типы, возвращаемые lua_type, закодированы следующими константами, определенными в lua.h: LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, и LUA_TLIGHTUSERDATA.

lua_typename

[-0, +0, -]

const char *lua_typename  (lua_State *L, int tp);

Возвращает имя типа, закодированного значением tp, которое должно быть одним из значений, возвращаемых lua_type.

lua_Writer

typedef int (*lua_Writer) (lua_State *L,
                           const void* p,
                           size_t sz,
                           void* ud);

Функция записи, используемая lua_dump. Каждый раз, когда она создает новую часть chunk, lua_dump вызывает функцию записи, передавая буфер для записи (p), его размер (sz), параметр data, передаваемый lua_dump.

Функция записи возвращает код ошибки: 0 обозначает, что ошибок не произошло; любое другое значение обозначает ошибку и останавливает lua_dump, предотвращая вызов функции записи снова.

lua_xmove

[-?, +?, -]

void lua_xmove (lua_State *from, lua_State *to, int n);

Меняет местами значения между различными потоками одного глобального состояния.

Эта функция выталкивает n значений из стека from, и вставляет их в стек to.

lua_yield

[-?, +?, -]

int lua_yield  (lua_State *L, int nresults);

Останавливает сопрограмму.

Эта функция должна быть использована только при передаче возвращаемого значения функции C, напр.:

     return lua_yield (L, nresults);

Когда функция C вызывает lua_yield таким образом, работающая сопрограмма останавливает свое выполнение, а вызов lua_resume, который заустил эту сопрограмму завершается. Параметр nresults – это число значений из стека, которые передаются как результаты в lua_resume.

3.8 - Интерфейсы отладки

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

lua_Debug

typedef struct lua_Debug {
  int event;
  const char *name;           /* (n) */
  const char *namewhat;       /* (n) */
  const char *what;           /* (S) */
  const char *source;         /* (S) */
  int currentline;            /* (l) */
  int nups;                   /* (u) number of upvalues */
  int linedefined;            /* (S) */
  int lastlinedefined;        /* (S) */
  char short_src[LUA_IDSIZE]; /* (S) */
  /* private part */
  other fields
} lua_Debug;

Эта структура используется для предоставления информации об активной функции. lua_getstack используется для заполнения только private-части этой структуры. Для того, чтобы заполнить остальные поля lua_Debug используйте lua_getinfo.

Поля структуры lua_Debug имеют следующее значение:

  • source: Если функция была определена в строке, то source будет содержать эту строку. Если же функция была определена в файле, тогда source начинается с символа '@' за которым следует имя файла.
  • short_src: «пригодная для печати» версия source, используемая в сообщениях об ошибках.
  • linedefined: номер строки, в которой начинается описание функции.
  • lastlinedefined: номер строки, в которой заканчивается описание функции.
  • what: Строка "Lua", если функция является функцией LUA, строка "C" если «Си-шная», "main" если это основная часть chunk и "tail" если это функция, которая совершает завершающий вызов (if it was a function that did a tail call). В последнем случае, Lua не имеет более никакой информации об этой функции.
  • currentline: Текущая строка, где данная функция выполняется. Когда информация о текущей строке недоступна, currentline устанавливается равной -1.
  • name: Подходящее имя (a reasonable) для данной функции name. Поскольку функции в Lua являются first-class объектами, они не имеют фиксированного имени: одни функции могут быть значениями множества глобальный переменных, в то время как другие могут храниться только в полях таблицы. Функция lua_getinfo проверяет как функция была вызвана для того, чтобы найти подходящее имя. Если имя найти не удалось, то значение поля name устанавливается в NULL.
  • namewhat: Объясняет поле name. Может принимать значения "global", "local", "method", "field", "upvalue", или "" (пустая строка), в соответствии с тем, как функция была вызвана. (Lua использует пустую строку, когда никакие другие значения не подходят).
  • nups: число внешних локальных переменных функции.

lua_gethook

[-0, +0, -]

lua_Hook lua_gethook (lua_State *L);

Возвращает текущую hook-функцию.

lua_gethookcount

[-0, +0, -]

int lua_gethookcount (lua_State *L);

Возвращает текущее количество инструкций, после которых происходит вызов hook-функций.

lua_gethookmask

[-0, +0, -]

int lua_gethookmask (lua_State *L);

Возвращает текущую маску hook’а.

lua_getinfo

[-(0|1), +(0|1|2), -]

int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);

Возвращает информацию об определенной функции или вызовах функции.

Для получения информации о вызовах функции параметр ar должен быть активирующей записью, которая была заполнена предыдущим вызовом lua_getstack или передана в качестве аргумента hook’у (см. lua_Hook).

Для того, чтобы получить информацию о функции, вы должны ее поместить в стек и в начало строки what добавить символ '>'. (В этом случае, lua_getinfo помещает функцию на вершину стека). Например, для того чтобы узнать, на какой строке определена функция f, можно использовать следующий код:

     lua_Debug ar;
     lua_getfield(L, LUA_GLOBALSINDEX, "f");  /* get global 'f' */
     lua_getinfo(L, ">S", &ar);
     printf("%d\n", ar.linedefined);

Каждый символ строки what определяет, какие поля структуры ar должны быть заполнены, или какое значение должно быть помещено в стек:

  • 'n': заполнять поля name и namewhat;
  • 'S': заполнять поля source, short_src, linedefined, lastlinedefined, и what;
  • 'l': заполнить поле currentline;
  • 'u': заполнить поле nups;
  • 'f': поместить в стек функцию, которая выполняется на заданном уровне;
  • 'L': поместить в стек таблицу, индексы которой являются номерами функциональных строк функции. (Функциональная строка – это такая строка, которая содержит некоторый код, и на которой можно поставить точку останова. Не функциональными строками являются пустые строчки и комментарии.

Функция возвращает 0 при ошибке. (Например, при неправильной опции в строке what).

lua_getlocal

[-0, +(0|1), -]

const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);

Получает информацию о локальной переменной данной структуры активации. Параметр ar должен быть структурой активации, которая была заполнена предыдущим вызовом lua_getstack или передана в качестве аргумента hook’у (см. lua_Hook). Параметр n определяет какую локальную переменную необходимо рассматривать. (1 означает первый параметр или активную локальную переменную и так далее до последней активной локальной переменной). lua_getlocal помещает значение переменной в стек и возвращает ее имя.

Переменные, имена которых начинаются с '(' (открывающаяся круглая скобка) представляют собой внутренние переменные (счетчики циклов, временные переменные, и локальные переменные функций на C).

Возвращает NULL (и ничего не помещает в стек) когда значение индекса больше чем количество активных локальных переменных.

lua_getstack

[-0, +0, -]

int lua_getstack (lua_State *L, int level, lua_Debug *ar);

Получает информацию о стеке времени выполнения.

Функция заполняет часть структуры lua_Debug с идентификацией структуры активации функции, выполняемой на заданном уровне. Уровень 0 – это выполняемая в данный момент функция, тогда как уровень n+1 это функция, которая была вызвана с уровня n. Когда не было обнаружено ошибок, lua_getstack возвращает 1; когда значение уровня больше чем высота стека – будет возвращен 0.

lua_getupvalue

[-0, +(0|1), -]

const char *lua_getupvalue (lua_State *L, int funcindex, int n);

Получает информацию о внешней локальной переменной (upvalue) экземпляра (closure) функции. (Функции Lua используют такие переменные и, следовательно, включают их в экземпляр). Функция lua_getupvalue получает индекс n внешней локальной переменной, извлекает ее значение в стек и возвращает ее имя. Значение funcindex указывает на положение экземпляра в стеке. (Внешние локальные переменные не имеют своего порядка, так как они активны в течение всего времени выполнения функции. Поэтому, они имеют случайный порядок.)

Возвращает NULL (и ничего не помещает в стек) когда индекс больше чем число внешних локальных переменных. Для функций, написанных на C, используется пустая строка "" в качестве имени всех внешних локальных переменных

lua_Hook

typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);

Тип данных для отладки hook-функций.

Каждый раз, когда вызывается hook, у аргумента ar поле event принимает значение события, которое инициировало запуск. Lua определяет эти события при помощи следующих констант: LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKTAILRET, LUA_HOOKLINE, и LUA_HOOKCOUNT. Кроме того, если произошло событие LUA_HOOKLINE, заполняется еще и поле currentline. Для получения значение любого другого поля в структуре ar, hook должен вызвать lua_getinfo. Для возвращения событий, event может быть LUA_HOOKRET, обычное значение или LUA_HOOKTAILRET. В последнем случае, Lua имитирует возвращение из функции, которая совершает завершающий вызов, при этом вызывать функцию lua_getinfo бесполезно.

Пока Lua выполняет hook, другие обращения к нему блокируются. Поэтому, если hook обращается обратно к Lua для выполнения функции или chunk, это выполнение произойдет без каких-либо обращений к hook-ам.

lua_sethook

[-0, +0, -]

int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);

Устанавливает отладочную hook функцию.

Аргумент f – это hook-функция. Параметр mask определяет, при каких события эта функция будет вызвана: Он формируется из констант LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE, и LUA_MASKCOUNT побитовым «или». Аргумент count имеет смысл только если маска содержит константу LUA_MASKCOUNT. Для каждого другого события, hook вызывается согласно тому, как это объяснено ниже:

  • Hook вызова: выполняется, когда интерпретатор вызывает функцию сразу после того как Lua входит в новую функцию, но перед тем, как функция получит свои аргументы.
  • Hook возвращения: выполняется когда интерпретатор выходит из функции. Hook вызывается сразу после того, как Lua покидает функцию, при этом нет никакого доступа к значение, которые функция возвратила.
  • Hook строки: выполняется, когда интерпретатор собирается начать выполнение новой строки кода или когда переходит назад в коде (даже на ту же строчку). (Это событие происходит только, когда Lua выполняет функции Lua)
  • Hook подсчета: выполняется после того, как интерпретатор выполнит каждую count–ую инструкцию. (Это событие происходит только, когда Lua выполняет функции Lua)

Для того, чтобы запретить hook, необходимо установить mask в ноль.

lua_setlocal

[-(0|1), +0, -]

const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);

Устанавливает значение локальной переменной данной активационной структуры. Параметры ar и n are такие же как и в lua_getlocal (см. lua_getlocal). lua_setlocal назначает значение, находящееся на вершине стека переменной и возвращает ее имя, при этом значение из стека извлекается.

Возвращает NULL (и ничего не выталкивает из стека) когда индекс больше чем количество активных локальных переменных.

lua_setupvalue

[-(0|1), +0, -]

const char *lua_setupvalue (lua_State *L, int funcindex, int n);

Устанавливает значение внешней локальной переменной экземпляра функции. Назначает значение, находящееся на вершине стека внешней локальной переменной и возвращает ее имя. Назначенное значение из стека выталкивается. Параметры funcindex и n are такие же как и в lua_getupvalue (см. lua_getupvalue).

Возвращает NULL (и ничего из стека не выталкивает) когда значение индекса больше чем количество внешних локальных переменных.

4 - Вспомогательная библиотека

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

Все функции этой библиотеки определены в заголовочном файле lauxlib.h и имеют префикс luaL_.

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

Некоторые функции также иногда используются для проверки аргументов функций на C. Их имена всегда начинаются на luaL_check* или luaL_opt*. Все эти функции возбуждают ошибку, если проверка не удовлетворительна. Поскольку сообщение об ошибке форматировано для аргументов (например, "bad argument #1"), вы не должны использовать эти функции для других значений стека.

4.1 - Функции и типы

В этой главе мы опишем все функции и типы из вспомогательной библиотеки в алфавитном порядке.

luaL_addchar

[-0, +0, m]

void luaL_addchar (luaL_Buffer *B, char c);

Добавляет символ c в буфер B (см. luaL_Buffer).

luaL_addlstring

[-0, +0, m]

void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);

Добавляет строку, на которую ссылается указатель s, длиной l в буфер B (см. luaL_Buffer). Строка может содержать нулевые символы.

luaL_addsize

[-0, +0, m]

void luaL_addsize (luaL_Buffer *B, size_t n);

Добавляет в буфер B (см. luaL_Buffer) строку длиной n, первоначально скопированную в область буфера (см. luaL_prepbuffer).

luaL_addstring

[-0, +0, m]

void luaL_addstring (luaL_Buffer *B, const char *s);

Добавляет строку с нулевым символом в конце, на которую указывает указатель s в буфер B (см. luaL_Buffer). Строка не может содержать нулевых символов кроме последнего.

luaL_addvalue

[-1, +0, m]

void luaL_addvalue (luaL_Buffer *B);

Добавляет значение из вершины стека в буфер B (см. luaL_Buffer). При этом, из стека это значение извлекается.

Это единственная функция, которая должна быть вызвана с дополнительным значением, размещенным в стеке, которое затем и помещается в буфер.

luaL_argcheck

[-0, +0, v]

void luaL_argcheck (lua_State *L,
                    int cond,
                    int narg,
                    const char *extramsg);

Проверяет на истинность условие cond. Если значение ложно, вызывает ошибку следующего содержания (где func определяется из стека вызова):

     bad argument #<narg> to <func> (<extramsg>)

luaL_argerror

[-0, +0, v]

int luaL_argerror (lua_State *L, int narg, const char *extramsg);

вызывает ошибку следующего содержания (где func определяется из стека вызова):

     bad argument #<narg> to <func> (<extramsg>)

Эта функция ничего не возвращает, но для поддержки идиомы C ее можно использовать как return luaL_argerror(args).

luaL_Buffer

typedef struct luaL_Buffer luaL_Buffer;

Тип данных для буфера строк.

Буфер строк позволяет коду на C постепенно строить строки Lua. Использовать его можно по следующей схеме:

  • Сначала вы объявляете переменную b типа luaL_Buffer.
  • Затем вы инициализируете ее при помощи luaL_buffinit(L, &b).
  • После этот добавляйте фрагменты строк, вызывая любую функцию из семейства luaL_add*.
  • Для окончания, вызывайте luaL_pushresult(&b). Этот вызов оставляет результирующую строку на вершине стека.

Во время обычной операции, буфер строк использует переменное количество слотов стека. Поэтому, используя буфер, вы не можете предполагать, что вы знаете, где находится вершина стека. Вы можете использовать стек между успешными вызовами к операциями над буфером до тех пор, пока его использование сбалансировано; т.е. когда вы вызываете операцию над буфером, стек находится на том же уровне, что и был после предыдущей операцией над буфером. (Единственное исключение из этого правила – это luaL_addvalue.) После вызова luaL_pushresult стек возвращается обратно на тот уровен, на котором он был, когда буфер был инициализирован, но на вершине у него будет храниться результирующая строка.

luaL_buffinit

[-0, +0, -]

void luaL_buffinit (lua_State *L, luaL_Buffer *B);

Инициализирует буфер B. Эта функция не выделяет место в памяти; буфер должен быть объявлен как переменная (см. luaL_Buffer).

luaL_callmeta

[-0, +(0|1), e]

int luaL_callmeta (lua_State *L, int obj, const char *e);

Вызывает метаметод.

Если объект под индексом obj имеет метатаблицу и она имеет поле e, эта функция вызывает это поле и передает ему объект как единственный аргумент. В этом случае функция возвращает 1 и записывает в стек значение, возвращаемое таким вызовом. Если объект не имеет ни метатаблицы ни метаметода, функция возвращает 0 (и ничего не записывает в стек).

luaL_checkany

[-0, +0, v]

void luaL_checkany (lua_State *L, int narg);

Проверяет, имеет ли функция аргумент любого типа (включая nil) на позиции narg.

luaL_checkint

[-0, +0, v]

int luaL_checkint (lua_State *L, int narg);

Проверяет, является ли narg-ый аргумент функции числом и возвращает это число, приведенное к типу int.

luaL_checkinteger

[-0, +0, v]

lua_Integer luaL_checkinteger (lua_State *L, int narg);

Проверяет, является ли narg-ый аргумент функции числом и возвращает это число, приведенное к типу lua_Integer.

luaL_checklong

[-0, +0, v]

long luaL_checklong (lua_State *L, int narg);

Проверяет, является ли narg-ый аргумент функции числом и возвращает это число, приведенное к типу long.

luaL_checklstring

[-0, +0, v]

const char *luaL_checklstring (lua_State *L, int narg, size_t *l);

Проверяет, является ли narg-ый аргумент функции строки и возвращает эту строку; если l не NULL, заполняет *l значением, равным длине строки.

luaL_checknumber

[-0, +0, v]

lua_Number luaL_checknumber (lua_State *L, int narg);

Проверяет, является ли narg-ый аргумент функции числом и возвращает это число.

luaL_checkoption

[-0, +0, v]

int luaL_checkoption (lua_State *L,
                      int narg,
                      const char *def,
                      const char *const lst[]);

Проверяет, является ли narg-ый аргумент функции строкой и ищет эту строку в массиве lst (который должен оканчиваться на NULL). Возвращает индекс элемента массива, в котором была найдена строка. Порождает ошибку, если аргумент строкой не является, или она не была найдена в массиве.

Если def не NULL, функция использует def как значение по умолчанию, когда не существует narg-ого аргумента или если этот аргумент является nil.

Эта функция часто используется для сопоставления строк с перечисляемыми типами C. (Обычно, в библиотеках Lua используется соглашение использовать строки вместо чисел для выбора опций.)

luaL_checkstack

[-0, +0, v]

void luaL_checkstack (lua_State *L, int sz, const char *msg);

Увеличивает размер стека до top + sz элементов, порождает ошибку, если стек не может быть увеличен до такого размера. Строка msg содержит дополнительный текст для сообщения об ошибке.

luaL_checkstring

[-0, +0, v]

const char *luaL_checkstring (lua_State *L, int narg);

Проверяет, является ли narg-ый аргумент функции строкой и возвращает эту строку.

luaL_checktype

[-0, +0, v]

void luaL_checktype (lua_State *L, int narg, int t);

Проверяет, имеет ли narg–ый аргумент функции тип t. См. lua_type для расшифровки типов t.

luaL_checkudata

[-0, +0, v]

void *luaL_checkudata (lua_State *L, int narg, const char *tname);

Проверяет, является ли narg-ый аргумент функции переменной C, хранящейся в переменной LUA (т.н. userdata) типа tname (см. luaL_newmetatable).

luaL_dofile

[-0, +?, e]

int luaL_dofile (lua_State *L, const char *filename);

Загружает и запускает указанный файл. Эта функция определена как следующий макрос:

     (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))

Возвращает 0, если в процессе выполнения не встретились ошибки, 1 в противном случае.

luaL_dostring

[-0, +?, e]

int luaL_dostring (lua_State *L, const char *str);

Загружает и запускает указанную строку. Эта функция определена как следующий макрос:

     (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))

Возвращает 0, если в процессе выполнения не встретились ошибки, 1 в противном случае.

luaL_error

[-0, +0, v]

int luaL_error (lua_State *L, const char *fmt, ...);

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

Эта функция ничего не возвращает, но для поддержки идиомы C ее можно использовать как return luaL_error(args).

luaL_getmetafield

[-0, +(0|1), e]

int luaL_getmetafield (lua_State *L, int obj, const char *e);

Записывает в стек поле e из метатаблицы объекта с индексом obj. Если объект не имеет метатаблицы или она не имеет указанного поля, функция возвращает 0 и ничего в стек не записывает.

luaL_getmetatable

[-0, +1, -]

void luaL_getmetatable (lua_State *L, const char *tname);

Записывает в стек метатаблицу, ассоциированную в реестре с именем tname (см. luaL_newmetatable).

luaL_gsub

[-0, +1, m]

const char *luaL_gsub (lua_State *L,
                       const char *s,
                       const char *p,
                       const char *r);

Создает копию строки s, заменяя любое вхождение строки p строкой r. Записывает в стек результирующую строку и возвращает ее же.

luaL_loadbuffer

[-0, +1, m]

int luaL_loadbuffer (lua_State *L,
                     const char *buff,
                     size_t sz,
                     const char *name);

Загружает буфер как модуль (chunk) Lua. Эта функция использует lua_load для загрузки модули в буфер, на который указывает buff размером sz.

Эта функция возвращает те же результаты, что и lua_load. Параметр name - это имя модуля (chunk), используемое для отладочной информации и в сообщениях об ошибках.

luaL_loadfile

[-0, +1, m]

int luaL_loadfile (lua_State *L, const char *filename);

Загружает файл как модуль (chunk) Lua. Эта функция использует lua_load для загрузки модуля из файла с именем filename. Если filename является NULL, тогда загрузка происходит из стандартного потока ввода. Первая строка файла игнорируется, если она начинается с символа #.

Эта функция возвращает такие же результаты, что и lua_load, но помимо этого обладает дополнительным кодом ошибки LUA_ERRFILE на тот случае, если невозможно открыть или прочитать файл.

Как и lua_load, эта функция, только загружает модуль (chunk), но не запускает его.

luaL_loadstring

[-0, +1, m]

int luaL_loadstring (lua_State *L, const char *s);

Загружает строку как модуль (chunk) Lua. Эта функция использует lua_load для загрузки модуля (chunk) в оканчивающейся нулем строке s.

Эта функция возвращает такие же результаты, как и lua_load.

Как и lua_load, эта функция, только загружает модуль (chunk), но не запускает его.

luaL_newmetatable

[-0, +1, m]

int luaL_newmetatable (lua_State *L, const char *tname);

Если реестр уже содержит ключ tname, возвращает 0. В противном случае, создает новую таблицу в качестве метатаблицы для переменной C, хранящейся в переменной LUA (userdata), добавляет ее в реестр с именем tname и возвращает 1.

В каждом из этих двух случаев, помещает в стек последнее значение, ассоциированное с именем tname в реестре.

luaL_newstate

[-0, +0, -]

lua_State *luaL_newstate (void);

Создает новое состояние Lua. Функция вызывает lua_newstate, используя стандартную функцию C realloc для выделения памяти, а затем использует функцию обработки ошибок (см. lua_atpanic), которая выводит сообщение об ошибке на стандартный поток вывода в случае фатальных ошибок.

Возвращает новое состояние или NULL, если в процессе выделения памяти встретились ошибки.

luaL_openlibs

[-0, +0, m]

void luaL_openlibs (lua_State *L);

Открывает все стандартные библиотеки Lua в контексте заданного состояния.

luaL_optint

[-0, +0, v]

int luaL_optint (lua_State *L, int narg, int d);

Если аргумент функции narg является числом, возвращает это число, приведенное к типу int. Если аргумент опущен или является nil – возвращает d. В противном случае – возбуждает ошибку.

luaL_optinteger

[-0, +0, v]

lua_Integer luaL_optinteger (lua_State *L,
                             int narg,
                             lua_Integer d);

Если аргумент функции narg является числом, возвращает это число, приведенное к типу данных lua_Integer. Если аргумент опущен или является nil – возвращает d. В противном случае – возбуждает ошибку.

luaL_optlong

[-0, +0, v]

long luaL_optlong (lua_State *L, int narg, long d);

Если аргумент функции narg является числом, возвращает это число, приведенное к типу данных long. Если аргумент опущен или является nil – возвращает d. В противном случае – возбуждает ошибку.

luaL_optlstring

[-0, +0, v]

const char *luaL_optlstring (lua_State *L,
                             int narg,
                             const char *d,
                             size_t *l);

Если аргумент функции narg является строкой, то возвращает эту строку. Если аргумент опущен или является nil – возвращает d. В противном случае – возбуждает ошибку.

Если l не является NULL, записывает в положение *l длину результата.

luaL_optnumber

[-0, +0, v]

lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);

Если аргумент функции narg является числом, то возвращает это число. Если аргумент опущен или является nil – возвращает d. В противном случае – возбуждает ошибку.

luaL_optstring

[-0, +0, v]

const char *luaL_optstring (lua_State *L,
                            int narg,
                            const char *d);

Если аргумент функции narg является строкой, то возвращает эту строку. Если аргумент опущен или является nil – возвращает d. В противном случае – возбуждает ошибку.

luaL_prepbuffer

[-0, +0, -]

char *luaL_prepbuffer (luaL_Buffer *B);

Возвращает указатель на место в памяти, размером LUAL_BUFFERSIZE, где можно копировать строку для добавления в буфер B (см. luaL_Buffer). После копирования строки в эту область памяти необходимо вызвать luaL_addsize с указанием размера строки, чтобы действительно добавить ее в буфер.

luaL_pushresult

[-?, +1, m]

void luaL_pushresult (luaL_Buffer *B);

Завершает использование буфера B, оставляя окончательную строчку на вершине стека.

luaL_ref

[-1, +0, m]

int luaL_ref (lua_State *L, int t);

Создает и возвращает ссылку на элемент таблицы с индексом t, для объекта на вершине стека (и выталкивает объект).

Ссылка является уникальным целочисленным ключом. До тех пор, пока вы не добавляете вручную ключи в таблицу t, luaL_ref гарантирует уникальность возвращаемых значений. Получить объект, на который ссылается ссылка r можно, вызывая lua_rawgeti(L, t, r). Функция luaL_unref освобождает ссылку и ассоциированный с ней объект.

Если объект на вершине стека nil, luaL_ref возвращает константу LUA_REFNIL. Константа LUA_NOREF всегда является отличной от любой ссылки, возвращаемой luaL_ref.

luaL_Reg

typedef struct luaL_Reg {
  const char *name;
  lua_CFunction func;
} luaL_Reg;

Тип для массивов функций, регистрируемых функцией luaL_register. Параметр name – имя функции, func – указатель на эту функцию. Каждый массив luaL_Reg должен оканчиваться предупреждающей записью, в которой name и func являются NULL.

luaL_register

[-(0|1), +1, m]

void luaL_register (lua_State *L,
                    const char *libname,
                    const luaL_Reg *l);

Открывает библиотеку.

При вызове со значением libname равным NULL, эта функция просто регистрирует все функции в списке l (см. luaL_Reg) в таблице на вершине стека.

При вызове с не null значением libname, luaL_register создает новую таблицу t, устанавливает ее как значение глобальной переменной libname, устанавливает ее также как значение package.loaded[libname] и регистрирует в ней все функции из списка l. Если таблица уже находится в package.loaded[libname] или в переменной libname, использует заново эту таблицу взамен создания новой.

В любом случае, функция оставляет таблицу на вершине стека.

luaL_typename

[-0, +0, -]

const char *luaL_typename (lua_State *L, int index);

Возвращает имя типа данных значения с индексом index.

luaL_typerror

[-0, +0, v]

int luaL_typerror (lua_State *L, int narg, const char *tname);

Генерирует ошибку с сообщением, подобным следующему:

     location: bad argument narg to 'func' (tname expected, got rt)

где location заполняется luaL_where, func имя текущей функции и rt имя типа актуального аргумента.

luaL_unref

[-0, +0, -]

void luaL_unref (lua_State *L, int t, int ref);

Освобождение ссылки ref из таблицы с индексом t (см. luaL_ref). Запись удаляется из таблицы, таким образом, что объекты, на которые они ссылаются, могут быть собраны. Ссылка ref is также освобождается для дальнейшего использования.

Если ref имеет значение LUA_NOREF или LUA_REFNIL, функция luaL_unref не выполняет никаких действий.

luaL_where

[-0, +1, m]

void luaL_where (lua_State *L, int lvl);

Записывает в стек строку, идентифицирующую текущее положение контролирующей единицы с уровнем lvl в стеке вызова. Обычно, эта строка имеет следующий формат:

     chunkname:currentline:

Уровень 0 - это выполняемая функция, уровень 1 - это функция, которая вызвала выполняемую функцию и т.д.

Эта функция используется для построения префикса для сообщений об ошибках.

5 - Стандартные библиотеки

Стандартные Lua библтотеки содержат часто используемые функции, которые выполняются непосредственно в C API. Некоторые из этих функций предоставляют важные сервисы языка (например, type и getmetatable); другие обеспечивают доступ к "внешним" сервисам (например, ввод/вывод); частично они реализованы на Lua, однако часто используемые и имеющие критическое время выполнения, реализованы на C (например, table.sort).

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

  • базовая библиотека (basic library);
  • библиотека пакетов (package library);
  • работа со строками (string manipulation);
  • работа с таблицами (table manipulation);
  • математические функции (sin, log, и т.п.);
  • ввод/вывод;
  • работа с операционной системой (operating system facilities);
  • отладка (debug facilities).

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

Для получения доступа к этим библиотекам, C хостовая программа должна вызвать функцию luaL_openlibs, которая открывает все стандартные библиотеки. Можно также загрузить каждую библиотеку отдельно: luaopen_base (для базовой библиотеки), luaopen_package (для библиотеи пакетов), luaopen_string (для библиотеки работы со строками), luaopen_table (для библиотеки работы с таблицами), luaopen_math (для библиотеки математических функций), luaopen_io (для ввода/вывода и библиотек работы с операционной системой), и luaopen_debug (для библиотеки отладки). Эти функции описаны в lualib.h и не должны вызываться непосредственно: их необходимо вызывать как любую другую C функцию Lua C, например с помощью lua_call.

5.1 - Базовые функции

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

assert (v [, message])

Выдает сообщение об ошибке, если значение параметра v равно false (т.е., nil или false); в противном случае, возвращаются все параметры. message – это сообщение об ошибке; если параметр отсутствует, по умолчанию выводится "assertion failed!"

collectgarbage (opt [, arg])

Эта функция является интерфейсом к сборщику мусора (garbage collector). В зависимости от значения параметра opt:

  • "stop": остановка сборщика мусора.
  • "restart": рестарт сборщика мусора.
  • "collect": выполнение полного цикла сборки мусора.
  • "count": возврат общего количества используемой Lua памяти (в Kбайтах).
  • "step": выполнение шага по сборке мусора. "Размер" шага регулируется параметром arg (большая величина соответствует большему шагу. Если Вы хотите регулировать размер шага, Вы должны сначала определить экспериментальным путем оптимальное значение arg. Возвращает true если шаг завершает полный цикл сборки мусора.
  • "setpause": присвоение значения arg/100 параметру пауза сборки мусора сборщика (см. §2.10).
  • "setstepmul": присвоение значения arg/100 параметру коэффициент шага сборки сборщика (см. §2.10).

dofile (filename)

Открывает указанный файл и выполняет его содержимое как Lua задачу (chunk). При вызове без параметров, dofile выполняет содержимое стандартного потока ввода (stdin). Возвращает все данные, возвращаемые выполняемой задачей. В случае ошибки, dofile передает ошибку вызывающей задаче (т.е.dofile запускается в незащищенном режиме).

error (message [, level])

Заканчивает последнюю защищенную вызванную функцию и возвращает message как сообщение об ошибках. Функция error никогда не возвращается.

Обычно, error добавляет информацию о местоположении возникновения ошибки в начало сообщения. Параметр level указывает способ определения места возникновения ошибки. Уровень 1 (по умолчанию), определяет положение ошибки в месте вызова функции error. Уровень 2 определяет место, где была вызвана функция, которая вызвала error; и т.д. Если параметр равен 0, то положение ошибки не добавляется в сообщение.

_G

Глобальная переменная (не функция), которая содержит глобальное окружение (environment) (_G._G = _G). Lua не использует эту переменную; изменение значения этой переменной не отражается на окружении и наоборот. (Для изменения окружения используйте setfenv.)

getfenv ([f])

Возвращает текущее окружение, в котором выполняется функция. f может быть как Lua функцией, так и числом, определяющим уровень стека, на котором расположена функция: Уровень 1 – это функция, которая вызвала getfenv. Если данная функция не является функцией Lua, или 0, getfenv возвращает глобальное окружение. По умолчанию f равно 1.

getmetatable (object)

Если object не имеет metatable, возвращается nil. В противном случае, если метатаблица объекта имеет поле "__metatable", возвращается значение этого поля. Иначе возвращается метатаблица данного объекта.

ipairs (t)

Возвращает три значения: итератор, таблицу t, и 0, поэтому конструкция

     for i,v in ipairs(t) do body end

будет выполнять цикл парами (1,t[1]), (2,t[2]), ···, до первого целого ключа, отсутствующего в таблице.

load (func [, chunkname])

Загружает составной оператор (chunk) с помощью функции func для получения составного оператора по частям. Каждый вызов func должен возвращать строку, которая соединяется с предыдущими результатами. Возврат значения nil (или отсутствие значения) говорит о конце составного оператора.

В случае отсутствия ошибок, возвращается откомпилированный составной оператор как функция; иначе, возвращается nil и сообщение об ошибке. Окружением возвращаемой функции является глобальное окружение.

chunkname используется как имя задачи для сообщения об ошибке, т.е. как отладочная информация. When absent, it defaults to "=(load)".

loadfile ([filename])

Аналогично load, но задача считывается из файла filename или из стандартного потока ввода, если имя файла не указано.

loadstring (string [, chunkname])

Аналогично load, но задача считывается из данной строки.

Для загрузки и выполнения данной строки, используйте следующую конструкцию

     assert(loadstring(s))()

When absent, chunkname defaults to the given string.

next (table [, index])

Позволяет программе получить все поля таблицы. Первый параметр – это таблица, второй – индекс в этой таблице. next возвращает следующий индекс в таблице и соответствующее ему значение. Если второй параметр nil, next возвращает начальный индекс и связанное с ним значение. При вызове последнего индекса, или с nil в пустой таблице, next возвращает nil. Если второй параметр отсутствует, он интерпретируется как nil. В частности, Вы можете использовать next(t) для проверки пустая таблица или нет.

Порядок следования индексов неопределен, даже для числовых индексов. (Для прохождения по таблице в числовом порядке, используйте числовой for или функцию ipairs.)

Результат работы next неопределен (undefined) если, в процессе сканирования таблицы, Вы присваиваете какое либо значение в несуществующее поле таблицы. Однако Вы можете модифицировать существующие поля. В частности, Вы можете очистить существующие поля.

pairs (t)

Возвращает три значения: функцию next (результат вызова, примечание переводчика), таблицу t, и nil, поэтому конструкция

     for k,v in pairs(t) do body end

будет выполнять итерацию по всем ключевым парам таблицы t.

См. предупреждения для функции next если Вы хотите в процессе итерации модифицировать таблицу.

pcall (f, arg1, ···)

Вызывает функцию f с данными параметрами в защищенном режиме (protected mode). Это значит, что при возникновении любой ошибки внутри функции f она дальше не передается; напротив, pcall перехватывает ошибку и возвращает статус. pcall возвращает сначала статус (тип boolean), который равен true если вызов завершился без ошибок. В этом случае, pcall также возвращает все данные, которые возвращает функция f, сразу после статуса. В случае возникновения ошибки, pcall возвращает false и сообщение об ошибке.

print (···)

Принимает любое количество параметров и отображает их значения в stdout, используется функция tostring для преобразования параметров в строки. print неудобен для форматированного вывода, он удобен для быстрого отображения значения, обычно используется для отладки. Чтобы сформатировать вывод используйте string.format.

rawequal (v1, v2)

Проверка равенства v1 и v2, без вызова каких либо метаметодов. Возвращает статус типа boolean.

rawget (table, index)

Возвращает реальное значение из table[index], без вызова метаметодов. table должен быть таблицей; index может быть любым значением.

rawset (table, index, value)

Присваивает value реальное значение из table[index] без выполнения метаметодов. table должен быть таблицей, index - любое значение отличное от nil, value – любое значение Lua.

Данная функция возвращает table.

select (index, ···)

Если index - число, возвращает все параметры после параметра с номером index. В противном случае, index должен быть строкой "#", в этом случае select возвращает общее количество параметров (исключая index, примечание переводчика).

setfenv (f, table)

Устанавливает окружение, которое будет использовано данной функцией. f может быть как Lua функцией, так и числом, которое указывает уровень стека функции: Уровень 1 – это функция, вызывающая setfenv. setfenv возвращает данную функцию.

В особом случае, когда f равно 0, setfenv изменяет окружение запущенной нити. В этом случае setfenv ничего не возвращает.

setmetatable (table, metatable)

Устанавливает метатаблицу для данной таблицы. (Вы не можете изменить метатаблицу из Lua, это можно сделать только из C). Если параметр metatable равен nil, то производится удаление метатаблицы для данной таблицы. Если метатаблица содержит поле "__metatable", то возникает ошибка.

Функция возвращает таблицу table.

tonumber (e [, base])

Попытка преобразования параметра в число. Если параметр уже является числом или строкой, конвертируемой в число, то tonumber возвращает это число; иначе, возвращает nil.

Необязательный параметр указывает основание системы счисления для интерпретации числа. Основание может быть любым целым числом в диапазоне от 2 до 36, включительно. Если основание больше 10, то символ 'A' (как в верхнем, так и в нижнем регистре) представляет 10, 'B' представляет 11, и так далее, символ 'Z' представляет 35. При основании 10 (по умолчанию), число может быть представлено в экспоненциальной форме (см. §2.1). Для других оснований можно указывать только беззнаковые целые числа.

tostring (e)

Принимает параметр любого типа и конвертирует его в строку в подходящем формате. Если требуется специальное форматирование, используйте функцию string.format.

Если метатаблица для e имеет поле "__tostring", tostring вызывает его значение с параметром e, и возвращает результат этого вызова.

type (v)

Возвращает тип параметра в виде строки. Возможные результаты этой функции - это "nil" (как строка, а не значение nil), "number", "string", "boolean", "table", "function", "thread", и "userdata".

unpack (list [, i [, j]])

Возвращает элементы из данной таблицы. Функция эквивалентна следующей конструкции
     return list[i], list[i+1], ···, list[j]

с тем исключением, что указанная выше конструкция может быть написана только для фиксированного количества элементов. По умолчанию, i равно 1, а j – длине списка, как это определено в операторе length (см. §2.5.5).

_VERSION

Глобальная переменная (не функция). Содержит строку, описывающую номер версии интерпретатора. В настоящий момент значение этой переменной равно "Lua 5.1".

xpcall (f, err)

Эта функция аналогична pcall, с тем отличием, что здесь Вы можете установить обработчик ошибок.

xpcall вызывает функцию f в защищенном режиме, используя обработчик ошибок err. Любые ошибки внутри f не передаются в вызывающую программу; напротив, xpcall перехватывает ошибку, вызывает функцию err с объектом, вызвавшим ошибку, и возвращает статус. Возвращает сначала статус (тип boolean), который равен true если вызов завершился без ошибок. В этом случае, xpcall также возвращает всё, что возвращает вызов функции f, сразу после статуса. Вслучае возникновения ошибок, xpcall возвращает false и результат из err.

5.2 - Работа с подпрограммами

Операции для работы с подпрограммами собраны в виде подбиблиотеки базовой библиотеки и содержатся внутри таблицы coroutine. См. §2.11 описание подпрограмм.

coroutine.create (f)

Создает новую подпрограмму, с телом f. Параметр f должен быть Lua функцией. Возвращает новую подпрограмму как объект типа нить ("thread").

coroutine.resume (co [, val1, ···])

Запускает или продолжает выполнение подпрограммы co. При первом использовании этой функции начинает выполняться тело функции. Значения val1, ··· передаются как параметры в эту функцию. Если подпрограмма была в состоянии yield, resume рестартует подпрограмму, передавая ей параметры val1, ··· а также результаты, полученные при вызове yield.

Если подпрограмма запускается без ошибок, resume возвращает true плюс любые значения переданные в yield (если подпрограмма была приостановлена ранее вызовом yield) или любые значения, возвращаемые функцией (если подпрограмма завершилась). В случае возникновения ошибок, resume возвращает false плюс сообщение об ошибке.

coroutine.running ()

Возвращает выполняемую подпрограмму, или nil, если вызвана из главной нити.

coroutine.status (co)

Возвращает статус подпрограммы co, в виде строки:
"running" (выполняется), если подпрограмма выполняется (собственно это и есть статус);
"suspended" (приостановалена), если подпрограмма приостановлена с помощью вызова yield, либо она еще не запущена на выполнение;
"normal" (норма) если подпрограмма активна, но еще не запущена на выполнение (т.е. она активизирована (resume) другой подпрограммой);
либо "dead" (остановлена) если подпрограмма завершилась или если остановлена по ошибке.

coroutine.wrap (f)

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

coroutine.yield (···)

Приостанавливает выполнение вызываемой подпрограммы. coroutine не может быть выполняющейся C функцией, метаметодом или итератором. Любые параметры, передаваемые в yield в дальнейшем передаются как дополнительные параметры при вызове resume.

5.3 - Модули

Библиотека пакетов предоставляет основные возможности для загрузки и построения модулей в Lua. Также она (библиотека, примечание переводчика) экспортирует две функции в глобальное окружение: require и module. Остальные экспортируются в таблицу package.

module (name [, ···])

Создает модуль. Если package.loaded[name] содержит таблицу, то эта таблица является модулем. В противном случае, если существует глобальная таблица t с данным именем name, то эта таблица – модуль. Иначе, если таблица не найдена, то создается новая таблица t и эта таблица помещается в поле - package.loaded[name]. Эта функция также инициализирует t._NAME заданным именем name, t._M собственно модулем (самой t), а t._PACKAGE именем пакета (полное имя модуля без последнего компонента; см. ниже). В конце module устанавливает t как новое окружение текущей функции и новое значение из package.loaded[name], т.о. require возвращает t.

Если name – составное (compound) имя (т.е., компоненты имени разделены точками), module создает (или повторно использует, если уже существует) таблицы для каждого компонента. Например, если name равно a.b.c, то module сохраняет модуль в поле c поля b глобального объекта a.

Данная функция может получать дополнительные опции options после имени модуля, где каждая опция является функцией, которая будет применена к модулю.

require (modname)

Загружает данный модуль. Функция начинается с проверки таблицы package.loaded для определения загружен модуль modname или нет. Если загружен, то require возвращает значение, хранящееся в package.loaded[modname]. В противном случае, она пытается найти загрузчик (loader) для данного модуля.

При поиске загрузчика, require просматривает массив package.loaders. Изменяя этот массив, мы можем изменить, как require, ищет модуль. Следующее объяснение базируется на заданной по умолчанию конфигурации для package.loaders.

При поиске загрузчика, require сначала запрашивает package.preload[modname]. Если там есть значение, это значение (оно должно быть функцией) является загрузчиком. В противном случае require ищет Lua загрузчик, используя путь (path), хранящийся в package.path. Если результат не достигнут, производит поиск C загрузчика, используя путь, хранящийся в package.cpath. Если поиск также безуспешен, используется универсальный загрузчик всё-в-одном (all-in-one) (см. package.loaders).

Как только загрузчик найден, require вызывает его с одним параметром: modname. Если загрузчик возвращает какое либо значение, require помещает его в package.loaded[modname]. Если загрузчик ничего не возвращает, то package.loaded[modname] устанавливается функцией require в true. В любом случае, require возвращает значение из package.loaded[modname].

Если возникают какие либо ошибки при загрузке или выполнении модуля, или если не удалось обнаружить загрузчик для модуля, то require вызывает ошибку.

package.cpath

Путь, используемый в require для поиска C загрузчика.

Lua инициализирует C путь package.cpath аналогично инициализации Lua пути package.path, используя переменную окружения LUA_CPATH (плюс путь по умолчанию, определенный в luaconf.h).

package.loaded

Данная таблица используется функцией require для проверки, загружен модуль или нет. Если Вам нужен модуль modname и package.loaded[modname] не равно false, require просто возвращает значение, хранящееся там.

package.loaders

Данная таблица используется функцией require для управления загрузкой модулей.

Каждая позиция в этой таблице - поисковая функция. При поиске модуля, require опрашивает каждую из этих функций в возрастающем порядке, с именем необходимого модуля в качестве параметра. Функция может возвратить другую функцию (загрузчик модуля) или строку с объясняснением почему функция не нашла модуль (или nil, если ей нечего сказать). Lua инициализирует эту таблицу с четырьмя функциями.

Первая поисковая функция просто ищет загрузчик в таблице package.preload.

Вторая поисковая функция ищет загрузчик как библиотеку Lua, по пути заданному в package.path. Путь представляет собой последовательность шаблонов, разделенных точками с запятой. В каждом шаблоне, функция подставляет вместо каждого знака вопроса в шаблоне - имя файла (filename), являющегося именем модуля и каждую точку - "разделителем каталога" (типа "/" в Unix); после этого она будет пробовать открыть файл по результирующему имени. Так, например, если Lua путь задан такой строкой:

     "./?.lua;./?.lc;/usr/local/?/init.lua"

то поисковая функция для модуля foo будет последоватьльно пробовать открыть файлы ./foo.lua, ./foo.lc, и /usr/local/foo/init.lua, именно в этом порядке.

Третья поисковая функция ищет загрузчик как библиотеку C, используя путь, заданный переменной package.cpath. Например, если C путь задан такой строкой:

     "./?.so;./?.dll;/usr/local/?/init.so"

то поисковая функция для модуля foo будет пробовать открыть файлы ./foo.so, ./foo.dll, и /usr/local/foo/init.so по порядку. Как только C библиотека находится, то функция вначале использует средства динамического связывания (dynamic link facility) для связывания (link) приложения с библиотекой. Затем она пытается найти C функцию внутри этой библиотеки с определенным именем и использовать её как загрузчик. Имя этой C функции составляется из строки "luaopen_" и к ней добавляется имя модуля, в котором точки заменены символом подчеркивания. Кроме того, если имя модуля содержит дефис, то начало имени до первого дефиса (включая его) удаляется. Например, если имя модуля a.v1-b.c, имя функции будет luaopen_b_c.

Четвертая поисковая функция вызывает универсальный загрузчик, называемый всё-в-одном (all-in-one loader). Этот загрузчик ищет C путь для библиотеки по основному имени (root name) данного модуля. Например, при запросе a.b.c, будет произведен поиск C библиотеки для a. Если она найдена, производится поиск открывающей функции; в нашем примере, это будет luaopen_a_b_c. Это позволяет одному пакету содержать несколько C подмодулей (submodules) в одной библиотеке, поскольку каждый подмодуль имеет свою функцию открытия.

package.loadlib (libname, funcname)

Динамическое связывание хостовой программы с C библиотекой libname. Внутри этой библиотеки производится поиск функции с именем funcname и она возвращается как C функция. (Поэтому, funcname должно соответствовать протоколу (см. lua_CFunction)).

Это функция низкого уровня (low-level function). Она игнорируется пакетной и модульной системой. В отличии от require, здесь не производится поиск путей и не производится автоматическое добавление расширений (extensions). libname должно быть полным именем файла C библиотеки, включая, если необходимо, путь и расширение. funcname должно быть именем, которое экспортировано из C библиотеки (это имя зависит от C компилятора и компоновщика (linker)).

Эта функция не поддерживается ANSI C. Поэтому это доступно не на всех платформах (доступно на Windows, Linux, Mac OS X, Solaris, BSD, плюс другие Unix системы, которые поддерживают dlfcn стандарт).

package.path

Путь, используемый функцией require для поиска Lua загрузчика.

При старте, Lua инициализирует эту переменную значением переменной окружения LUA_PATH или значением по умолчанию из luaconf.h, если переменная окружения не определена. Любое вхождение строки ";;" в переменную среды окружения замещается значением по умолчанию.

package.preload

Таблица, хранящая загрузчики для модулей (см. require).

package.seeall (module)

Устанавливает метатаблицу для модуля module с полем __index , ссылающимся на глобальное окружение, т.е. этот модуль наследует глобальное окружение. Это будет использоваться как опция для функции module.

5.4 - Работа со строками

Библиотека предоставляет основные функции для работы со строками, такие как поиск и выделение подстрок, а также поиск по шаблону. Строки в Lua индексируются с 1 (а не 0, как в C). Индексы могут быть отрицательными и интерпретируются как индекс с конца строки. Т.е. последний символ имеет позицию -1, и т.д.

Библиотека работы со строками предоставляет все функции в таблице string. Она также устанавливает поле __index метатаблицы строк на таблицу string. Также, Вы можете использовать строковые функции в объектно-ориентированном стиле. Например, string.byte(s, i) может быть записано как s:byte(i).

string.byte (s [, i [, j]])

Возвращает числовые коды символов s[i], s[i+1], ···, s[j]. По умолчанию значение для i равно 1; по умолчанию значение для j равно i.

Напоминаем, что числовые коды символов не одинаковы на разных платформах.

string.char (···)

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

Напоминаем, что числовые коды символов не одинаковы на разных платформах.

string.dump (function)

Возвращает строку, содержащую двоичное представление данной функции, так, что если после этого вызвать функцию loadstring указав ей в качестве параметра эту строку, то мы получим копию функции. function должна быть Lua функцией без внешних локальных переменных (upvalues).

string.find (s, pattern [, init [, plain]])

Ищет первое вхождение шаблона pattern в строку s. Если поиск успешен, то find возвращает индексы s где найдено совпадение с шаблоном, т.е. начало и конец вхождения; иначе возвращает nil. Третий, необязательный числовой параметр init указывает откуда начинать поиск; по умолчанию он равен 1, также он может быть отрицательным. Значение true в четвертом, необязательном параметре plain выключает возможность поиска по шаблону, в этом случае производится поиск подстроки как есть, т.е. считается, что она не содержит «шаблонных» ("magic") символов. Помните, что если указан параметр plain, то параметр init должен быть указан тоже.

Если шаблон содержит подшаблоны (captures) и поиск успешен, то найденные подстроки также возвращаются, сразу после двух индексов.

string.format (formatstring, ···)

Возвращает параметры, передаваемые в функцию, отформатированные в соответствии первым параметром (который должен быть строкой). Строка формата должна строиться по тем же правилам, что и строка формата для семейства C функций printf. Отличие только в том, что опции/модификаторы *, l, L, n, p и h не поддерживаются, но имеется дополнительная опция q. Опция q позволяет вернуть строку в формате, безопасно воспринимаемом Lua интерпретатором: сама строка выводится в двойных кавычках, а все двойные кавычки, перевод строки, символы с кодом 0 и обратный слеш внутри строки экранируются обратным слешем (escaped). Например, вызов
     string.format('%q', 'a string with "quotes" and \n new line')

возвратит строку:

     "a string with \"quotes\" and \
      new line"

Опции c, d, E, e, f, g, G, i, o, u, X, и x должны использоваться только для числовых параметров, а q и s - для строковых.

Эта функция не принимает строковые параметры, содержащие символы с кодом 0, кроме параметров для формата, имеющего опцию q.

string.gmatch (s, pattern)

Возвращает итератор, который, при каждом вызове, возвращает следующее захваченное значение. Если шаблон pattern не содержит подшаблонов (captures), то при каждом вызове будет выполнено простое сравнение.

Например,следующий цикл

     s = "hello world from Lua"
     for w in string.gmatch(s, "%a+") do
       print(w)
     end

будет проходить по всем словам в строке s, печатая их построчно по одному. Следующий пример собирает все парные ключи key=value из указанной строки в таблицу:

     t = {}
     s = "from=world, to=Lua"
     for k, v in string.gmatch(s, "(%w+)=(%w+)") do
       t[k] = v
     end

Для данной функции, символ '^' в начале шаблона (т.е. признак поиска с начала строки) не работает, поскольку это помешает итерации.

string.gsub (s, pattern, repl [, n])

Возвращает копию s, в котором все найденные строки (или только n строк, если этот параметр задан) были заменены строкой замены, указанной repl. repl может быть строкой, таблицей, или функцией. Функция gsub также возвращает как второе значение общее количество произведенных замен.

Если repl - строка, то для замены используется ее значение. Символ % работает как символ со специальным назначением: любая последовательность в repl в виде %n, где n - число от 1 до 9, заменяется на n-ную подстроку (см. ниже). Последовательность %0 заменяется на всю найденную строку. Для задания одиночный символа % используется запись %%.

Если repl является таблицей, то она запрашивается при каждом совпадении шаблона со строкой, с использованием первой захваченной подстроки в качестве ключа; если шаблон не содержит подшаблонов, то в качестве ключа используется найденная строка целиком.

Если repl является функцией, то эта функция вызывается каждый раз, когда обнаруживается совпадение. В качестве параметров ей передаются все захваченные подстроки; если шаблон не содержит подшаблонов, то в функцию передается найденная строка целиком как единственный аргумент.

Если значение, возвращаемое таблицей или функцией является строкой или числом, то это значение используется для замены; в противном случае, если значение равно false или nil, то замена не производится (т.е. найденное значение остается без замены).

Необязательный последний параметр n ограничивает максимальное количество замен. Например, если n равно 1, то будет выполнено не более одной замены.

Несколько примеров:

     x = string.gsub("hello world", "(%w+)", "%1 %1")
     --> x="hello hello world world"

     x = string.gsub("hello world", "%w+", "%0 %0", 1)
     --> x="hello hello world"

     x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
     --> x="world hello Lua from"

     x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
     --> x="home = /home/roberto, user = roberto"

     x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
           return loadstring(s)()
         end)
     --> x="4+5 = 9"

     local t = {name="lua", version="5.1"}
     x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
     --> x="lua-5.1.tar.gz"

string.len (s)

Возвращает длину строки, переданной в качестве параметра. Пустая строка "" имеет длину 0. Вложенные символы с кодом 0 также считаются как символ, т.е. строка "a\000bc\000" имеет длину 5.

string.lower (s)

Возвращает копию строки s, где все заглавные буквы заменены на прописные. Все остальные символы остаются неизменными. Понятие «заглавные буквы» зависит от текущей кодовой страницы.

string.match (s, pattern [, init])

Поиск первого вхождения шаблона pattern в строку s. В случае обнаружения, match возвращает захваченные значения (captures); в противном случае возвращает nil. Если pattern не содержит подшаблонов, то производится простое сравнение. Третий, необязательный числовой параметр init указывает с какого символа строки необходимо начинать поиск; по умолчанию этот параметр равен 1. Также он может быть отрицательным.

string.rep (s, n)

Возвращает строку, в которой содержится n копий строки s.

string.reverse (s)

Возвращает строку, в которой символы строки s расположены в обратном порядке.

string.sub (s, i [, j])

Возвращает подстроку строки s, которая начинается с символа с индексом i и продолжается до символа с индексом j; i и j могут быть отрицательными. Если j не указан, то считается, что он равен -1 (то же самое, что длина строки). В частности, вызов string.sub(s,1,j) возвращает начальную часть строки с длиной j, а string.sub(s, -i) возвращает конец строки s длиной i.

string.upper (s)

Принимает строку и возвращает копию этой строки, где все прописные буквы заменены на заглавные. Все остальные символы остаются неизменными. Понятие «прописные буквы» зависит от текущей кодовой страницы.

5.4.1 - Шаблоны

Символьный Класс:

Символьный класс используется, чтобы представить набор символов. Следующие комбинации используются для описания символьного класса:

  • x: (где x - соответствует сам себе. (Он не может быть равен ни одному из волшебных символов ^$()%.[]*+-?).
  • .: (точка) соответствует любому символу.
  • %a: соответствует любой букве.
  • %c: соответствует любому управляющему символу.
  • %d: соответствует любой цифре.
  • %l: соответствует любой букве в нижнем регистре.
  • %p: соответствует любому символу пунктуации.
  • %s: соответствует любому пробельному символу.
  • %u: соответствует любой букве в верхнем регистре.
  • %w: соответствует любому алфавитно-цифровые символу.
  • %x: соответствует любой шестнадцатеричной цифре.
  • %z: соответствует символу с представлением 0.
  • %x: (где x - любой не алфавитно-цифровой символ), соответствует сам себе. Это - стандартный способ экранировки волшебных символов. Лучше следить за тем, чтобы любому символу пунктуации (даже не "волшебному") предшествовал '%', когда этот символ применен в шаблоне.
  • [set]: соответствует любому символу из набора, заданного в set. Диапазон символов может быть определен, с помощью символа '-' отделяющего начало и конец диапазона. Все символьные классы %x описанные выше, могут использоваться как компоненты в наборе. Все другие символы в наборе представляются как есть. Например, [%w_] (или [_%w]) соответствует любому алфавитно-цифровому символу или символу подчеркивания, [0-9] соответствует любой десятичной цифре, и [0-9%l%-] соответствует любой десятичной цифре или любой букве в нижнем регистре или символу дефиса '-'.

    Взаимодействие между диапазонами и классами не определено. Поэтому, наборы подобные [%a-z] или [a-%%] не имеют никакого значения.

  • [^set]: Отрицательный набор символов. Соответствует любому символу, кроме тех, что заданы в наборе set. Содержимое набора интерпретируется аналогично описанному выше [set].

Для всех классов, представляемых одиночными символами (%a, %c, и т.п.), соответствующая прописная буква представляет отрицание класса. Например, %S представляет все НЕ пробельные символы.

Представления символа, пробела и других символьных групп зависят от текущих региональных установок. В частности, класс [a-z] не эквивалентен %l.

Элемент шаблона:

Элементом шаблона может быть

  • Одиночный символьный класс, который соответствует любому одиночному символу из заданного класса;
  • Одиночный символьный класс, сопровождаемый '*', что соответствует 0 или большему количеству повторений символов из заданного класса. Эти элементы повторения будут всегда соответствовать самой длинной возможной последовательности.
  • Одиночный символьный класс, сопровождаемый '+', что соответствует 1 или большему количеству повторений символов из заданного класса. Эти элементы повторения будут всегда соответствовать самой длинной возможной последовательности.
  • Одиночный символьный класс, сопровождаемый '-', что также соответствует 0 или большему количеству повторений символов из заданного класса. В отличие от *, элементы повторения будут всегда соответствовать самой короткой возможной последовательности;
  • Одиночный символьный класс, сопровождаемый '?', что соответствует 0 или единственному вхождению символа из заданного класса;
  • %n, при n от 1 до 9; такой элемент равняется n-й зафиксированной подстроке (см. ниже);
  • %bxy, здесь x и y - два различных символа. Такой элемент соответствует строкам, которые начинаются с x, заканчиваются на y, и в них сбалансированы x и y. Это означает, что, если читать строку слева направо, подсчитывая +1 для x и -1 для y, то последний y является первым y, для которого счетчик равен 0. Например, элемент %b() соответствует выражениям со сбалансированными круглыми скобками.

Шаблон:

Шаблон представляет собой последовательность описанных выше элементов. Символ '^' в начале шаблона, говорит о том, что заданная последовательность начинается с начала строки. Символ '$' в конце шаблона, говорит о том, что заданной последовательностью строка заканчивается. Символы '^' и '$', размещенные в других местах шаблона, не имеют никакого специального значения и представляются как есть.

Подшаблоны:

В шаблон можно включить подшаблоны, выделив их круглыми скобками. Если найденная строка соответствует шаблону, то ее подстроки, соответствующие подшаблонам, будут доступны для будущего использования. Подшаблоны пронумерованы согласно их левым круглым скобкам. Например, в шаблоне "(a*(.)%w(%s*))", часть строки, соответствующая "a*(.)%w(%s*)" будет зафиксирована как первый подшаблон (и поэтому имеет номер 1); любые символы попавшие под соответствие "." будут зафиксированы как подшаблон номер 2, и часть строки, соответствующая "%s*" получит номер 3.

Специальный вариант использования подшаблонов - получение текущей позиции в строке. Для этого используются пустые подшаблоны (). Например, если мы применим шаблон "()aa()" к строке "flaaap", то получим два результата: 3 и 5.

Шаблон не может содержать вложенные ноли. Используйте %z вместо этого.

5.5 - Обработка таблиц

Эта библиотека предоставляет основные функции для обработки таблиц. Все функции включены в таблицу table.

Большинство функций в библиотеке таблиц предполагают что таблица является массивом или списком. Для этих функций, когда мы говорим о параметре «длина» таблицы, мы имеем в виду результат оператора length.

table.concat (table [, sep [, i [, j]]])

Соединяет массив, в котором все элементы – строки или числа, возвращая строку в виде table[i]..sep..table[i+1] ··· sep..table[j]. Значение по умолчанию для разделителя sep – пустая строка, значение по умолчанию для начального индекса i – 1, а для конечного j – длина таблицы. Если i больше j, функция возвращает пустую строку.

table.insert (table, [pos,] value)

Вставляет элемент value в позицию pos в table, сдвигая вверх остальные элементы. Значение по умолчанию для pos равно n+1, где n это длина таблицы (см. §2.5.5), таким образом вызов table.insert(t,x) добавляет x в конец таблицы t.

table.maxn (table)

Возвращает наибольший положительный числовой индекс заданной таблицы, или ноль если таблица не имеет положительных числовых индексов. (Для выполнения запроса эта функция перебирает все индексы таблицы.)

table.remove (table [, pos])

Удаляет из table элемент в позиции pos, сдвигая вниз остальные элементы, если это необходимо. Возвращает значение удаленного элемента. Значение по умолчанию для pos – n, где n – длина таблицы, таким образом вызов table.remove(t) удаляет последний элементы таблицы t. (Примечание: использование функций insert remove со значениями по умолчанию позволяет работать с таблицей как со стандартным LIFO – стеком)

table.sort (table [, comp])

Сортирует элементы таблицы в заданном порядке, внутри таблицы, начиная с table[1] и заканчивая table[n], где n – длина таблицы. Необязательный параметр comp - функция, определяющая порядок сортировки, которая для двух входных параметров возвращает true если первый из них меньше второго. (Таким образом not comp(a[i+1],a[i]) вернет true для любого i после окончания сортировки). Если comp не задан, то вместо него будет использован стандартный оператор сравнения <.

Алгоритм сортировки не стабилен; в том смысле, что элементы, в результате заданного алгоритма сравнения посчитанные равными, могут быть переставлены в процессе сортировки.

5.6 - Математические функции

Эта библиотека предоставляет интерфейс к некоторым функциям стандартной математической библиотеки C. Все эти функции сосредоточены в таблице math.

math.abs (x)

Возвращает модуль x.

math.acos (x)

Возвращает арккосинус x (в радианах).

math.asin (x)

Возвращает арксинус x (в радианах).

math.atan (x)

Возвращает арктангенс x (в радианах).

math.atan2 (y, x)

Возвращает арктангенс x/y (в радианах), но использует знаки обоих параметров для вычисления «четверти» на плоскости. (Также корректно обрабатывает случай когда y равен нулю.)

math.ceil (x)

Возвращает наименьшее целое число, большее или равное x. (Округление «вверх»).

math.cos (x)

Возвращает косинус x (Угол – в радианах).

math.cosh (x)

Возвращает кошинус (гиперболический косинус) x.

math.deg (x)

Переводит угол, заданный x в радианах в градусы.

math.exp (x)

Возвращает ex.

math.floor (x)

Возвращает наибольшее целое число, меньшее или равное x. (Округление «вниз»)

math.fmod (x, y)

Возвращает остаток от деления x на y.

math.frexp (x)

Возвращает m и e такие, что x = m2e, e – целое, а модуль m находится в интервале [0.5, 1) (либо ноль, если x равен нулю). (Разложение числа с фиксированной запятой).

math.huge

Значение HUGE_VAL, значение большее, либо равное любому числовому значению.

math.ldexp (m, e)

Возвращает m2e (e должно быть целым). (Восстановление значения по мантиссе и показателю).

math.log (x)

Возвращает натуральный логарифм x.

math.log10 (x)

Возвращает десятичный логарифм x.

math.max (x, ···)

Возвращает максимальный из аргументов.

math.min (x, ···)

Возвращает минимальный из аргументов.

math.modf (x)

Возвращает как два числа целую и дробную часть x.

math.pi

Значение pi.

math.pow (x, y)

Возвращает xy. (Вы также можете использовать запись x^y для вычисления значения этой функции.)

math.rad (x)

Конвертирует угол x, заданный в градусах, в радианы.

math.random ([m [, n]])

Эта функция является интерфейсом к простейшему генератору псевдослучайных чисел rand, предоставляемому ANSI C. (Нет никаких гарантий по поводу его статистических свойств.)

При вызове без аргументов, возвращает псевдослучайное действительной число в интервале [0,1). При вызове с аргументом m, math.random возвращает псевдослучайное целое число из отрезка [1, m]. При вызове с двумя аргументами – m и n, math.random возвращает псевдослучайное целое число из отрезка [m, n].

math.randomseed (x)

Инициализирует генератор псевдослучайных чисел параметром x ("seed"): каждый параметр порождает соответствующую (но одну и ту же) последовательность псевдослучайных чисел.

math.sin (x)

Возвращает синус x (аргумент – в радианах).

math.sinh (x)

Возвращает шинус (гиперболический синус) x.

math.sqrt (x)

Возвращает квадратный корень x. (Вы также можете использовать выражение x^0.5 для вычисления этого значения.)

math.tan (x)

Возвращает тангенс угла x (аргумент – в радианах).

math.tanh (x)

Возвращает гиперболический тангенс x.

5.7 - Средства ввода-вывода

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

При использовании неявных файловых дескрипторов, все операции предоставляются таблицей io. При использовании явных дескрипторов, операция io.open возвращает дескриптор, а после этого все операции являются методами данного дескриптора.

Таблица io также предоставляет три предопределенных (predefined) файловых дескриптора со стандартными (в C) значениями: io.stdin, io.stdout, и io.stderr.

Если не указано иное, все функции ввода-вывода возвращают nil при ошибочном завершении (а также сообщение об ошибке как второй результат и системно-независимый код ошибке в третьем результате) или какое-либо значение, отличное от nil при успешном завершении.

io.close ([file])

Эквивалентна file:close(). Без параметра file, закрывает стандартный поток вывода.

io.flush ()

Эквивалентна file:flush для стандартного потока вывода.

io.input ([file])

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

В случае ошибок, данная функция возбуждает ошибку вместо того, чтобы возвратить код ошибки.

io.lines ([filename])

Открывает файл с данным именем в режиме чтения и возвращает функцию-итератор (iterator function) которая при каждом последующем вызове возвращает новую строчку из файла. Таким образом, конструкция

     for line in io.lines(filename) do body end

обработает все строки файла. При обнаружении функцией-итератором конца файла, она возвратит nil (для окончания цикла) и автоматически закроет файл.

Вызов io.lines() (без имени файла) эквивалентен io.input():lines(); таким образом он обработает строки стандартного файла ввода. В этом случае, файл по окончанию итераций не закроется автоматически.

io.open (filename [, mode])

Эта функция открывает файл в режиме, указанном в строке mode. Возвращает хендлер файла, или, в случае ошибок, nil и сообщение об ошибке.

Строка mode может содержать следующие значения:

  • "r": режим чтения (используется по умолчанию);
  • "w": режим записи;
  • "a": режим дозаписи в конец файла;
  • "r+": режим изменения, все ранее записанные данные сохраняются;
  • "w+": режим изменения, все ранее записанные данные стираются;
  • "a+": режим изменения с дозаписью в конец, все ранее записанные данные сохраняются, запись разрешена только в конец файла.

Строка mode может также содержать 'b' в конце; этот символ нужен для некоторых систем для открытия файла в двоичном режиме. Эта строка полностью повторяет синтаксис функции C fopen.

io.output ([file])

Аналогична io.input, но работает с стандартным потоком вывода.

io.popen (prog [, mode])

Запускает программу prog в отдельном процессе и возвращает хендлер файла. Его можно использовать для чтения данных из этой программы (если mode равен "r", значение по умолчанию) или для записи данных в эту программу (если mode равен "w").

Эта функция системно зависима и доступна не на всех платформах.

io.read (···)

Эквивалентна функции io.input():read.

io.tmpfile ()

Возвращает хендлер для временного файла. Этот файл открывается в режиме изменения и автоматически удаляется при завершении программы.

io.type (obj)

Проверяет, является ли obj валидным хендлером файла. Возвращает строку "file" если obj – открытый хендлер файла, строку "closed file" если obj закрытый хендлер файла, или nil если obj не является хендлером файла.

io.write (···)

Эквивалентна функции io.output():write.

file:close ()

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

file:flush ()

Сохраняет все данные, записанные в файл file.

file:lines ()

Возвращает функцию-итератор, которая при каждом вызове возвращает новую строку из файла. Таким образом, конструкция

     for line in file:lines() do body end

обработает все строки файла. (Но, в отличии от io.lines, эта функция не закроет файл по окончании цикла (т.е. по достижении конца файла).)

file:read (···)

Читает данные из файла file, в соответствии с заданными форматами, которые определяют, что читать. Для каждого формата, функция возвращает строку (или число) с прочитанными символами, или nil если ей не удалось прочитать данные в указанном формате. При вызове без указания формата, использует стандартный формат, соответствующий чтению всей следующей строки (см. ниже).

Возможные форматы:

  • "*n": читает число; это – единственный формат, возвращающий число вместо строки.
  • "*a": читает весь файл, начиная с текущей позиции. Если позиция совпадает с концом файла, возвращает пустую строку.
  • "*l": читает следующую строку (пропуская конец строки), возвращает nil в конце файла. Это – формат по умолчанию.
  • number: читает строку, но не более заданного количества символов, возвращает nil по достижении конца файла. Если число равно нулю, функция ничего не читает, возвращая пустую строку, или nil по достижении конца файла.

file:seek ([whence] [, offset])

Получает текущую позицию в файле, отсчитываемую от начала файла. Так же устанавливает текущую позицию, прибавляя к исходной число, заданное параметром offset. Исходная позиция задается строкой whence, следующим образом:

  • "set": исходная позиция равна 0 (начало файла);
  • "cur": исходная позиция – текущая;
  • "end": исходная позиция – конец файла;

В случае успешного выполнения, функция seek возвращает позицию уставленную в файле, отсчитываемую от начала файла. Если функция завершается неудачно, она возвращает nil и строку – описание ошибки.

Значение по умолчанию для параметра whence равно "cur", а для параметра offset – 0. Таким образом вызов file:seek() возвращает текущую позицию в файле, не изменяя ее; вызов file:seek("set") перемещает указатель текущей позиции в начало файла (и возвращает 0); а вызов file:seek("end") перемещает указатель текущей позиции в конец файла, и возвращает его длину.

file:setvbuf (mode [, size])

Изменяет режим файла записи (output file) на буферизованный режим. Существует 3 возможных режима:

  • "no": отключить буферизацию; результат записи в файл немедленно «сбрасывается» на диск.
  • "full": полная буферизация; операции записи на диск выполняются только при переполнении буфера (или при вызове функции очистки буфера (см. io.flush)).
  • "line": построчная буферизация; запись буферизуется до достижения конца строки или происходит ввод из особенных (специальных) файлов (таких как, например, терминал).

В двух последних случаях, size указывает размер буфера в байтах. По умолчанию используется «необходимый и достаточный размер».

file:write (···)

Записывает значение каждого из аргументов в файл file. Аргументами могут быть строки или числа. Для записи других значений, до вызова функции write, обработайте данные функциями tostring или string.format.

5.8 - Функции операционной системы

Эта библиотека включена в таблицу os.

os.clock ()

Возвращает примерное количество времени в секундах, потраченное CPU на выполнение программы

os.date ([format [, time]])

Возвращает строку или таблицу, содержащую дату и время, отформатированные в соответствии с заданным параметром format.

Если аргумент time передается функции, то это время будет отформатировано (см. функцию os.time). В противном случае, date будет форматировать текущее время.

Если параметр format начинается с '!', то время форматируется в соответствии с универсальным глобальным временем (по Гринвичу). После этого опционального символа, если format равен "*t", то date возвращает таблицу со следующими полями: year (год, четыре цифры), month (месяц, 1 – 12), day (день, 1 – 31), hour (час, 0 – 23), min (минуты, 0 – 59), sec (секунды, 0 – 61), wday (день недели, воскресенью соответствует 1), yday (день года), и isdst (флаг дневного времени суток, тип boolean).

Если format не равен "*t", то функция date возвращает дату в виде строки, отформатированной в соответствии с правилами функции C strftime.

При вызове без аргументов, date возвращает данные «в обычном формате», который зависит от системы и текущих настроек операционной системы (т.е., os.date() эквивалентна os.date("%c")).

os.difftime (t2, t1)

Возвращает число секунд, прошедшее в интервале от времени t1 до времени t2. В POSIX, Windows, и некоторых других системах, это значение равно в точности t2-t1.

os.execute ([command])

Эта функция эквивалентна функции C system. Она передает параметр command на выполнение оболочке операционной системы. Она возвращает системно-зависимый статус. Если параметр command не передается, то возвращает не ноль, если оболочка доступна и ноль в противном случае.

os.exit ([code])

Вызывает функцию C exit, с опциональным параметром code, для останова выполнения программы-хозяина. Значение по умолчанию для параметра code – код успешного завершения. Примечание: в ISO C описаны коды 0, EXIT_SUCCESS (обычно равен 0, но не стандартизирован, может обозначать «успешное завершение, отличное от состояния 0»), EXIT_FAILURE (обычно какое-либо ненулевое значение, но не стандартизирован).

os.getenv (varname)

Возвращает значение переменной окружения varname, или nil если эта переменная не определена.

os.remove (filename)

Удалаяет файл или директорию с заданным именем. Директории должны быть пусты. Если функция не может провести удаления, она возвращает nil, плюс строку, содержащую описание ошибки.

os.rename (oldname, newname)

Переименовывает файл или директорию oldname в newname. Если функция не модет провести переименования, она возвращает nil, плюс строку, содержащую описание ошибки.

os.setlocale (locale [, category])

Изменяет текущие региональные настройки (locale) программы. Параметр locale является строкой, содержащей региональные настройки (locale); category – опциональный строчный параметр, содержащий категорию, для которой производится изменение: "all", "collate", "ctype", "monetary", "numeric", или "time"; значением по умолчанию является категория "all". Функция возвращает значение новых настроек (locale), или nil, если вызов не может быть обработан.

Если locale – пустая строка, региональные настройки изменяются на региональные настройки, определяемые реализацией (implementation-defined nativelocale). Если locale – строка "C", текущие региональные настройки изменяются на стандартные C-настройки.

При вызове с nil в качестве первого аргумента, эта функция возвращает текущие региональные настройки для заданной категории.

os.time ([table])

Возвращает текущее время при вызове без аргументов, или время и дату, указанные в передаваемой таблице. Эта таблица должна иметь поля year, month, и day, и может иметь поля hour, min, sec, и isdst (описание этих полей см. в описании функции os.date).

Возвращаемое значение – это число, значение которого зависит от системы. В POSIX, Windows, и некоторых других системах, это число соответствует количеству секунд, отсчитываемому от некоторого заданного момента времени ("эпоха"). В других системах, значение не специфицировано, и число, возвращаемое функцией time может быть использовано только как аргумент функций date и difftime.

os.tmpname ()

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

5.9 - Библиотека отладки

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

Все функции этой библиотеки описаны в таблице debug. Все функции, которые работают с нитями (thread) имеют опциональный первый параметр, который является нитью, над которой будут производиться действия. По умолчанию всегда используется текущая нить.

debug.debug ()

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

Обратите внимание, что команды для функции debug.debug лексически не вложены ни в какую функцию, поэтому не имеют прямого доступа к локальным переменным.

debug.getfenv (o)

Возвращает окружение (environment) объекта o.

debug.gethook ([thread])

Возвращает текущие настройки перехвата (hook settings) нити (thread), как три значения: текущая функция перехвата, текущая маска перехвата, и текущее количество перехватов (hook count) (в соответствии с параметрами, установленными функцией debug.sethook).

debug.getinfo ([thread,] function [, what])

Возвращает таблицу с информацией о функции. Вы можете задать функцию непосредственно, или вы можете задать номер функции, который соответствует функции, запущенной на уровне function стека вызовов заданной нити: уровень 0 соответствует текущей функции (getinfo непосредственно); уровень 1 – это функция, которая вызвала getinfo; и т.д. Если в параметре function задано число, большее, чем количество запущенных функций, то getinfo возвращает nil.

Возвращаемая таблица может содержать все поля, возвращаемые lua_getinfo, в соответствии со строкой what, содержащей описание, какие поля должны быть заполнены. Значением по умолчанию для параметра what является значение, соответствующее заполнению всех возможных полей, за исключением таблицы валидных строк. В случае наличия опции 'f' в строке, заполняется поле func, содержащее непосредственно функцию. При наличии опции 'L' заполняется поле activelines с таблицей валидных строк.

Например, выражение debug.getinfo(1,"n").name возвращает имя текущей функции, если подходящее имя может быть найдено, а выражение debug.getinfo(print) возвращает таблицу со всей возможной информацией о функции print.

debug.getlocal ([thread,] level, local)

Данная функция возвращает имя и значение локальной переменной с индексом local функции на уровне level стека. (Первый локальная переменная функции имеет индекс 1, и т.д., вплоть до последней локальной переменной.) Функция возвращает nil если не существует локальной переменной с заданным индексом, и возбуждает ошибку при вызове с параметром level, большем максимально разрешенного. (Вы можете вызвать debug.getinfo для проверки, является ли уровень в стеке разрешенным.)

Переменные, начинающиеся с '(' (открывающей скобки) являются внутренними переменными (переменные циклов, временные переменные, и локальные переменные функций C).

debug.getmetatable (object)

Возвращает метатаблицу заданного объекта object или nil если объект не имеет метатаблицы.

debug.getregistry ()

Возвращает таблицу реестра (registry table) (см. §3.5).

debug.getupvalue (func, up)

Данная функция возвращает имя и значение внешней локальной переменной (upvalue) с индексом up функции func. Функция возвращает nil если не существует внешней локальной переменной (upvalue) с заданным индексом.

debug.setfenv (object, table)

Изменяет окружение заданного объекта object на заданное в table. Возвращает объектobject.

debug.sethook ([thread,] hook, mask [, count])

Делает данную функцию функцией перехвата (hook). Строка mask и число count определяют условия вызова функции перехвата. Строка mask может содержать следующие символы с данным значением:

  • "c": функция перехвата вызывается при каждом вызове функции;
  • "r": функция перехвата вызывается при каждом выходе из функции;
  • "l": функция перехвата вызывается при каждом переходе на новую строку кода.

Если параметр count отличен от нуля, перехват происходит через каждые count инструкций.

При вызове без аргументов, debug.sethook отключает перехват.

When the hook is called, its first parameter is a string describing the event that has triggered its call: "call", "return" (or "tail return"), "line", and "count". For line events, the hook also gets the new line number as its second parameter. Inside a hook, you can call getinfo with level 2 to get more information about the running function (level 0 is the getinfo function, and level 1 is the hook function), unless the event is "tail return". In this case, Lua is only simulating the return, and a call to getinfo will return invalid data.

debug.setlocal ([thread,] level, local, value)

Эта функция присваивает значение value локальной переменной с индексом local функции на уровне level стека. Функция возвращает nil если не существует локальной переменной с данным индексом, и возбуждает ошибку при вызове с уровнем level, выходящем за границы стека. (Вы можете вызвать getinfo для проверки того, что уровень является верным.) В противном случае, возвращает значение локальной переменной.

debug.setmetatable (object, table)

Изменяет метатаблицу заданного объекта object на таблицу table (которая также может быть nil).

debug.setupvalue (func, up, value)

Данная функция присваивает значение value локальной внешней переменной (upvalue) с индексом up функции func. Функция возвращает nil если не существует локальной внешней переменной (upvalue) с данным индексом. В противном случае, возвращает имя локальной внешней переменной (upvalue).

debug.traceback ([thread,] [message] [, level])

Возвращает строку со следом (traceback) стека вызовов. Опциональный параметр message добавляется в начало следа. Опциональный параметр level – число, обозначающее уровень, с которого необходимо начинать след (traceback) (значение по умолчанию равно 1, т.е. соответствует функции, вызывающей traceback).

6 - Интерпретатор языка Lua

Несмотря на то, что язык Lua был разработан в качестве языка-расширения, для включения в программы-хозяева, написанные на C, он также зачастую используется как автономный язык. Интерпретатор Lua для автономного выполнения программ называется lua, и включен в стандартный пакет поставки. Автономный интерпретатор включает все стандартные библиотеки, в том числе библиотеку отладки. Параметры запуска интерпретатора:

     lua [options] [script [args]]

Параметры (options) могут быть следующими:

  • -e stat: выполняет строку stat;
  • -l mod: "требует" mod;
  • -i: после запуска script переходит в интерактивный режим;
  • -v: выводит информацию о версии;
  • --: игнорирует все последующие опции командной строки;
  • -: использует ввод с stdin вместо имени скрипта и игнорирует все последующие опции командной строки.

После обработки опций, lua выполняет заданный скрипт script, передавая ему аргументы args как строковые значения. При вызове без аргументов, lua работает аналогично lua -v -i когда стандартный поток ввода (stdin) – терминал, и как lua - - в противном случае.

Перед обработкой аргументов, интерпретатор проверяет, выставлена ли переменная окружения LUA_INIT. Если ее формат соответствует @filename, то lua запускает указанный файл. В противном случае, lua выполняет команду, записанную в переменной.

Все опции обрабатываются в прямом порядке, за исключением опции -i. Например, следующий вызов

     $ lua -e'a=1' -e 'print(a)' script.lua

Приведет к тому, что интерпретатор сначала изменит значение a на 1, затем выведет значение переменной a (как '1'), и только после этого запустит файл script.lua без аргументов. (В данном случае $ – приглашение командной строки (терминала). Ваше приглашение командной строки может быть другим.)

Перед началом выполнения скрипта, lua собирает все аргументы командной строки в глобальную таблицу arg. Имя скрипта будет размещено по индексу 0, первый аргумент после имени скрипта – по индексу 1, и т.д. Все аргументы перед именем скрипта (т.е., имя интерпретатора и его опции) сохраняются с отрицательными индексами. Например, при вызове

     $ lua -la b.lua t1 t2

интерпретатор сначала запускает файл a.lua, затем создает таблицу

     arg = { [-2] = "lua", [-1] = "-la",
             [0] = "b.lua",
             [1] = "t1", [2] = "t2" }

и, наконец, запускает файл b.lua. Скрипт вызывается с аргументами arg[1], arg[2], ··· он может также получить доступ к этим аргументам при помощи выражения обработки переменного количества аргументов (vararg expression) '...'.

В интерактивном режиме, если вы вводите неполное выражение, интерпретатор ожидает его завершения изменяя вид входного приглашения.

Если глобальная переменная _PROMPT содержит строку, то ее значение используется в качестве входного приглашения. Аналогично, если глобальная переменная _PROMPT2 содержит строку, ее значение используется в качестве «вторичного» входного приглашения (используемого при вводе неполных выражений). Поэтому, оба приглашения могут быть изменены непосредственно из командной строки или из любых программах Lua, путем изменения _PROMPT. Смотрите следующий пример:

     $ lua -e"_PROMPT='myprompt> '" -i

(Внешняя пара кавычек необходима для корректной обработки команды оболочкой ОС, внутренняя пара - для Lua.) Обратите внимание на опцию -i, для установки интерактивного режима; в противном случае, программа бы тихо завершилась сразу после переназначения _PROMPT.

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

     #!/usr/local/bin/lua

(Конечно, местоположение интерпретатора Lua может изменяться. Если lua находится в каталоге, указанном в переменной окружения PATH, то

     #!/usr/bin/env lua

будет лучшим и более переносимым решением.)

7 - Несовместимости с предыдущей версией

Ниже представлен список несовместимостей, которые вы можете обнаружить при переходе с Lua 5.0 на Lua 5.1. Вы можете предотвратить большинство несовместимостей, перекомпилировав Lua с необходимыми опциями (см. файл luaconf.h). Однако, все опции обратной совместимости будут удалены в следующей версии Lua.

7.1 - Изменения в языке

  • Система переменного количества параметров изменена, вместо псевдо-аргумента arg, содержащего таблицу дополнительных параметров используется выражение переменного количества аргументов. (См. опцию компилятора LUA_COMPAT_VARARG в luaconf.h.)
  • Произошло небольшое изменение в использовании неявных переменных в операторах for и repeat.
  • Синтаксис длинной строки/длинного комментария ([[string]]) не разрешает вложения. Вы можете использовать новый синтаксис ([=[string]=]) в случае необходимости. (См. опцию компилятора LUA_COMPAT_LSTR в luaconf.h.)

7.2 - Изменения в библиотеках

  • Функция string.gfind была переименована в string.gmatch. (См. опцию компилятора LUA_COMPAT_GFIND в luaconf.h.)
  • Когда функция string.gsub вызывается с функцией в качестве третьего аргумента, и эта функция возвращает nil или false, то в качестве строки замены будет использоваться строка «полного совпадения», вместо пустой строки.
  • Функция table.setn была удалена. Функция table.getn соответствует новому оператору длины (#); используйте этот оператор вместо функции. (См. опцию компилятора LUA_COMPAT_GETN в luaconf.h.)
  • Функция loadlib была переименована в package.loadlib. (См. опцию компилятора LUA_COMPAT_LOADLIB в luaconf.h.)
  • Функция math.mod была переименована в math.fmod. (См. опцию компилятора LUA_COMPAT_MOD в luaconf.h.)
  • Функции table.foreach и table.foreachi удалены. Вы можете использовать цикл for loop с pairs или ipairs вместо них.
  • Проведены значительные изменения функции require из-за новой модульной системы. Однако новое поведение в основном совпадает с поведением функций старых версий, за тем исключением что параметр require получает путь из package.path вместо LUA_PATH.
  • Функция collectgarbage имеет другие аргументы. Функция gcinfo удалена; используйте collectgarbage("count") вместо нее.

7.3 - Изменения в API

  • Функции luaopen_* (для открытия библиотек) не могут быть вызваны напрямую (непосредственно), как стандартные функции C. Они должны вызываться через Lua, как функции Lua.
  • Функция lua_open была заменена на lua_newstate для того, чтобы дать возможность пользователю изменить функцию выделения памяти. Вы можете использовать luaL_newstate из стандартной библиотеки для создания состояния с использованием стандартной функции выделения памяти (основанной на realloc).
  • Функции luaL_getn и luaL_setn (из вспомогательной библиотеки) были удалены. Используйте lua_objlen вместо luaL_getn и ничего не используйте вместо luaL_setn.
  • Функция luaL_openlib была заменена на luaL_register.
  • Функция luaL_checkudata теперь возбуждает ошибку, если ее значение не является пользовательскими данными предполагаемого типа. (В Lua 5.0 она возвращала NULL.)

8 - Полный синтаксис Lua

Полный синтаксис Lua в расширенном BNF. (Не описывает приоритет операторов.)

    chunk ::= {stat [`;´]} [laststat [`;´]]

    block ::= chunk

    stat ::=  varlist `=´ explist |
         functioncall |
         do block end |
         while exp do block end |
         repeat block until exp |
         if exp then block {elseif exp then block} [else block] end |
         for Name `=´ exp `,´ exp [`,´ exp] do block end |
         for namelist in explist do block end |
         function funcname funcbody |
         local function Name funcbody |
         local namelist [`=´ explist]

    laststat ::= return [explist] | break

    funcname ::= Name {`.´ Name} [`:´ Name]

    varlist ::= var {`,´ var}

    var ::=  Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name

    namelist ::= Name {`,´ Name}

    explist ::= {exp `,´} exp

    exp ::=  nil | false | true | Number | String | `...´ | function |
         prefixexp | tableconstructor | exp binop exp | unop exp

    prefixexp ::= var | functioncall | `(´ exp `)´

    functioncall ::=  prefixexp args | prefixexp `:´ Name args

    args ::=  `(´ [explist] `)´ | tableconstructor | String

    function ::= function funcbody

    funcbody ::= `(´ [parlist] `)´ block end

    parlist ::= namelist [`,´ `...´] | `...´

    tableconstructor ::= `{´ [fieldlist] `}´

    fieldlist ::= field {fieldsep field} [fieldsep]

    field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp

    fieldsep ::= `,´ | `;´

    binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ |
         `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ |
         and | or

    unop ::= `-´ | not | `#´

Перевод ЗАО АИС@


Справочное руководство по языку Lua 5.1

Lua 5.1 - Справочное руководство

Copyright © 2006-2007 Lua.org, PUC-Rio. В свободном доступе в соответствии с Lua license.

Содержание

  • 1 - Введение

  • 2 - Описание языка
    • 2.1 - Лексические соглашения
    • 2.2 - Значения и типы
      • 2.2.1 - Приведение типов
    • 2.3 - Переменные
    • 2.4 - Операторы
      • 2.4.1 - Порции
      • 2.4.2 - Блоки
      • 2.4.3 - Присваивание
      • 2.4.4 - Управляющие конструкции
      • 2.4.5 - Оператор For
      • 2.4.6 - Вызов функции
      • 2.4.7 - Локальные объявления
    • 2.5 - Выражения
      • 2.5.1 - Арифметические операции
      • 2.5.2 - Операции сравнения
      • 2.5.3 - Логические операции
      • 2.5.4 - Конкатенация
      • 2.5.5 - Получение длины
      • 2.5.6 - Приоритет операций
      • 2.5.7 - Конструкторы таблиц
      • 2.5.8 - Вызовы функций
      • 2.5.9 - Объявление функций
    • 2.6 - Области видимости
    • 2.7 - Обработка ошибок
    • 2.8 - Метатаблицы
    • 2.9 - Окружение
    • 2.10 - Сборщик мусора
      • 2.10.1 - Метаметоды сборщика мусора
      • 2.10.2 - Таблицы "слабых" ссылок
    • 2.11 - Подпрограммы

  • 3 - Интерфейс программирования приложений (API)
    • 3.1 - Стек
    • 3.2 - Размер стека
    • 3.3 - Псевдо-индексы
    • 3.4 - C - включения
    • 3.5 - Реестр
    • 3.6 - Обработка ошибок в C
    • 3.7 - Функции и типы
    • 3.8 - Интерфейсы отладки

  • 4 - Вспомогательная библиотека
    • 4.1 - Функции и типы

  • 5 - Стандартные библиотеки
    • 5.1 - Базовые функции
    • 5.2 - Работа с подпрограммами
    • 5.3 - Модули
    • 5.4 - Работа со строками
      • 5.4.1 - Шаблоны
    • 5.5 - Обработка таблиц
    • 5.6 - Математические функции
    • 5.7 - Средства ввода-вывода
    • 5.8 - Функции операционной системы
    • 5.9 - Библиотека отладки

  • 6 - Интерпретатор языка Lua

  • 7 - Несовместимости с предыдущей версией
    • 7.1 - Изменения в языке
    • 7.2 - Изменения в библиотеках
    • 7.3 - Изменения в API

  • 8 - Полный синтаксис Lua

Индекс

Функции Lua

_G
_VERSION
assert
collectgarbage
dofile
error
getfenv
getmetatable
ipairs
load
loadfile
loadstring
module
next
pairs
pcall
print
rawequal
rawget
rawset
require
select
setfenv
setmetatable
tonumber
tostring
type
unpack
xpcall

coroutine.create
coroutine.resume
coroutine.running
coroutine.status
coroutine.wrap
coroutine.yield

debug.debug
debug.getfenv
debug.gethook
debug.getinfo
debug.getlocal
debug.getmetatable
debug.getregistry
debug.getupvalue
debug.setfenv
debug.sethook
debug.setlocal
debug.setmetatable
debug.setupvalue
debug.traceback

file:close
file:flush
file:lines
file:read
file:seek
file:setvbuf
file:write

io.close
io.flush
io.input
io.lines
io.open
io.output
io.popen
io.read
io.stderr
io.stdin
io.stdout
io.tmpfile
io.type
io.write

math.abs
math.acos
math.asin
math.atan
math.atan2
math.ceil
math.cos
math.cosh
math.deg
math.exp
math.floor
math.fmod
math.frexp
math.huge
math.ldexp
math.log
math.log10
math.max
math.min
math.modf
math.pi
math.pow
math.rad
math.random
math.randomseed
math.sin
math.sinh
math.sqrt
math.tan
math.tanh

os.clock
os.date
os.difftime
os.execute
os.exit
os.getenv
os.remove
os.rename
os.setlocale
os.time
os.tmpname

package.cpath
package.loaded
package.loaders
package.loadlib
package.path
package.preload
package.seeall

string.byte
string.char
string.dump
string.find
string.format
string.gmatch
string.gsub
string.len
string.lower
string.match
string.rep
string.reverse
string.sub
string.upper

table.concat
table.insert
table.maxn
table.remove
table.sort

C API

lua_Alloc
lua_CFunction
lua_Debug
lua_Hook
lua_Integer
lua_Number
lua_Reader
lua_State
lua_Writer

lua_atpanic
lua_call
lua_checkstack
lua_close
lua_concat
lua_cpcall
lua_createtable
lua_dump
lua_equal
lua_error
lua_gc
lua_getallocf
lua_getfenv
lua_getfield
lua_getglobal
lua_gethook
lua_gethookcount
lua_gethookmask
lua_getinfo
lua_getlocal
lua_getmetatable
lua_getstack
lua_gettable
lua_gettop
lua_getupvalue
lua_insert
lua_isboolean
lua_iscfunction
lua_isfunction
lua_islightuserdata
lua_isnil
lua_isnone
lua_isnoneornil
lua_isnumber
lua_isstring
lua_istable
lua_isthread
lua_isuserdata
lua_lessthan
lua_load
lua_newstate
lua_newtable
lua_newthread
lua_newuserdata
lua_next
lua_objlen
lua_pcall
lua_pop
lua_pushboolean
lua_pushcclosure
lua_pushcfunction
lua_pushfstring
lua_pushinteger
lua_pushlightuserdata
lua_pushlstring
lua_pushnil
lua_pushnumber
lua_pushstring
lua_pushthread
lua_pushvalue
lua_pushvfstring
lua_rawequal
lua_rawget
lua_rawgeti
lua_rawset
lua_rawseti
lua_register
lua_remove
lua_replace
lua_resume
lua_setallocf
lua_setfenv
lua_setfield
lua_setglobal
lua_sethook
lua_setlocal
lua_setmetatable
lua_settable
lua_settop
lua_setupvalue
lua_status
lua_toboolean
lua_tocfunction
lua_tointeger
lua_tolstring
lua_tonumber
lua_topointer
lua_tostring
lua_tothread
lua_touserdata
lua_type
lua_typename
lua_upvalueindex
lua_xmove
lua_yield

Вспомогательная библиотека

luaL_Buffer
luaL_Reg

luaL_addchar
luaL_addlstring
luaL_addsize
luaL_addstring
luaL_addvalue
luaL_argcheck
luaL_argerror
luaL_buffinit
luaL_callmeta
luaL_checkany
luaL_checkint
luaL_checkinteger
luaL_checklong
luaL_checklstring
luaL_checknumber
luaL_checkoption
luaL_checkstack
luaL_checkstring
luaL_checktype
luaL_checkudata
luaL_dofile
luaL_dostring
luaL_error
luaL_getmetafield
luaL_getmetatable
luaL_gsub
luaL_loadbuffer
luaL_loadfile
luaL_loadstring
luaL_newmetatable
luaL_newstate
luaL_openlibs
luaL_optint
luaL_optinteger
luaL_optlong
luaL_optlstring
luaL_optnumber
luaL_optstring
luaL_prepbuffer
luaL_pushresult
luaL_ref
luaL_register
luaL_typename
luaL_typerror
luaL_unref
luaL_where

Перевод ЗАО АИС@


Исходный текст перевода был взят на <http://www.lua.ru>
Работу "ЗАО АИС@" проделал немалую. Честь ему и хвала за это!

К сожалению, на мои письма это секретное учереждение мне не ответило, поэтому пришлось воспользоваться переводом без спроса.
При ближайшем рассмотрении оказалось что:
- документация разбита по главам на отдельные страницы,
- HTML файлы сильно замусорены лишними тегами (очевидно их правили Word-ом),
- многие перекрестные ссылки не работают,
- одна из глав ("5.4.1 - Шаблоны") - утеряна,
- похерены все индикаторы функций C API (похоже, что - умышленно),
- несколько небольших абзацев остались непереведенными.

Автоматически удалить обильный мусор из HTML файлов не получилось, поэтому пришлось утомительно править оригинальную документацию (взятую с <http://www.lua.org>) вручную.

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

Попутно корректировался перевод и исправлялись найденные ошибки.

Закончил перевод главы "2.1 - Лексические соглашения".

Полностью перевел главу "5.4.1 - Шаблоны".

Восстановил "5.3 - Модули" - "package.loaders"

Сгенерил оглавление и индекс для поиска по ключевым словам, откомпилил в CHM
вот, собственно, и все. Наслаждайтесь :)

------------------------------------------------------------------------
mozers™
<http://scite.ruteam.ru>
<icq #256106175>