RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
YandexMoney: 
41001198119846 
E-gold:
5128052

Глава 4. Язык LUA

Справочное руководство по языку программирования Lua 4.0

4.1 Введение

4.1.1 Что такое Lua?

Сайт языка Lua: http://www.tecgraf.puc-rio.br/lua.

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

Lua был предоставлен первый приз (технологическая категория) в Second Compaq Award for Research and Development in Computer Science в 1997. Это вознаграждение было объединенным предприятием Compaq Computer Brazil, the Brazilian Ministry of Science and Technology и the Brazilian Academy of Sciences.

Lua использовался во многих различных проектах во всем мире. Краткий перечень есть на http://www.tecgraf.puc-rio.br/lua/uses.html.

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

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

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

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

4.1.2 Доступность

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

  Базовые  http://www.tecgraf.puc-rio.br/lua
  сайты:   http://csg.uwaterloo.ca/~lhf/lua

  Зеркала:
  Brazil:  ftp://ftp.tecgraf.puc-rio.br/pub/lua/
  Canada:  ftp://csg.uwaterloo.ca/pub/lhf/lua/
  USA:     ftp://ftp.freesoftware.com/pub/languages/lua/
  Germany: ftp://ftp.uni-trier.de/pub/languages/lua/
  Germany: ftp://ftp.gwdg.de/pub/languages/lua/
  Greece:  ftp://ftp.ntua.gr/pub/lang/lua/
  Japan:   ftp://ftp.u-aizu.ac.jp/pub/lang/lua/
  Denmark: ftp://ftp.ucore.com/lua/dist

Lua распространяется свободно. Реализация, описанная в этом руководстве, доступна по адресам: http://www.tecgraf.puc-rio.br/lua и ftp://ftp.tecgraf.puc-rio.br/pub/lua.

4.1.3 Связь с авторами

Lua был разработан и выполнен Waldemar Celes, Roberto Ierusalimschy и Luiz Henrique de Figueiredo. С ними можно входить в контакт по e-mail lua@tecgraf.puc-rio.br.

Шлите Ваши комментарии, вопросы и отчеты об ошибках на lua@tecgraf.puc-rio.br. Для сообщений об ошибках попробуйте также список рассылки lua-l@tecgraf.puc-rio.br. Для получения большего количества информации относительно этого списка, включая инструкции о том, как на него подписаться, обратитесь на http://www.tecgraf.puc-rio.br/lua/lua-l.html.

Lua разработан в TeCGraf, the Computer Graphics Technology Group of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro in Brazil). TeCGraf является лабораторией отдела информатики. Множество индустриальных программ, разработанных в TeCGraf, используют Lua.

4.2 Среда и составные части

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

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

Глобальные переменные в Lua не должны быть объявлены. Любая переменная считается глобальной, пока не объявлена явно как локальная. Перед первым назначением, значение глобальной переменной nil (это значение по умолчанию может быть изменено, подробности в разделе 4.4.8). Таблица используется, чтобы хранить все глобальные имена и значения (таблицы объясняются в разделе 4.3).

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

chunk ::= {stat [`;']}
Инструкции описаны в разделе 4.4.4. Запись выше представляет собой обычный расширенный BNF, в котором {a} соответствует 0 или более объектов a [a] означает факультативный a, а (a)+ задает один или большее количество a. Полный синтаксис Lua дан в BNF.

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

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

4.3 Типы и тэги

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

Имеются шесть базисных типов в Lua: nil, number (число), string (строка), function (функция), userdata (пользовательские данные) и table (таблица). Nil тип значения nil, чье основное свойство должно отличаться от любого другого значения. Number представляет реальные (двойная точность с плавающей запятой) числа, в то время как string имеет обычное значение. Lua нормально понимает 8-разрядные символы, так что строки могут содержать любой 8-разрядный символ, включая вложенные нули ('\0'). Подробности в разделе 4.4.1. Функция type возвращает строку, описывающую тип данного значения (подробности в разделе 4.6.1).

Функции рассматриваются как значения первого класса (first-class values) в Lua. Это означает, что функции могут быть сохранены в переменных, переданы как параметры другим функциям и возвращены как результаты. Lua может вызывать и управлять как функциями, написанными на Lua, так и функциями, написанными на C. Два вида функций могут различаться их тэгами: все функции Lua имеют тот же самый тэг, и все функции C имеют свой тэг, который отличается от тэга функций Lua. Функция tag возвращает тэг данного значения (подробности в разделе 4.6.1).

Тип userdata обеспечивается, чтобы позволить произвольным C-указателям быть сохраненными в Lua-переменных. Этот тип соответствует void* и не имеет никаких предопределенных операций в Lua, за исключением теста равенства и назначения. Однако, используя методы тэгов, программист может определять операции для значений userdata. Подробности в разделе 4.4.8.

Тип table осуществляет ассоциативные массивы, то есть массивы, которые могут быть индексированы не только числами, а любыми значениями (за исключением nil). Следовательно, этот тип может использоваться не только, чтобы представить обычные массивы, но также и символные таблицы, наборы, записи, графы, деревья и т.д. Таблицы представляют собой основной механизм, структурирующий данные в Lua. Чтобы представлять записи (records), Lua использует имя поля как индекс. Язык поддерживает это представление, обеспечивая a.name как синтаксический аналог для a["name"]. Таблицы могут также нести методы: поскольку функции представляют собой значения первого класса, поля таблицы могут содержать функции. Форма t:f(x) синтаксический аналог для t.f(t,x), который вызывает метод f из таблицы t прохождением таблицы непосредственно как первый параметр (подробности в разделе 4.4.5.9).

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

Каждый из типов nil, number и string имеет свой тэг. Вообще, очень многое в Lua построено именно вокруг тэгов. Все значения каждого из этих типов имеют тот же самый предопределенный тэг. Как объяснено выше, значения типа function могут иметь два различных тэга в зависимости от того, являются ли они функциями Lua или функциями C. В заключение, значения типов userdata и table могут иметь переменные тэги, назначенные программистом (подробности в разделе 4.4.8). Функция tag возвращает тэг данного значения. Пользовательские тэги могут быть созданы функцией newtag. Функция settag используется, чтобы изменить тэг таблицы (подробности в разделе 4.6.1). Тэг значений userdata может быть установлен из C (подробности в разделе 4.5.7). Тэги главным образом используются, чтобы выбрать соответствующие методы тэгов, когда происходят некоторые события. Методы тэгов представляют собой основной механизм для распространения семантики Lua (подробности в разделе 4.4.8).

4.4 Язык

Этот раздел описывает лексику, синтаксис и семантику Lua.

4.4.1 Лексические соглашения в языке

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

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

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

Следующие строки обозначают другие лексемы (tokens):

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

Литеральные строки могут быть разграничены одиночными или двойными кавычками, и могут содержать C-подобные управляющие последовательности: \a (bell), \b (backspace), \f (form feed), \n (newline), \r (carriage return), \t (horizontal tab), \v (vertical tab), \\ (backslash), \" (double quote), \' (single quote), и \newline (то есть, наклонная черта влево, сопровождаемая реальным newline, который приводит к переводу строки). Символ в строке может также быть определен числовым значением, через управляющую последовательность \ddd, где ddd последовательность до трех десятичных цифр. Строки в Lua могут содержать любое 8-разрядное значение, включая вложенные нули, которые могут быть определены как \000.

Литеральные строки могут также быть разграничены парами [[ ... ]]. Литералы в этой форме в скобках могут занимать по несколько строк, содержать вложенные пары скобок [[ ... ]] и не интерпретировать управляющие последовательности. Эта форма особенно удобна для записи строк, которые содержат части программы или другие цитируемые строки. Как пример, в системе использующей ASCII-кодировку, следующие три литерала эквивалентны:

1)   "alo\n123\""
2)   '\97lo\10\04923"'
3)   [[alo
     123"]]

Комментарии начинаются с двойного тире (--) и выполняются до конца строки. Кроме того, первая строка составной части всегда пропущена, если начинается с символа #. Это средство позволяет использование Lua как интерпретатора скриптов в Unix-системах.

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

3     3.0     3.1416  314.16e-2   0.31416E1

4.4.2 Приведение

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

4.4.3 Корректировка

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

4.4.4 Инструкции

Lua поддерживает почти стандартный набор инструкций, подобных таким же наборам на Pascal или C. Стандартные команды включают присваивание, контроль выполнения и вызовы процедур. Нестандартные команды включают конструкторы таблицы и объявления локальных переменных.

4.4.4.1 Блоки

Блоком является список инструкций. Синтаксически блок равен составной части (chunk):
block ::= chunk

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

stat ::= do block end
Явные блоки полезны, чтобы управлять областью видимости (контекстом) локальных переменных. Явные блоки также иногда используются, чтобы добавить возврат или разрывать инструкцию в середине другого блока.

4.4.4.2 Присваивания

Lua поддерживает такую удобную вещь, как многократные присваивания. Следовательно, синтаксис определяет список переменных с левой стороны и список выражений с правой сторона. Элементы в обоих списках отделяются запятыми:
stat ::= varlist1 `=' explist1
varlist1 ::= var {`,' var}
Эта инструкция сначала оценивает все значения справа и возможные индексы слева, а затем делает примваивание. Так, код:
i = 3
i, a[i] = 4, 20
установит a[3] в 20, но не воздействует на a[4] потому, что i в a[i] оценен прежде, чем ему было присвоено значение 4. Многократное присваивание может использоваться, чтобы поменять местами два значения, например:
x, y = y, x

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

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

var ::= name

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

var ::= varorfunc `[' exp1 `]'
varorfunc ::= var | functioncall
varorfunc должен иметь в качестве результата значение из таблицы, где поле, индексированное значением выражения exp1, получает назначенное ему значение.

Синтаксис var.NAME представляет собой только синтаксический аналог для выражения var["NAME"]:

var ::= varorfunc `.' name

Значение присваиваний, оценок глобальных переменных и индексированных переменных может быть изменено методами тэгов. Фактически, назначение x=val, где x представляет собой глобальную переменную, является эквивалентным обращению setglobal("x",val), а присваивание t[i]=val эквивалентно settable_event(t,i,val). В разделе 4.4.8 есть полное описание этих функций (setglobal находится в базисной библиотеке, settable_event используется только для объяснительных целей).

4.4.4.3 Структуры управления

Структуры управления if, while и repeat имеют обычное значение и знакомый синтаксис:
stat ::= while exp1 do block end
stat ::= repeat block until exp1
stat ::= if exp1 then block {elseif exp1 then block} [else block] end
Выражение exp1 условия структуры управления может возвращать любое значение. Все значения, отличные от nil, рассматриваются как истина, только nil считается ложью.

Инструкция return используется, чтобы возвратить значения из функции или из chunk. Поскольку функции или составные части могут возвращать больше, чем одно значение, синтаксис для инструкции return:

stat ::= return [explist1]

Инструкция break может использоваться, чтобы завершить выполнение цикла, переходя к следующей инструкции сразу после цикла:

stat ::= break
break заканчивает самый внутренний вложенный цикл (while, repeat или for).

По синтаксическим причинам инструкции return и break могут быть написаны только как последние инструкции блока. Если действительно необходимо вставить их в середину, надо применить явный внутренний блок, например, do return end потому, что теперь return в самом деле последняя инструкция во внутреннем блоке.

4.4.4.4 Инструкция For

Инструкция for имеет две формы, по одной для чисел и таблиц. Числовая версия цикла for имеет следующий синтаксис:

stat ::= for name `=' exp1 `,' exp1 [`,' exp1] do block end
Инструкция for, подобная:
for var = 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
    block
    var = var+_step
  end
end
Обратите внимание на следующее:
  • sep=0pt
  • _limit и _step являются невидимыми переменными. Имена здесь даны только для объяснительных целей.
  • Поведение неопределено, если Вы меняете значение var внутри блока.
  • Если третье выражение (step) отсутствует, то используется step 1.
  • Значения limit и step оценены только однажды, перед стартом цикла.
  • Переменная var локальна для инструкции: Вы не можете использовать ее значение после окончания работы for.
  • Вы можете использовать break, чтобы выйти из for. Если Вы нуждаетесь в значении индекса, присвойте его другой переменной перед выходом.

Таблица для инструкции for пересекает все пары (index,value) данной таблицы. Это имеет следующий синтаксис:

stat ::= for name `,' name in exp1 do block end
Инструкция for, подобная:
for index, value in exp do block end
равносильна такому коду:
do
  local _t = exp
  local index, value = next(t, nil)
  while index do
    block
    index, value = next(t, index)
  end
end
Обратите внимание на следующее:
  • sep=0pt
  • _t является невидимомй переменномй. Имя здесь дано только для объяснительных целей.
  • Поведение неопределено, если Вы меняете значение index внутри блока.
  • Поведение неопределено, если Вы меняете таблицу _t при работе цикла.
  • Переменнае index и var локальны для инструкции: Вы не можете использовать их значения после окончания работы for.
  • Вы можете использовать break, чтобы выйти из for. Если Вы нуждаетесь в значениях index или value, присвойте их другим переменным перед выходом.
  • Порядок, в котором элементы таблицы будут пересечены, неопределен, даже для числовых индексов. Если Вы хотите пересекать индексы в числовом порядке, используйте числовой вариант for.

4.4.4.5 Обращения к функции как инструкции

Из-за возможных побочных эффектов, обращения к функции могут быть выполнены как инструкции:
stat ::= functioncall
В этом случае все возвращенные значения утрачены. Обращения к функции объясняются в разделе 4.4.5.8.

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

Локальные переменные могут быть объявлены где-нибудь внутри блока. Объявление может включать начальное присваивание:
stat ::= local declist [init]
declist ::= name {`,' name}
init ::= `=' explist1
Если представлено начальное назначение, то оно имеет ту же самую семантику многократного назначения. Иначе все переменные инициализированы nil.

Сhunk также блок, так что локальные переменные могут быть объявлены снаружи любого явного блока.

Область действия (контекст) локальных переменных начинается после объявления и продолжается до конца блока. Таким образом, код local print=print создает локальную переменную, названную print, чье начальное значение будет взято из глобальной переменной с тем же самым именем.

4.4.5 Выражения

4.4.5.1 Базисные выражения

Базисные выражения в Lua такие:

exp ::= `(' exp `)'
exp ::= nil
exp ::= number
exp ::= literal
exp ::= var
exp ::= upvalue
exp ::= function
exp ::= functioncall
exp ::= tableconstructor

Доступ к глобальной переменной x эквивалентен обращению getglobal("x"), а доступ к индексированной переменной t[i] эквивалентен обращению к gettable_event(t,i). Подробности в разделе 4.4.8, там есть описания этих функций (getglobal находится в базисной библиотеке).

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

exp1 ::= exp

4.4.5.2 Арифметические операторы

Lua поддерживает комплект обычных арифметических операторов: двоичный + (сложение), - (вычитание), * (умножение), / (деление), ^ (возведение в степень), а также унарный - (обращение знака числа). Если операнды числа или строки, которые могут быть преобразованы в числа, (согласно правилам, данным в разделе 4.4.2), то все операции за исключением возведения в степень имеют обычное значение. Иначе будет вызван соответствующий метод тэга. Возведение в степень всегда вызывает метод тэга. Стандартная математическая библиотека переопределяет этот метод для чисел, давая ожидаемое значение (подробности в разделе 4.6.3).

4.4.5.3 Реляционные операторы

Реляционные операторы в Lua:
==    ~=    <     >     <=    >=
Эти операторы возвращают nil как ложь, или любое другое значение (но не nil) в качестве истины.

Равенство (==) сначала сравнивает тэги операндов. Если они различны, то результатом будет nil. Иначе сравниваются их значения. Числа и строки сравниваются обычным способом. Таблицы, userdata, и функции сравниваются как ссылки, то есть две таблицы рассматриваются равными только, если они реально та же самая таблица. Оператор ~= прямо противоположен оператору равенства (==).

Правила преобразования из раздела 4.4.2 НЕ применяются к сравнениям равенства. Таким образом, "0"==0 вернет false, а t[0] и t["0"] обозначают различные записи в таблице.

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

4.4.5.4 Логические операторы

Логические операторы в Lua:
and   or   not
Подобно структурам управления, все логические операторы рассматривают nil как false (ложь), а все остальное как истину (true).

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

x = x or v
Которая является эквивалентной:
if x == nil then x = v end
Эта идиома устанавливает x к значению по умолчанию v, когда x не установлен.

Вторая идиома такая:

x = a and b or c
Которая должна читаться как x=(a and b) or c. Эта идиома эквивалентна:
if a then x = b else x = c end
При условии, что b не nil.

4.4.5.5 Объединения

Оператор объединения строк в Lua обозначен двумя точками (`..'). Если оба операнда строки или числа, они будут преобразованы в строки согласно правилам в разделе 4.2. Иначе будет вызван метод concat тэга.

4.4.5.6 Старшинство

Порядок старшинства в Lua следует из таблицы ниже. Операторы в ней перечислены в порядке от низкого к более высокому приоритету:
and   or
<     >     <=    >=    ~=    ==
..
+     -
*     /
not   - (unary)
^
Все двоичные операторы ассоциативны слева, кроме возведения в степень, который является ассоциативным справа. Прекомпилятор может перестраивать порядок оценки ассоциативных операторов (типа .. или +), пока эти оптимизация не изменяют нормальные результаты. Однако, эти оптимизация могут изменять некоторые результаты, если Вы определяете не ассоциативные методы тэгов для этих операторов.

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

Конструкторы таблиц представляют собой выражения, которые создают таблицы: каждый раз конструктор оценен, и новая таблица создана. Конструкторы могут использоваться, чтобы создать пустые таблицы или создать таблицу и инициализировать некоторые из полей (необязательно все). Общий синтаксис для конструкторов:
tableconstructor ::= `{' fieldlist `}'
fieldlist ::= lfieldlist|ffieldlist|lfieldlist `;'
              ffieldlist|ffieldlist `;' lfieldlist
lfieldlist ::= [lfieldlist1]
ffieldlist ::= [ffieldlist1]

Форма lfieldlist1 используется, чтобы инициализировать списки:

lfieldlist1 ::= exp {`,' exp} [`,']
Выражения в списке назначены последовательным числовым индексам, начиная с 1 (но не с 0!). Например, код:
a = {"v1", "v2", 34}
является эквивалентным коду:
do
  local temp = {}
  temp[1] = "v1"
  temp[2] = "v2"
  temp[3] = 34
  a = temp
end

Форма ffieldlist1 инициализирует другие поля в таблице:

ffieldlist1 ::= ffield {`,' ffield} [`,']
ffield ::= `[' exp `]' `=' exp | name `=' exp
Например такая запись:
a = {[f(k)] = g(y), x = 1, y = 3, [0] = b+c}
эквивалентна такому коду:
do
  local temp = {}
  temp[f(k)] = g(y)
  temp.x = 1    -- or temp["x"] = 1
  temp.y = 3    -- or temp["y"] = 3
  temp[0] = b+c
  a = temp
end
Выражения, подобные {x=1, y=4} фактически синтаксический аналог для выражения вида {["x"]=1, ["y"]=4}.

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

x = {;}
x = {"a", "b",}
x = {type="list"; "a", "b"}
x = {f(0), f(1), f(2),; n=3,}

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

Вызовы функций в Lua имеют синтаксис:
functioncall ::= varorfunc args
Сначала вычисляется varorfunc. Если значение имеет тип function, то эта функция будет вызвана с данными параметрами. Иначе вызывается метод function тэга, имея первым параметром значение varorfunc с перечисленными затем первоначальными параметрами обращения. Подробности в разделе 4.4.8.

Форма

functioncall ::= varorfunc `:' name args
Может использоваться, чтобы вызвать methods. Обращение v:name(...) синтаксически аналогично v.name(v, ...), за исключением того, что v будет оценен только однажды. Параметры имеют следующий синтаксис:
args ::= `(' [explist1] `)'
args ::= tableconstructor
args ::= literal
explist1 ::= {exp1 `,'} exp
Все выражения параметра оценены перед обращением. Обращение в форме f{...} синтаксически аналогично f({...}), то есть список параметров представляет собой одиночную новую таблицу. Обращение в форме f'...' (f"..." или f[[...]]) синтаксически аналогично f('...'), то есть список параметров представляет собой одиночную строку литералов.

Потому, что функция может возвращать любое число результатов, число результатов должно быть откорректировано прежде, чем они используются. Если функция вызвана как инструкция, то список возврата откорректирован к 0, таким образом отбрасывая все возвращенные значения. Если функция вызвана в месте, которое нуждается в одиночном значении (синтаксически обозначенном нетерминальным exp1), то список возврата откорректирован к 1, таким образом отбрасывая все возвращенные значения, но не первый. Если функция вызвана в месте, которое может использовать много значений (синтаксически обозначено нетерминальным exp), то никакая корректировка не будет сделана. Единственные места, которые могут обрабатывать много значений, это последние (или единственные) выражения в присваивании, в списке параметров или в инструкции return. Имеются примеры:

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

4.4.5.9 Определение функций

Синтаксис для определения функций такой:

function ::= function `(' [parlist1] `)' block end
stat ::= function funcname `(' [parlist1] `)' block end
funcname ::= name | name `.' name | name `:' name
Инструкция
function f () ... end
является только синтаксическим аналогом для
f = function () ... end
а инструкция
function v.f () ... end
является синтаксическим аналогом для
v.f = function () ... end

Функциональное определение представляет собой выполнимое выражение, чье значение имеет тип function. Когда Lua прекомпилирует chunk, все функциональные тела также прекомпилируются. Затем, всякий раз, когда Lua выполняет функциональное определение верхние переменные (upvalues) фиксируются, и функция выполняется. Этот функциональный образец (или замкнутое выражение) представляет собой конечное значение выражения. Различные образцы той же самой функции могут иметь различные верхние переменные.

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

parlist1 ::= `...'
parlist1 ::= name {`,' name} [`,' `...']
Когда функция вызвана, список параметров будет откорректирован к длине списка параметров, если функция не vararg-функция, которая обозначена тремя точками (`...') в конце списка параметра. Функция vararg не корректирует список параметров, вместо этого она собирает все лишние параметры в неявный параметр, названный arg. Значением arg является таблицы из n полей, чьим значением является число параметров дополнительного пространства и сами эти параметры, перечисленные в полях 1, 2, ..., n.

Как пример, рассмотрите следующие определения:

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, arg={n=0}
g(3, 4)          a=3, b=4, arg={n=0}
g(3, 4, 5, 8)    a=3, b=4, arg={5, 8; n=2}
g(5, r())        a=5, b=1, arg={2, 3; n=2}

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

Синтаксис

funcname ::= name `:' name
используется для определения методов, то есть функции, которые имеют неявный дополнительный параметр self .

Инструкция

function v:f (...) ... end
является только синтаксическим аналогом для
v.f = function (self, ...) ... end
Обратите внимание, что функция получает дополнительный формальный параметр self.

4.4.6 Зона видимости и Upvalues

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

upvalue ::= `%' name

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

Имеются некоторые примеры:

a,b,c = 1,2,3   -- глобальные переменные
local d
function f (x)
  local b = {}  -- x и b локальны для f, b затеняет глобальную b
  local g = function (a)
    local y     -- a и y локальны для g
    p = a       -- OK, доступ к локальной a
    p = c       -- OK, доступ к глобальной c
    p = b       -- ERROR: невозможен доступ к переменной вне зоны видимости
    p = %b      -- OK, доступ к замороженной b (локальная f)
    %b = 3      -- ERROR: нельзя менять upvalue
    %b.x = 3    -- OK, изменение содержимого таблицы
    p = %c      -- OK, доступ к замороженному значению глобальной c
    p = %y      -- ERROR: `y' невидима, где `g' определена
    p = %d      -- ERROR: `d' невидима, где `g' определена
  end           -- g
end             -- f

4.4.7 Обработка ошибок

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

Ошибки распределения памяти представляют собой исключительную ситуацию из предыдущего правила. Когда происходит сбой распределения памяти, Lua не может выполнить функцию _ERRORMESSAGE. Так что, для этого вида ошибки, Lua не вызывает функцию _ERRORMESSAGE. Вместо этого соответствующая функция из библиотеки немедленно завершится со специальным кодом ошибки (LUA_ERRMEM). Это и другие коды ошибки определено в заголовочном файле lua.h, подробности в разделе 4.5.8.

Единственный параметр _ERRORMESSAGE: строка, описывающая ошибку. Заданное по умолчанию определение для этого: обращение к функции _ALERT, которая печатает сообщение на stderr. Стандартная библиотека ввода-вывода переопределяет _ERRORMESSAGE и использует средства отладки, чтобы печатать некоторую дополнительную информацию, типа расположения обращений в стеке.

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

4.4.8 Методы тэгов

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

Метод тэга для некоего специфического события выбран согласно тэгу значения. Функция settagmethod изменяет метод тэга, связанный с данной парой (tag, event). Первый параметр представляет собой тэг, второй строку (имя события), а третий параметр (функция) задает новый метод или nil, чтобы восстановить заданное по умолчанию поведение для пары. Функция settagmethod возвращает предыдущий метод тэга для этой пары. Функция-компаньон gettagmethod получает тэг и имя события и возвращает текущий метод, связанный с парой.

Методы тэгов вызваны при соответствующих событиях, которые идентифицированы данными именами. Семантика методов лучше объяснена функцией Lua, описывающей поведение интерпретатора в каждом событии. Эта функция не только показывает, когда метод вызван, но также параметры, результаты и заданное по умолчанию поведение. Код, показанный здесь, только иллюстративен: реальное поведение сложно закодировано в интерпретаторе и намного более эффективно, чем это моделирование. Все функции, используемые в этих описаниях (rawget, tonumber, call и т.д.), описаны подробно в разделе 4.6.1.

``add'':
Вызван, когда операция + применяется к не числовым операндам.

Функция getbinmethod ниже определяет, как Lua выбирает метод для двоичной операции. Сначала Lua пробует первый операнд. Если тэг не определяет метод для операции, то Lua пробует второй операнд. Если это также терпит неудачу, то Lua получает метод из тэга 0.

function getbinmethod (op1, op2, event)
  return gettagmethod(tag(op1), event) or
         gettagmethod(tag(op2), event) or gettagmethod(0, event)
end
При использовании этой функции, метод события ``add'' такой:
function add_event (op1, op2)
  local o1, o2 = tonumber(op1), tonumber(op2)
  if o1 and o2 then  -- both operands are numeric
     return o1+o2  -- '+' here is the primitive 'add'
  else  -- at least one of the operands is not numeric
    local tm = getbinmethod(op1, op2, "add")
    if tm then
      -- call the method with both operands and an extra
      -- argument with the event name
      return tm(op1, op2, "add")
    else  -- no tag method available: default behavior
      error("unexpected type at arithmetic operation")
    end
  end
end

``sub'':
Вызван, когда операция - применяется к не числовым операндам. Поведение подобно событию ``add''.

``mul'':
Вызван, когда операция * применяется к не числовым операндам. Поведение подобно событию ``add''.

``div'':
Вызван, когда операция / применяется к не числовым операндам. Поведение подобно событию ``add''.

``pow'':
Вызван, когда операция ^ (возведение в степень) применяется к числовым операндам.
function pow_event (op1, op2)
  local tm = getbinmethod(op1, op2, "pow")
  if tm then
    -- call the method with both operands and an extra
    -- argument with the event name
    return tm(op1, op2, "pow")
  else  -- no tag method available: default behavior
    error("unexpected type at arithmetic operation")
  end
end

``unm'':
Вызван, когда одноместная операция - применяется к не числовому операнду.
function unm_event (op)
  local o = tonumber(op)
  if o then  -- operand is numeric
    return -o  -- '-' here is the primitive 'unm'
  else  -- the operand is not numeric.
    -- Try to get a tag method from the operand;
    --  if it does not have one, try a "global" one (tag 0)
    local tm = gettagmethod(tag(op), "unm") or
               gettagmethod(0, "unm")
    if tm then
      -- call the method with the operand, nil, and an extra
      -- argument with the event name
      return tm(op, nil, "unm")
    else  -- no tag method available: default behavior
      error("unexpected type at arithmetic operation")
    end
  end
end

``lt'':
Вызван, когда операция порядка применяется к не числовому или не строчному операнду. Это соответствует оператору <.
function lt_event (op1, op2)
  if type(op1) == "number" and type(op2) == "number" then
     return op1 < op2   -- numeric comparison
  elseif type(op1) == "string" and type(op2) == "string" then
    return op1 < op2   -- lexicographic comparison
  else local tm = getbinmethod(op1, op2, "lt")
    if tm then return tm(op1, op2, "lt")
    else error("unexpected type at comparison");
    end
  end
end
Другие операторы порядка используют этот метод согласно обычным эквивалентностям:
a>b    <=>  b<a
a<=b   <=>  not (b<a)
a>=b   <=>  not (a<b)
``concat'':
Вызван, когда конкатенация применяется к не строчным операндам.
function concat_event (op1, op2)
  if (type(op1) == "string" or type(op1) == "number") and
     (type(op2) == "string" or type(op2) == "number") then
     return op1..op2  -- primitive string concatenation
  else local tm = getbinmethod(op1, op2, "concat")
    if tm then return tm(op1, op2, "concat")
    else error("unexpected type for concatenation")
    end
  end
end

``index'':
Вызван, когда Lua пробует найти значение индекса, не представленного в таблице.

``getglobal'':
Вызван всякий раз, когда Lua нуждается в значении глобальной переменной. Этот метод может быть установлен только для nil и для тэгов, порожденных вызовом newtag. Обратите внимание, что тэг представляет собой текущее значение глобальной переменной.
function getglobal (varname)
  -- access the table of globals
  local value = rawget(globals(), varname)
  local tm = gettagmethod(tag(value), "getglobal")
  if not tm then return value
  else return tm(varname, value)
  end
end
Функция getglobal определена в базисной библиотеке.
``setglobal'':
Вызван всякий раз, когда Lua присваивает значение глобальной переменной. Этот метод не может быть установлен для чисел, строк, таблиц и userdata с заданным по умолчанию тэгом.
function setglobal (varname, newvalue)
  local oldvalue = rawget(globals(), varname)
  local tm = gettagmethod(tag(oldvalue), "setglobal")
  if not tm then rawset(globals(), varname, newvalue)
  else tm(varname, oldvalue, newvalue)
  end
end
Функция setglobal определена в базисной библиотеке.

``gettable'':
Вызван всякий раз, когда Lua обращается к индексированной переменной. Этот метод не может быть установлен для таблиц с заданным по умолчанию тэгом.
function gettable_event (table, index)
  local tm = gettagmethod(tag(table), "gettable")
  if tm then return tm(table, index)
  elseif type(table) ~= "table" then
    error("indexed expression not a table");
  else local v = rawget(table, index)
    tm = gettagmethod(tag(table), "index")
    if v == nil and tm then return tm(table, index)
    else return v
    end
  end
end

``settable'':
Вызван, когда Lua присваивает значение индексированной переменной. Этот метод не может быть установлен для таблиц с заданным по умолчанию тэгом.
function settable_event (table, index, value)
  local tm = gettagmethod(tag(table), "settable")
  if tm then tm(table, index, value)
  elseif type(table) ~= "table" then error("indexed expression not a table")
  else rawset(table, index, value)
  end
end

``function'':
Вызван, когда Lua пробует вызывать не функциональное значение.
function function_event (func, ...)
  if type(func) == "function" then return call(func, arg)
  else local tm = gettagmethod(tag(func), "function")
    if tm then for i=arg.n,1,-1 do arg[i+1] = arg[i]
      end
      arg.n = arg.n+1
      arg[1] = func
      return call(tm, arg)
    else error("call expression not a function")
    end
  end
end

``gc'':
Вызван, когда Lua начинает уборку мусора в userdata. Этот метод может быть установлен только из C, и не может быть установлен для userdata с заданным по умолчанию тэгом. Для каждого объекта userdata, который будет собран, Lua делает эквивалент следующей функции в цикле уборки мусора:
function gc_event (obj)
  local tm = gettagmethod(tag(obj), "gc")
  if tm then tm(obj)
  end
end
В цикле уборки мусора методы тэгов для userdata вызываются в порядке, обратном созданию тэгов, то есть первые методы, которые будут вызваны, связаны с последним тэгом, созданным в программе. Кроме того, в конце цикла Lua делает эквивалент обращения gc_event(nil).

4.5 API

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

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

4.5.1 Состояния

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

Перед вызовом любой функции API, Вы должны создать состояние вызовом:

lua_State *lua_open (int stacksize);
Единственный параметр этой функции: размер стека для интерпретатора. Каждое обращение к функции нуждается в одной позиции стека для каждого параметра, локальной переменной и временного значения, плюс по одной позиция для бухгалтерии. Стек должен также иметь приблизительно 20 позиций дополнительного пространства доступными. Для очень маленьких реализаций, без применения рекурсивных функций, размер стека в 100 должен быть достаточным. Если параметр stacksize равен 0, то используется заданный по умолчанию размер в 1024.

Чтобы освободить состояние, созданное lua_open, вызовите:

void lua_close (lua_State *L);
Эта функция уничтожает все объекты в данной среде Lua (вызывая соответствующие методы тэгов для уборки мусора, если они есть) и освобождает всю динамическую память, используемую этим состоянием. Обычно Вы не должны вызвать эту функцию потому, что все ресурсы естественно освобождены, когда Ваша программа заканчивается. С другой стороны, долго работающие программы должны бы освобождать ресурсы как только они становятся ненужными, чтобы не становиться слишком большими.

За исключением lua_open все функции в Lua API нуждаются в состоянии как в первом параметре.

4.5.2 Стек и индексы

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

Для удобства большинство операций запроса в API не следует за строгой дисциплиной стека. Вместо этого они могут обратиться к любому элементу в стеке, используя индекс: положительный индекс представляет абсолютную позицию стека (начиная с 1, а не с 0, как в C). Отрицательный индекс представляет смещение от верхней части стека. Более определенно, если стек имеет n элементов, индекс 1 представляет первый элемент (то есть, первый элемент, помещенный в стек), а индекс n представляет последний элемент. Индекс -1 также представляет последний элемент (то есть, элемент наверху), и индекс -n представляет первый элемент. Мы говорим, что индекс имеет силу, если он находится между 1 и верхней частью стека (то есть, если 1 <= abs(index) <= top).

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

int lua_gettop (lua_State *L);
Потому, что начало индексов в 1, результат lua_gettop равно числу элементов в стеке (0 стало быть означает пустой стек).

Когда Вы взаимодействуете с Lua API, Вы ответственны за контроль переполнения стека. Функция

int lua_stackspace (lua_State *L);
возвращает число доступных позиций стека. Всякий раз, когда Lua вызывается C, это гарантирует, что по крайней мере LUA_MINSTACK позиций все еще доступны. LUA_MINSTACK определен в файле заголовка lua.h и по крайней мере 16, так что Вы должны позаботиться о месте в стеке только, когда Ваш код имеет циклы, помещающие элементы в стек.

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

(index < 0 && abs(index) <= top) ||
(index > 0 && index <= top + stackspace)
Обратите внимание, что 0 не является приемлемым индексом.

4.5.3 Манипуляции со стеком

API предлагает следующие функции для базисного манипулирования стеком:
void lua_settop(lua_State *L, int index);
void lua_pushvalue(lua_State *L, int index);
void lua_remove(lua_State *L, int index);
void lua_insert(lua_State *L, int index);

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

#define lua_pop(L,n) lua_settop(L, -(n)-1)
выталкивает n элементов из стека.

lua_pushvalue помещает в стек копию элемента в данном индексе. lua_remove удаляет элемент в данной позиции, сдвигая элементы вверх от этой позиции, чтобы заполнить промежуток. lua_insert перемещает верхний элемент в данную позицию, сдвигая элементы вверх от позиции на открытое место. Эти функции принимают только имеющие силу индексы. Как пример, если стек хранит значения (снизу вверх) 10 20 30 40 50:

lua_pushvalue(L, 3)  --> 10 20 30 40 50 30
lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30
lua_remove(L, -3)    --> 10 20 30 40 30 30
lua_remove(L,  6)    --> 10 20 30 40 30
lua_insert(L,  1)    --> 30 10 20 30 40
lua_insert(L, -1)    --> 30 10 20 30 40  (никакого эффекта нет)
lua_settop(L, -3)    --> 30 10 20
lua_settop(L, 6)     --> 30 10 20 nil nil nil

4.5.4 Запросы к стеку

Чтобы проверять тип элемента стека, следующие функции доступны:

int lua_type(lua_State *L, int index);
int lua_tag(lua_State *L, int index);
int lua_isnil(lua_State *L, int index);
int lua_isnumber(lua_State *L, int index);
int lua_isstring(lua_State *L, int index);
int lua_istable(lua_State *L, int index);
int lua_isfunction(lua_State *L, int index);
int lua_iscfunction(lua_State *L, int index);
int lua_isuserdata(lua_State *L, int index);
Эти функции могут быть вызваны с любым приемлемым индексом.

lua_type возвращает одну из следующих констант, согласно типу данного объекта: LUA_TNIL, LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA. Если индекс не имеет силу (то есть, если та позиция стека пуста), то lua_type возвращает LUA_TNONE. Эти константы могут быть преобразованы в строки с помощью вызова:

const char *lua_typename(lua_State *L, int t);
здесь t представляет собой тип, возвращенный lua_type. Строки, возвращаемые lua_typename: "nil", "number", "string", "table", "function", "userdata" и "no value",

lua_tag возвращает тэг значения или LUA_NOTAG для не имеющего силу индекса.

Функция lua_is* возвращает 1, если объект совместим с данным типом, и 0 в противном случае. Всегда возвращается 0 для не имеющего силу индекса. lua_isnumber принимает числа и числовые строки. lua_isstring берет строки и числа и lua_isfunction воспринимает функции Lua и C. Чтобы различать между функциями Lua и функциями C, Вы должны использовать lua_iscfunction. Чтобы различать между числами и числовыми строками, Вы можете использовать lua_type.

API также имеет функции, чтобы сравнить два значения в стеке:

int lua_equal(lua_State *L, int index1, int index2);
int lua_lessthan(lua_State *L, int index1, int index2);
Эти функции эквивалентны их дубликатам в Lua. Определенно, lua_lessthan эквивалентна lt_event. Обе функции возвращают 0, если любой из индексов не имеет силу.

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

double  lua_tonumber(lua_State *L, int index);
const char *lua_tostring(lua_State *L, int index);
size_t lua_strlen(lua_State *L, int index);
lua_CFunction lua_tocfunction(lua_State *L, int index);
void *lua_touserdata(lua_State *L, int index);
Эти функции могут быть вызваны с любым приемлемым индексом. Когда вызваны с не имеющим силу индексом, они действуют так, как будто переданное им значение имело неправильный тип.

lua_tonumber преобразовывает значение в данном индексе к числу с плавающей запятой. Это значение должно быть числом или строкой, обратимой в число (подробности в разделе 4.2). Иначе lua_tonumber возвращает 0.

lua_tostring преобразовывает значение Lua в строку (const char*). Это значение должно быть числом или строкой, иначе будет возвращен NULL. Эта функция возвращает указатель на строку внутри Lua-среды. Эти строки всегда имеют ноль ('\0') после их последнего символа (как в C), но могут содержать другие ноли в их теле. Если Вы не знаете, может ли строка содержать ноли, Вы должны использовать lua_strlen, чтобы получить фактическую длину. Потому, что Lua имеет мусороуборщик, не имеется никакой гарантии, что указатель, возвращенный lua_tostring, будет иметь силу после того, как соответствующее значение удалено из стека.

lua_tocfunction преобразовывает значение в стеке к функции C. Это значение должно быть функцией C, иначе lua_tocfunction возвращает NULL. Тип lua_CFunction рассмотрен более подробно в отдельном разделе 5.13.

lua_touserdata преобразовывает значение в void*. Это значение должно иметь тип userdata, иначе lua_touserdata вернет NULL.

4.5.5 Помещение значений в стек

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

void lua_pushnumber(lua_State *L, double n);
void lua_pushlstring(lua_State *L, const char *s, size_t len);
void lua_pushstring(lua_State *L, const char *s);
void lua_pushusertag(lua_State *L, void *u, int tag);
void lua_pushnil(lua_State *L);
void lua_pushcfunction(lua_State *L, lua_CFunction f);
Эти функции получают значение C, преобразовывают его в соответствующее значение Lua, и помещают результат в стек. В частности, lua_pushlstring и lua_pushstring делают внутреннюю копию данной строки. lua_pushstring может использоваться только, чтобы поместить соответствующие C-строки (то есть, такие строки, которые заканчиваются нолем и не содержат вложенные ноли), иначе Вы должны использовать более общую функцию lua_pushlstring, которая принимает явный размер данных.

4.5.6 Уборка мусора

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

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

int lua_getgccount (lua_State *L);
int lua_getgcthreshold (lua_State *L);
Оба возвращают их соответствующие значения в килобайтах. Вы можете изменять пороговое значение с помощью:
void  lua_setgcthreshold (lua_State *L, int newthreshold);
Снова значение newthreshold задано в килобайтах. Когда Вы вызываете эту функцию, Lua устанавливает новый порог и проверяет счетчик байтов. Если новый порог меньше, чем счетчик байтов, то Lua немедленно выполняет уборку мусора. После нее новый порог будет установлен согласно предыдущему правилу.

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

4.5.7 Userdata и тэги

Поскольку userdata представляют собой объекты, функция lua_pushusertag может создавать новые userdata. Если Lua имеет userdata с данным значением (void*) и тэг, то этот объект размещен. Иначе создается новый userdata с данным значением и тэгом. Если эта функция вызвана с тэгом, равным LUA_ANYTAG , то Lua пробует находить любой объект userdata с данным значением, независимо от его тэга. Если не имеется никакого userdata с этим значением, то новый объект будет создан с тэгом, равным 0.

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

int lua_newtag (lua_State *L);
Функция lua_settag меняет тэг объекта в верхней части стека (без того, чтобы получить его):
void lua_settag (lua_State *L, int tag);
Объект должен быть userdata или таблицей, данный тэг должен быть значением, созданным с помощью функции lua_newtag.

4.5.8 Выполнение Lua-кода

Ведущая программа может выполнять Lua-chunk, записанные в файле или в строке, используя следующие функции:
int lua_dofile(lua_State *L, const char *filename);
int lua_dostring(lua_State *L, const char *string);
int lua_dobuffer(lua_State *L, const char *buff, size_t size,
                 const char *name);
Эти функции возвращают 0 в случае успеха, или один из следующих кодов ошибки, если они терпят неудачу:
  • LUA_ERRRUN: ошибка при управлении chunk.
  • LUA_ERRSYNTAX: ошибка синтаксиса в течение прекомпиляции.
  • LUA_ERRMEM: ошибка распределения памяти. Для таких ошибок, Lua не вызывает _ERRORMESSAGE (подробности в разделе 4.4.7).
  • LUA_ERRERR: ошибка при управлении _ERRORMESSAGE. Для таких ошибок Lua не вызывает _ERRORMESSAGE снова, чтобы избежать циклов.
  • LUA_ERRFILE: ошибка открытия файла (только для lua_dofile). В этом случае Вы можете проверять errno, вызывая strerror или perror, чтобы сообщить пользователю, что пошло неправильно.
Эти константы определены в lua.h.

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

Третий параметр для lua_dobuffer задает имя chunk, который используется сообщениях об ошибках и отладочных сообщениях. Если имя name равно NULL, то Lua дает заданное по умолчанию имя этому chunk.

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

{
  int oldtop = lua_gettop(L);
  lua_dofile(L, filename);
  lua_settop(L, oldtop);
}

4.5.9 Управление глобальными переменными в Lua

Чтобы прочитать значение глобальной переменной Lua, надо:

void lua_getglobal (lua_State *L, const char *varname);
Это помещает в стек значение данной переменной. Как в Lua эта функция может вызывать метод тэга для события getglobal. Чтобы читать реальное значение глобальной переменной без того, чтобы вызывать любой метод тэга, используют lua_rawget над таблицей глобальных переменных.

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

void lua_setglobal (lua_State *L, const char *varname);
Это извлекает из стека значение, которое будет сохранено в данной переменной. Как в Lua эта функция может вызывать метод тэга для события setglobal. Чтобы устанавливать реальное значение глобальной переменной без того, чтобы вызывать любой метод тэга, используют lua_rawset над таблицей глобальных переменных (подробности приведены ниже).

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

void lua_getglobals (lua_State *L);
Это помещает текущую (актуальную) таблицу глобальных переменных в стек. Чтобы устанавливать другую таблицу глобальных переменных, используйте вызов:
void lua_setglobals (lua_State *L);
Таблица, которую нужно использовать, извлекается из стека.

4.5.10 Управление таблицами в Lua

Lua-таблицы могут также управляться через API.

Чтобы читать значение в таблице, таблица должна находиться где-нибудь в стеке. Теперь вызовите

void lua_gettable (lua_State *L, int index);
где index относится к таблице. lua_gettable извлекает ключ из стека и возвращает (через стек) содержание таблицы для заданного ключа. Как в Lua эта операция может вызывать метод тэга для события gettable. Получать реальное значение любого ключа таблицы, без того, чтобы вызывать любой метод тэга, можно, используя
void lua_rawget (lua_State *L, int index);

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

void lua_settable (lua_State *L, int index);
здесь index относится к таблице. lua_settable извлекает из стека ключ и значение. Как и все в Lua, эта операция может вызывать метод тэга для события settable. Чтобы устанавливать реальное значение любого индекса таблицы без того, чтобы вызывать любой метод тэга, используют raw-версию:
void lua_rawset (lua_State *L, int index);

В заключение, еще одна функция

void lua_newtable (lua_State *L);
создает новую, пустую, таблицу и помещает ее в стек.

4.5.11 Использование таблиц как массивов

API имеет функции, которые помогают использовать таблицы Lua как массивы, то есть таблицы, индексированные только числами:
void lua_rawgeti(lua_State *L, int index, int n);
void lua_rawseti(lua_State *L, int index, int n);
int lua_getn(lua_State *L, int index);

lua_rawgeti получает значение энного элемента таблицы в позиции index стека.

lua_rawseti устанавливает значение энного элемента таблицы в позиции index стека к значению наверху стека.

lua_getn возвращает число элементов в таблице в позиции index. Это число представляет собой значение поля n таблицы, если это имеет числовое значение, или самый большой числовой индекс со значением non-nil в таблице.

4.5.12 Вызов функций Lua

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

int lua_call (lua_State *L, int nargs, int nresults);
Эта функция возвращает те же самые коды ошибки, что и lua_dostring и другие (подробности в разделе 4.5.8). Если Вы хотите исследовать ошибку, вместо того, чтобы возвратить код ошибки, используйте:
void lua_rawcall(lua_State *L, int nargs, int nresults);

В обеих функциях nargs задает число параметров, которые Вы поместили в стек. Все параметры и функциональное значение берутся из стека, а функциональные результаты помещены туда. Число результатов будет откорректировано до nresults, если nresults не LUA_MULTRET. В этом случае все результаты функции будут помещены в стек. Функциональные результаты помещены в прямом порядке (первый результат и помещен первым), чтобы после обращения последний результат оказался на самой вершине стека.

Следующий пример показывает, как ведущая программа может делать эквивалент коду на Lua:

a,b = f("how", t.x, 4)
Here it is in C:
lua_getglobal(L, "t");    /* глобальная `t' (потом пригодится) */
lua_getglobal(L, "f");    /* функция, которая будет вызвана */
lua_pushstring(L, "how"); /* 1-ый параметр */
lua_pushstring(L, "x");   /* помещает в стек строку `x' */
lua_gettable(L, -4);      /* помещает в стек результат t.x (2-ой аргумент) */
lua_pushnumber(L, 4);     /* 3-ий параметр */
lua_call(L, 3, 2);    /* вызывает функцию с 3 параметрами и 2 результатами */
lua_setglobal(L, "b");    /* устанавливает глобальную переменную `b' */
lua_setglobal(L, "a");    /* устанавливает глобальную переменную `a' */
lua_pop(L, 1);            /* удаляет из стека `t' */
Обратите внимание, что код выше сбалансированный: в конце стек обратен к первоначальной конфигурации. Это считается хорошей практикой.

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

void lua_error (lua_State *L, const char *message);
Эта функция никогда не возвращает ничего. Если lua_error вызвана из функции C, которая была вызвана из Lua, то соответствующий блок кода Lua завершается так, как будто ошибка произошла внутри кода Lua. Иначе вся ведущая программа завершается обращением exit(EXIT_FAILURE). Перед завершением выполнения, сообщение message будет передано функции драйвера ошибки _ERRORMESSAGE. Если message равно NULL, то _ERRORMESSAGE не вызывается.

Методы тэгов могут быть изменены с

void lua_settagmethod (lua_State *L, int tag, const char *event);
Второй параметр задает тэг, а третий представляет собой имя события. Новый метод берется из стека. Чтобы получить текущее (актуальное) значение метода тэга используйте функцию
void lua_gettagmethod(lua_State *L, int tag, const char *event);

Также возможно копировать все методы из одного тэга в другой:

int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
Эта функция вернет tagto.

Вы можете пересекать таблицу с функцией:

int lua_next (lua_State *L, int index);
здесь index относится к таблице, которая будет пересечена. Функция берет ключ из стека и помещает туда пару "значение-ключ" из таблицы (следующую после данного ключа). Если не имеется больше элементов, то функция возвращает 0 (и не помещает в стек ничего). Типичный пример использования выглядит следующим образом:
lua_pushnil(L);  /* first key */
while (lua_next(L, t) != 0) {
  /* `key' is 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)));
  lua_pop(L, 1);  /* removes `value'; keeps `index' for next iteration */
}

Функция

void lua_concat (lua_State *L, int n);
конкатенирует n значений сверху стека, извлекает их и оставляет результат наверху. Здесь n должно быть по крайней мере равно 2. Конкатенация выполнена по правилам обычной семантики Lua

4.5.13 Определение функций C

Чтобы зарегистрировать функцию C в Lua, имеется следующая макрокоманда:
#define lua_register(L, n, f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
/* const char *n;   */
/* lua_CFunction f; */
Которая получает имя, которое функция будет иметь в Lua, и указатель на функцию. Этот указатель должен иметь тип lua_CFunction, который определен так;
typedef int (*lua_CFunction) (lua_State *L);
То есть, это указатель на функцию с целочисленным результатом и одиночным параметром, Lua-средой.

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

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

static int foo (lua_State *L) {
  int n = lua_gettop(L);    /* number of arguments */
  double sum = 0;
  int i;

  for (i = 1; i <= n; i++) {
    if (!lua_isnumber(L, i))
       lua_error(L, "incorrect argument to function `average'");
    sum += lua_tonumber(L, i);
  }
  lua_pushnumber(L, sum/n);   /* первый результат */
  lua_pushnumber(L, sum);     /* второй результат */
  return 2;                   /* сколько всего результатов */
}
Эта функция может быть зарегистрирована в Lua как average таким вызовом:
lua_register(L, "average", foo);

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

void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
используется, чтобы поместить функцию C в стек с параметром n означающим, сколько upvalues должно быть связан с функцией (эти upvalues берутся из стека). Фактически, макрокоманда lua_pushcfunction определена как lua_pushcclosure с n установленным в 0. Затем, всякий раз, когда функция C вызвана, эти upvalues вставлены как последние параметры функции, после фактических параметров, переданных в обращении. Это избавляет от необходимости выяснять, сколько параметров было передано фактически. Так i-th upvalue находится в стеке в индексе i-(n+1), где n задает номер upvalues.

Для большего количества примеров функций C и замкнутых выражений изучите файлы lbaselib.c, liolib.c, lmathlib.c и lstrlib.c в дистрибутиве Lua.

4.5.14 Ссылки к Lua-объектам

Если C-код должен хранить значение Lua вне продолжительности жизни функции C, то надо создать ссылку к значению. Функции, чтобы управлять ссылками, следующие:

int lua_ref(lua_State *L, int lock);
int lua_getref(lua_State *L, int ref);
void lua_unref(lua_State *L, int ref);

lua_ref выталкивает значение из стека, создает ссылку к нему и возвращает эту ссылку. Для значения nil ссылка всегда LUA_REFNIL. lua.h также определяет константу LUA_NOREF, которая отличается от любой имеющей силу ссылки. Если lock не равно 0, то объект блокирован: это означает, что объект не будет обработан мусоросборщиком. Разблокированные ссылки могут быть удалены в порядке уборки мусора на общих основаниях.

Всякий раз, когда вызванный объект необходим в C, обращение к lua_getref помещает тот объект в стек; если объект был убран, lua_getref вернет 0 (и не поместит ничего в стек).

Когда ссылка больше не нужна, ее надо освободить вызовом lua_unref.

4.5.15 Системный реестр

При своем запуске Lua регистрируют таблицу в позиции LUA_REFREGISTRY. К этому можно обращаться через макрокоманду:

#define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY)
Эта таблица может использоваться C-библиотеками как общий механизм системного реестра. Любая C-библиотека может сохранять данные в этой таблице, пока она выбирает ключ регистрации, отличный от других библиотек.

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

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

  • Базисная библиотека.
  • Работа со строками.
  • Различная математика (sin, log и т,п,).
  • Ввод и вывод (плюс некоторые средства системы).
Чтобы иметь доступ к этим библиотекам, ведущая C-программа должна вызвать функции lua_baselibopen, lua_strlibopen, lua_mathlibopen и lua_iolibopen, которые объявлены в файле заголовков lualib.h.

4.6.1 Базисные функции

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

_ALERT (message)

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

assert (v [, message])

Выдает ошибку assertion failed!, когда параметр v равен nil. Эта функция эквивалентна следующей функции Lua:
function assert(v, m)
  if not v then m = m or ""
     error("assertion failed!  " .. m)
  end
end

call (func, arg [, mode [, errhandler]])

Вызывает функцию func с параметрами, заданными таблицей arg. Обращение эквивалентно
func(arg[1], arg[2], ..., arg[n])
где n представляет собой результат getn(arg). Все результаты из func просто возвращены call.

По умолчанию, если ошибка происходит в течение обращения к func, она объясняется подробно. Если строка mode включает "x", то обращение защищено. В этом режиме обращение к функции не call не объясняет ошибку подробно, независимо от того, что случается в течение обращения. Вместо этого, это возвращает nil, чтобы сообщить об ошибке (помимо вызова приспособленного драйвера ошибки).

Если errhandler обеспечивается, функция ошибки _ERRORMESSAGE временно установлена к errhandler на время выполнения func. В частности, если errhandler равен nil, никакие сообщения об ошибках не будут выданы в течение выполнения вызванной функции вообще.

collectgarbage ([limit])

Устанавливает порог для мусоросборщика в данное значение (в Kbytes). Если новый порог меньше, чем счетчик байтов, то Lua немедленно выполняет уборку мусора в памяти. Если limit отсутствует, значением по умолчанию является ноль (таким образом уборка мусора запустится сразу).

copytagmethods (tagto, tagfrom)

Копирует все методы тэга из одного тэга в другой, возвращает tagto.

dofile (filename)

Получает имя файла, открывает именованный файл и выполняет его содержимое как Lua-код или как прекомпилируемый код. Когда вызвано без параметров, dofile выполняет содержание стандартного ввода (stdin). Если имеется любая ошибка, dofile вернет nil. Иначе это возвращает значения, возвращенные кодом, или значение не-nil, если блок кода не возвращает никаких значений. Это выдает ошибку, когда вызвано не со строчным параметром.

dostring (string [, chunkname])

Выполняет данную строку как код на Lua. Если имеется любая ошибка, то dostring вернет nil. Иначе это возвращает значения, возвращенные кодом, или значение не-nil, если код не возвращает никакие значения. Факультативный параметр chunkname имя кода, используемого для информации об ошибках и отладочных сообщений.

error (message)

Вызывает драйвер ошибки и затем завершает последнюю защищенную вызванную функцию (в C: lua_dofile, lua_dostring, lua_dobuffer или lua_callfunction, в Lua: dofile, dostring или call в защищенном режим). Если message равно nil, то драйвер ошибки не будет вызван. Функция error никогда ничего не возвращает.

foreach (table, func)

Выполняется данную func над всеми элементами таблицы table. Для каждого элемента, функция вызвана с индексом и соответствующим значением как параметрами. Если функция возвращает любое значение не-nil, то цикл завершается, и это значение будет возвращено как конечное значение foreach. Эта функция могла бы быть определена в Lua так:
function foreach (t, f)
  for i, v in t do
    local res = f(i, v)
    if res then return res end
  end
end
Поведение foreach неопределено, если Вы изменяете таблицу t в ходе работ.

foreachi (table, func)

Выполняет данную func над числовыми индексами таблицы table. Для каждого индекса функция вызвана с индексом и соответствующим значением как параметрами. Индексы обрабатываются в последовательном порядке, от 1 до n, где n представляет собой результат getn(table). Если функция возвращает любое значение не-nil, то цикл прерывается, а это значение будет возвращено как конечное значение foreachi. Эта функция могла бы быть определена в Lua таким образом:
function foreachi (t, f)
  for i=1,getn(t) do
    local res = f(i, t[i])
    if res then return res end
  end
end

getglobal (name)

Получает значение глобальной переменной или вызывает метод тэга для события getglobal. Полная семантика объясняется в разделе 4.4.8 . Строка name задает имя переменной.

getn (table)

Возвращает размер таблицы, представленной как список. Если таблица имеет n полей с числовым значением, это количество и будет размером таблицы. Иначе размером является самый большой числовой индекс со значением не-nil в таблице. Эта функция могла бы быть определена в Lua так:
function getn (t)
  if type(t.n) == "number" then return t.n end
  local max = 0
  for i, _ in t do
    if type(i) == "number" and i>max then max=i end
  end
  return max
end

gettagmethod (tag, event)

Возвращает текущий метод тэга для данной пары (tag, event). Эта функция не может использоваться, чтобы получить метод тэга для события gc. Такие методы тэга могут управляться только C-кодом.

globals ([table])

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

newtag ()

Возвращает новый тэг.

next (table, [index])

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

Lua не имеет никакого объявления полей: семантически не имеется никакого различия между полем, не представленным в таблице, или полем со значением nil. Следовательно, next рассматривает только поля со значениями не-nil. Порядок, в котором индексы перечислены, не определен даже для числовых индексов. Чтобы обработать таблицу в числовом порядке, надо использовать функцию foreachi.

Поведение next неопределено, если Вы изменяете таблицу в ходе работ.

print (e1, e2, ...)

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

rawget (table, index)

Получает реальное значение table[index] без того, чтобы вызвать любой метод тэга. Таблица должна быть задана как table, а index представляет собой любое значение, отличное от nil.

rawset (table, index, value)

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

setglobal (name, value)

Устанавливает именованную глобальную переменную к данному значению, или вызывает метод тэга для события setglobal. Полная семантика объясняется в разделе 4.8.

settag (t, tag)

Устанавливает тэг данной таблицы. Тэг (tag) должен быть значением, созданным через newtag. settag вернет значение первого параметра (таблицу). Для безопасности ведущих программ невозможно изменить тэг userdata прямо из Lua.

settagmethod (tag, event, newmethod)

Устанавливает новый метод тэга к данной паре (tag, event) и возвращает старый метод. Если newmethod равно nil, то settagmethod восстанавливает заданное по умолчанию поведение для данного события. Эта функция не может использоваться, чтобы установить метод для события gc. Такие методы могут управляться только C-кодом.

sort(table [, comp])

Сортирует элементы таблицы в данном порядке, данные берутся из table[1] и помещаются в table[n], где n представляет собой результат getn(table). Если comp задан, то это должно быть функцией, которая получает два элемента таблицы и возвращает истину (то есть значение, отличное от nil), когда первый меньше, чем второй (так, чтобы not comp(a[i+1], a[i]) был истиной после сортировки). Если comp не задано, то вместо этого используется стандартный оператор < языка Lua.

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

tag (v)

Позволяет программам Lua проверять тэг значения. Это получает один параметр и возвращает тэг (число).

tonumber (e [, base])

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

Факультативный параметр определяет ядро, чтобы интерпретировать цифру. Ядром может быть любое целое число между 2 и 36 включительно. В базах более, чем 10, символ A (заглавные или строчные буквы) представляет 10, B соответствует 11 и так далее до символа Z, соответствующему 35. В ядре 10 (значение по умолчанию) число может иметь десятичную часть, также как и факультативную часть экспоненты. В других базах только целые числа без знака.

tostring (e)

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

tinsert (table [, pos] , value)

Вставляет значение элемента value в позицию pos таблицы, сдвигая другие элементы в случае необходимости на открытое место. Значение по умолчанию для pos равно n+1, где n является результатом getn(table) так, чтобы обращение tinsert(t,x) вставило x в конец таблицы t. Эта функция также устанавливает или увеличивает поле n таблицы, превращая его в n+1. Эта функция эквивалентна следующей функции Lua, за исключением того, что доступ к таблице прямой (без методов тэгов):

function tinsert (t, ...)
  local pos, value
  local n = getn(t)
  if arg.n == 1 then pos, value = n+1, arg[1]
  else pos, value = arg[1], arg[2]
  end
  t.n = n+1;
  for i=n,pos,-1 do
    t[i+1] = t[i]
  end
  t[pos] = value
end

tremove (table [, pos])

Удаляет из таблицы table элемент в позиции pos, сдвигая в случае необходимости другие элементы, чтобы закрыть образовавшуюся дырку. Возвращает значение удаленного элемента. Значение по умолчанию для pos равно n, где n является результатом getn(table), чтобы обращение tremove(t) удалило последний элемент из таблицы t. Эта функция также устанавливает поле n таблицы в значение n-1.

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

function tremove (t, pos)
  local n = getn(t)
  if n<=0 then
     return
  end
  pos = pos or n
  local value = t[pos]
  for i=pos,n-1 do
    t[i] = t[i+1]
  end
  t[n] = nil
  t.n = n-1
  return value
end

type (v)

Позволяет программам Lua проверять тип значения. Это получает один параметр, а возвращает тип, кодированный как строка. Возможные результаты этой функции: "nil" (строка, а не значение nil!), "number", "string", "table", "function" и "userdata".

4.6.2 Строковые манипуляции в Lua

Эта библиотека обеспечивает универсальные функции для манипулирования строками, типа нахождения и извлечения соответствия образца и подстрок. При индексации строки в Lua, первый символ находится в позиции 1 (не в 0, как в C!). Также, индексам позволено быть отрицательными, что понимается как индексация в обратном направлении, с конца строка к началу. Таким образом, последний символ находится в позиции -1 и так далее.

strbyte (s [, i])

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

Числовые коды не обязательно переносимы между платформами.

strchar (i1, i2, ...)

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

Числовые коды не обязательно переносимы между платформами.

strfind (s, pattern [, init [, plain]])

Ищет первое соответствие образцу pattern в s. Если это найдено, strfind вернет индексы s, где эти вхождения начинаются и заканчивается, иначе это возвращает nil. Если образец определяет набор данных (подробности в описании gsub ниже), зафиксированные строки возвращены как дополнительные результаты. Факультативный числовой параметр init определяет, где запустить поиск: значение по умолчанию 1, и оно может быть отрицательным. Четвертый факультативный аргумент plain выключает средства поиска образца, так что функция просто ищет подстроку без символов в pattern, обрабатываемых особым образом. Обратите внимание, что если задана опция plain, должна быть задана и init.

strlen (s)

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

strlower (s)

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

strrep (s, n)

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

strsub (s, i [, j])

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

strupper (s)

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

format (formatstring, e1, e2, ...)

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

Преобразования могут применяться к энному параметру в списке параметров вместо следующего неиспользуемого параметра. В этом случае символ % заменен последовательностью %d$, где d десятичная цифра в диапазоне [1,9], определяет позицию параметра в списке. Например, обращение format("%2$d -> %1$03d", 1, 34) выдаст результат "34 -> 001". Тот же самый параметр может использоваться больше, чем в одном преобразовании.

Опции c, d, E, e, f, g, G, i, o, u, X и x все ожидают число как параметр, в то время как q и s ожидают строку. Модификатор * может применяться, формируя соответствующую строку формата. Например, "%*g" может соответствовать "%"...что-то-внутри..."g".

Ни строка формата, ни значения строки, которые нужно форматировать с %s, не могут содержать вложенные ноли. Но %q обрабатывает значения строк с вложенными нолями.

gsub (s, pat, repl [, n])

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

Если repl является строкой, то значение используется для замены как есть. Любая последовательность в repl в форме %n с n от 1 до 9 предназначена для n-й зафиксированной подстроки.

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

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

Имеются некоторые примеры:

   x = gsub("hello world", "(%w+)", "%1 %1")
   --> x="hello hello world world"
   x = gsub("hello world", "(%w+)", "%1 %1", 1)
   --> x="hello hello world"
   x = gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
   --> x="world hello Lua from"
   x = gsub("home = $HOME, user = $USER", "%$(%w+)", getenv)
   --> x="home = /home/roberto, user = roberto"  (for instance)
   x = gsub("4+5 = $return 4+5$", "%$(.-)%$", dostring)
   --> x="4+5 = 9"
   local t = {name="lua", version="4.0"}
   x = gsub("$name - $version", "%$(%w+)", function (v) return %t[v] end)
   --> x="lua - 4.0"
   t = {n=0}
   gsub("first second word", "(%w+)", function (w) tinsert(%t, w) end)
   --> t={"first", "second", "word"; n=3}

Шаблоны

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

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

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

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

Элемент образца:

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

Шаблоны:

Шаблон представляет собой последовательность элементов образца. Циркумфлекс (^) в начале образца закрепляет соответствие в начале подчиненной строки. $ в конце образца закрепляет соответствие в конце подчиненной строки. В других позициях ^ и $ не имеют никакого специального значения и представляются как есть.

Сборы данных:

Образец может содержать подобразцы, включенные в круглые скобки, они описывают сборы данных. Когда соответствие выполнено, подстроки подчиненной строки, которые соответствуют сборам данных, сохранены для будущего использования. Сборы данных пронумерованы согласно их левым круглым скобкам. Например, в образце "(a*(.)%w(%s*))", часть соответствия строки "a*(.)%w(%s*)" сохранена как первый сбор данных (а, следовательно, имеет номер 1), символьное соответствие . зафиксировано с номером 2, а часть, соответствующая %s*, конечно, имеет номер 3.

Образец не может содержать вложенные ноли. Используйте вместо этого %z.

4.6.3 Математические функции

Эта библиотека предоставляет интерфейс к некоторым функциям стандартной математической библиотеки C. Кроме того, это регистрирует метод тэга для двоичного оператора ^, который возвращает x^y, когда применяется к числам x^y.

Библиотека обеспечивает следующие функции:

abs  acos  asin  atan  atan2  ceil  cos  deg    exp    floor   log  log10
max  min   mod   rad   sin    sqrt  tan  frexp  ldexp  random  randomseed
Плюс глобальная переменная PI. Большинство из них представляют собой только интерфейсы к функциям в C-библиотеке, за исключением того, что для тригонометрических функций все углы выражены в градусах, а не в радианах. Функции deg и rad могут использоваться для того, чтобы преобразовывать данные между радианами и градусами.

Функция max возвращает максимальное значение числовых параметров. Точно так же min вычисляет минимум. Обе они могут использоваться с 1, 2 или большим количеством параметров.

Функции random и randomseed представляют собой интерфейсы к простому генератору случайных чисел, предоставляемому ANSI C (соответвенно функции rand и srand). Не может быть дпно никаких гарантий касательно их статистических свойств. Функция random при вызове без параметров возвращает псевдослучайное вещественное число в диапазоне [0,1). При вызове с параметром n, random вернет псевдослучайное целое число в диапазоне [1,n]. При вызове с двумя параметрами l и u, random вернет псевдослучайное целое число в диапазоне [l,u]. Границы всегда входят в диапазон.

4.6.4 Средства ввода-вывода

Все операции ввода-вывода в Lua реализованы через два дескриптора файла, по одному на ввод и вывод. Эти дескрипторы сохранены в двух глобальных переменных Lua, названных _INPUT и _OUTPUT. Глобальные переменные _STDIN, _STDOUT и _STDERR инициализированы с описателями файлов для stdin, stdout и stderr. Первоначально Initially, _INPUT=_STDIN и _OUTPUT=_STDOUT.

Дескриптор файла представляет собой объект userdata, содержащий поток файла (FILE*) с отличительным тэгом, созданным библиотекой ввода-вывода (I/O).

Если иное не установлено, все функции I/O возвращают nil на сбое и некоторое значение, отличное от nil, при успехе.

openfile (filename, mode)

Эта функция открывает файл в режиме, определенном в строке mode. Это возвращает новый дескриптор файла или, в случае ошибок, nil плюс строку, описывающую ошибку. Эта функция не изменяет _INPUT или _OUTPUT.

Строка mode может быть любой из следующего списка:

r
Режим чтения.
w
Режим записи.
a
Режим добавления к концу.
r+
Режим обновления, все ранее записанные данные сохраняются.
w+
Режим обновления, все ранее записанные данные уничтожаются.
a+
Режим модификации, предыдущие данные сохраняются, запись позволяется только в конце файла.
Строка mode может также иметь в конце b, что необходимо в некоторых системах, чтобы открыть файл в двоичном режиме. Эта строка аналогична той, что используется в стандартной функции C fopen.

closefile (handle)

Эта функция закрывает файл. Это не изменяет _INPUT или _OUTPUT.

readfrom (filename)

Эта функция может быть вызвана двумя путями. Когда она вызвана с именем файла, открывает именованный файл, устанавливает дескриптор как значение _INPUT и возвращает это значение. Это не закрывает текущий файл input. При вызове без параметров, она закрывает файл _INPUT и восстанавливает stdin как значение _INPUT. Если эта функция где-то не сработала, она возвращает nil плюс строку описания.

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

writeto (filename)

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

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

appendto (filename)

Открывает файл, именованный filename и устанавливает это как значение _OUTPUT. В отличие от операции writeto, эта функция не стирает предыдущее содержание файла, вместо этого все, что пишется в файл, будет конкатенировано к концу. Если эта функция получила сбой, она вернет nil плюс строку, описывающую ошибку.

remove (filename)

Удаляет файл с данным именем. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.

rename (name1, name2)

Переименовывает файл name1 в name2. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.

flush ([filehandle])

Сохраняет любые записанные данные в заданный файл. Если filehandle не определен, то flush сбросит на диск все открытые файлы. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.

seek (filehandle [, whence] [, offset])

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

set
Позиция 0 (начало файла).
cur
Текущая позиция.
end
Конец файла.
В случае успеха функция seek возвращает конечную позицию файла, измеряемую в байтах от начала файла. Если эта функция получила сбой, она вернет nil плюс строку, описывающую эту ошибку.

Значение по умолчанию для whence равно cur, а для offset это 0. Следовательно, вызов seek(file) возвращает текущую позицию файла без того, чтобы изменить это. Вызов seek(file, "set") устанавливает позицию на начало файла (и возвращает 0), а seek(file, "end") устанавливает позицию в конец файла и возвращает его размер.

tmpname ()

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

read ([filehandle,] format1, ...)

Читает файл _INPUT или filehandle, если этот параметр задан, согласно данным форматам, которые определяют, что читать. Для каждого формата, функция возвращает строку или число с прочитанными данными или nil, если не может читать данные с определенным форматом. Когда вызвана без форматов, эта функция использует заданный по умолчанию формат, который читает следующую строку.

Доступные форматы такие:

*n
Читает число. Это единственный формат, который возвращает число вместо строки.
*l
Читает следующую строку (обходя концы строк) или nil в конце файла. Это и есть заданный по умолчанию формат.
*a
Читает целый файл, начинающийся в текущей позиции. На конце файла, возвращает пустую строку.
*w
Читает следующее слово (максимальная последовательность символов без пробелов. Пробелы обходит в случае необходимости. Замечу, что под пробелом здесь понимается не только собственно пробел, но и спецсимволы. В конце файла функция вернет nil.
Число
Читает строку до указанного числа символов в длину или nil на конце файла.

write ([filehandle, ] value1, ...)

Пишет значение каждого из параметров в файл _OUTPUT или в filehandle, если этот параметр задан. Параметры должны быть строками или числами. Чтобы писать другие значения, используйте tostring или format перед write. Если эта функция нарвалась на ошибку, она вернет nil и строку с описанием данной ошибки.

4.6.5 Средства системы

clock ()

Возвращает приближение количество времени CPU, используемое программой (в секундах).

date ([format])

Возвращает строку, содержащую дату и время, форматируемую согласно данному формату format. Формат задается по тем же самым правилам, что и в функции ANSI C strftime. Когда вызвана без параметров, возвращает приемлемое представление даты и времени, которое зависит от ведущей системы и от текущего региона.

execute (command)

Эта функция эквивалентна функции C system. Это передает команду command, которая будет выполнена оболочкой операционной системы. Возвращает код состояния, который является зависимым от системы.

exit ([code])

Вызывает C-функцию exit с факультативным кодом завершения программы code. Значение по умолчанию для code: код успешного завершения.

getenv (varname)

Возвращает значение системной переменной процесса varname или nil, если эта переменная не определена.

setlocale (locale [, category])

Эта функция предоставляет интерфейс к функции ANSI C setlocale. locale представляет собой строку, определяющую регион, category факультативная строка, описывающая которую категорию изменить: "all", "collate", "ctype", "monetary", "numeric" или "time", заданная по умолчанию категория: "all". Функция возвращает имя нового региона или nil, если этот запрос не может быть выполнен.

4.7 Интерфейс отладки

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

4.7.1 Информация стека и функций

Основная функция, чтобы получить информацию относительно стека интерпретатора:

int lua_getstack (lua_State *L, int level, lua_Debug *ar);
Это заполняет части структуры lua_Debug с идентификацией записи активации функции, выполняющейся в заданном уровне. Уровень 0 текущая функция управления, в то время как уровень n+1 функция, которая вызвала уровнем n. Обычно lua_getstack вернет 1, когда вызвана с уровнем больше, чем глубина стека, она возвращает 0.

Структура lua_Debug используется, чтобы нести различные части информации относительно активной функции:

typedef struct lua_Debug {
  const char *event;     /* "call", "return" */
  int currentline;       /* (l) */
  const char *name;      /* (n) */
  const char *namewhat;
          /* (n) поля, глобальные и локальные переменные, методы тэгов */
  int nups;              /* (u) количество upvalues */
  int linedefined;       /* (S) */
  const char *what;      /* (S) "Lua" функция, "C" функция, Lua "main" */
  const char *source;    /* (S) */
  char short_src[LUA_IDSIZE]; /* (S) */
  /* private part */
  ...
} lua_Debug;
lua_getstack заполняет только одну из частей этой структуры для будущего использования. Чтобы заполнить другие поля lua_Debug полезной информацией, надо вызвать:
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
Эта функция возвращает 0 на ошибке (например, недопустимая опция в what). Каждый символ в строке what указывает некоторые поля ar, которые будет заполнены, как обозначено символом в круглых скобках в определении lua_Debug: S заполняет поле исходником (source), linedefined и what, l заполняет поле текущей строкой (currentline) и так далее. Кроме того, f помещает в стек функцию, которая работает в данном уровне.

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

  lua_Debug ar;
  lua_getglobal(L, "f");
  lua_getinfo(L, ">S", &ar);
  printf("%d\n", ar.linedefined);
Поля lua_Debug имеют следующее значение:
source
Если функция была определена в строке, source как раз и будет этой строкой, а если функция была определена в файле, source начинается с @, а дальше имя файла.
short_src
Пригодная к печати версия source, чтобы использоваться в сообщениях об ошибке.
linedefined
Код строки, где было начато определение функции.
what
Строка "Lua", если это функция Lua, "C", если это функция C или "main", если это основная часть chunk.
currentline
Текущая строка, где данная функция выполняется. Когда никакая информация о строке недоступна, currentline установлен в -1.
name
Приемлемое имя для данной функции. Так как функции в Lua значения первого класса, они не имеют фиксированных имен. Именем функции может быть значение многих глобальных переменных, в то время как другие функции могут быть сохранены только в поле таблицы. Функция lua_getinfo проверяет, является ли данная функция методом тэга или значением глобальной переменной. Если данная функция представляет собой метод тэга, name указывает на имя события. Если данная функция является значением глобальной переменной, то name указывает на имя переменной. Если данная функция не является ни методом тэга, ни глобальной переменной, то name установлен в NULL.
namewhat
Объясняет предыдущее поле. Если функция глобальная переменная, namewhat равен "global". Если функция метод тэга, namewhat равен "tag-method", иначе namewhat равен "" (пустой строке).
nups
Число upvalues в функции.

4.7.2 Управление локальными переменными

Для манипулирования локальными переменными luadebug.h использует индексы: первый параметр или локальная переменная имеет индекс 1 и так далее до последней активной локальной переменной.

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

const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
Параметр ar должен быть имеющей силу записью активации, заполненной предыдущим обращением к lua_getstack или данный как параметр обработчика прерываний. Функция lua_getlocal получает индекс локальной переменной (n), помещает значение в стек и возвращает имя. Для lua_setlocal Вы помещаете новое значение в стек, а функция назначает это значение переменной и возвращает имя. Обе функции возвращают NULL при сбое. Это случается, если заданный индекс больше, чем число активных локальных переменных.

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

int listvars (lua_State *L, int level) {
  lua_Debug ar;
  int i = 1;
  const char *name;

  if (lua_getstack(L, level, &ar) == 0) return 0;
     /* failure: no such level in the stack */
  while ((name = lua_getlocal(L, &ar, i++)) != NULL) {
    printf("%s\n", name);
    lua_pop(L, 1);  /* remove variable value */
  }
  return 1;
}

4.7.3 Обработчики прерываний

Lua-интерпретатор предлагает два обработчика прерываний для целей отладки: call и line. Оба обработчика имеют тот же самый тип:

typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
Вы можете устанавливать их со следующими функциями:
lua_Hook lua_setcallhook (lua_State *L, lua_Hook func);
lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);
Обработчик прерываний заблокирован, когда значение NULL, что и является начальным значением обоих обработчиков прерываний. Функции lua_setcallhook и lua_setlinehook устанавливают соответствующие обработчики прерываний и возвращают их предыдущие значения.

Обработчик прерываний call вызван всякий раз, когда интерпретатор вызывает или оставляет функцию. Поле события event записи ar имеет строки "call" или "return". Этот ar может затем использоваться в обращениях для lua_getinfo, lua_getlocal и lua_setlocal, чтобы получить большее количество информации относительно функции и управлять локальными переменными.

Обработчик прерываний line вызван каждый раз, когда интерпретатор изменяет строку кода, которую выполняет. Поле event в ar имеет строку "line", а поле currentline хранит код строки. Вы можете использовать этот ar в других обращениях к отладочному API.

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

4.7.4 Рефлексивный интерфейс отладки

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

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

getinfo (function, [what])

Эта функция возвращает таблицу с информацией относительно функции. Вы можете давать функцию непосредственно, или Вы можете давать число как значение function, что означает функциональное управление в уровне стека function. Уровень 0 считается текущей функцией (непосредственно getinfo), уровень 1: функция, которая вызвала getinfo и так далее. Если function представляет собой число большее, чем число активных функций, то getinfo сразу вернет nil.

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

Например, выражение getinfo(1,"n").name вернет имя текущей функции, если приемлемое имя может быть найдено, и getinfo(print) возвращает таблицу со всей доступной информацией относительно функции print.

getlocal (level, local)

Эта функция возвращает имя и значение локальной переменной с индексом, local на уровне level стека. Первый параметр или локальная переменная имеет индекс 1 и так далее до последней активной локальной переменной. Функция вернет nil, если не имеется никакой локальной переменной с данным индексом, и поднимает ошибку когда вызвана с level вне диапазона. Вы можете вызывать getinfo, чтобы проверить, имеет ли этот уровень силу.

setlocal (level, local, value)

Эта функция назначает значение value локальной переменной с индексом local функции на уровне level стека. Функция вернет nil, если не имеется никакой локальной переменной с данным индексом, и поднимает ошибку когда вызвана с уровнем level вне диапазона.

setcallhook (hook)

Устанавливает функциональный обработчик прерываний hook как обработчик прерываний call. Этот обработчик прерываний будет вызван каждый раз при начале и завершении интерпретации функции. Единственный параметр на обработчик прерываний call: имя события ("call" или "return"). Вы можете вызывать getinfo с уровнем 2, чтобы получить большее количество информации относительно функции (уровень 0 соответствует функции getinfo, а уровень 1 задает функцию обработчика прерываний. Когда вызвана без параметров, эта функция выключает обработчики прерываний call. setcallhook вернет старый обработчик прерываний.

setlinehook (hook)

Устанавливает функциональный обработчик прерываний hook как обработчик прерываний line. Этот обработчик прерываний будет вызван каждый раз, когда интерпретатор изменяет обрабатываемую строку кода. Единственный параметр на обработчике прерываний line: код строки, которую интерпретатор собирается выполнять. Когда вызвана без параметров, эта функция выключает обработчики прерываний line. Вызов setlinehook возвращает старый обработчик прерываний.

4.8 Lua в автономном режиме

Хотя Lua был разработан как язык расширений, чтобы быть вложенным в ведущую программу на C, это часто используется как автономный язык. Интерпретатор для Lua, как автономного языка, называется просто lua. Эта программа может быть вызвана с любой последовательностью следующих параметров:

-sNUM
Устанавливает размер стека в NUM (если используется, должно быть первой опцией).
-
Выполняет stdin как файл.
-c
Вызывает lua_close после обработки всех параметров.
-e \rmstat
Выполняет строку stat.
-f filename
Выполняет файл filename с параметрами для таблицы arg.
-i
Вводит интерактивный режим с подсказкой.
-q
Вводит интерактивный режим без подсказки.
-v
Информация о версии пакета.
var=value
Устанавливает глобальную переменную var в строку "value".
filename
Выполняет файл filename.
Когда вызван без параметров, lua ведет себя как lua -v -i, когда stdin представляет собой терминал, или аналогично lua - в противном случае.

Все параметры обработаны по порядку, за исключением -c. Например, обращение, подобное:

$ lua -i a=test prog.lua
Сначала взаимодействует с пользователем до EOF в stdin, затем установит a в "test" и в заключение выполнит файл prog.lua. Здесь под $ понимается подсказка оболочки. Ваша подсказка может быть иной.

Когда используется опция -f filename, все параметры в командной строке переданы программе Lua filename в таблице, названной arg. В этой таблице поле n получает индекс последнего параметра, а поле 0 получает "filename". Например,

$ lua a.lua -f b.lua t1 t3
интерпретатор сначала выполняет файл a.lua, затем создает таблицу:
arg = {"t1", "t3";  n = 2, [0] = "b.lua"}
а в заключение выполняет файл b.lua. Автономный интерпретатор также обеспечивает функцию getargs, которая может использоваться, чтобы обратиться ко всем параметрам командной строки. Например, если Вы вызываете Lua строкой:
$ lua -c a b
то обращение к getargs в a или в b возвратит такую таблицу:
{[0] = "lua", [1] = "-c", [2] = "a", [3] = "b", n = 3}

В интерактивном режиме может быть написана многострочная инструкция. Для этого надо заканчивать промежуточные строки наклонной чертой влево (\). Если глобальная переменная _PROMPT определена как строка, то ее значение используется как подсказка. Следовательно, подсказка может быть изменена непосредственно в командной строке. Например:

$ lua _PROMPT='myprompt> ' -i
Или в программе Lua, назначая новое значение переменной _PROMPT.

В Unix Lua-скрипты могут быть переделаны в выполнимые программы, используя chmod +x и форму #! как в #!/usr/local/bin/lua или #!/usr/local/bin/lua -f, чтобы получить другие параметры.

4.10 Благодарности

Авторы пакета хотели бы поблагодарить CENPES/PETROBRAS, который, совместно с TeCGraf, использовал ранние версии этой системы и дал ценные комментарии. Авторы также хотели бы отблагодарить Carlos Henrique Levy за найденное имя для проекта. Lua на португальском означает луну.

4.11 Несовместимость с предыдущими версиями

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

Несовместимости с version 3.2

Изменения в языке

  • Все прагмы ($debug, $if, ...) удалены.
  • for, break и in теперь зарезервированные слова.
  • Методы тэгов уборки мусора для таблиц теперь устаревшие.
  • Имеется теперь только один метод тэга для операторов порядка.
  • Во вложенных обращениях к функции, подобно f(g(x)), все возвращаемые значения из g переданы как параметры f. Это случается только, когда g последний или единственный параметр для f.
  • Предварительный компилятор может принимать, что некоторые операторы ассоциативны для оптимизации. Это может вызывать проблемы, если эти операторы имеют не ассоциативные методы тэгов.
  • Старые прекомпилированные программы устарели, и должны быть перетранслирована.

Изменения в библиотеках

  • При пересечении таблицы с next или foreach таблица не может изменяться.
  • Общие образцы чтения теперь устаревшие.
  • Функции rawgettable и rawsettable теперь переименованы соответственно в rawget и rawset.
  • Функции foreachvar, nextvar, rawsetglobal и rawgetglobal устаревшие. Вы можете получать их функциональные возможности, используя операции таблицы с таблицей глобальных переменных, возвращаемой globals.
  • setglobal и sort больше не возвращают значение. Вызов type больше не возвращает второе значение.
  • Опция p в функции call устарела.

Изменения в API

  • API был полностью переделан. Это теперь полностью повторно используемо и намного более ясно.
  • Отладочный API был полностью переделан.

4.12 Полный синтаксис Lua

chunk ::= {stat [`;']}
block ::= chunk
stat ::=  varlist1 `=' explist1 
| functioncall
| do block end
| while exp1 do block end
| repeat block until exp1
| if exp1 then block {elseif exp1 then block} [else block] end
| return [explist1]
| break
| for `name' `=' exp1 `,' exp1 [`,' exp1] do block end
| for `name' `,' `name' in exp1 do block end
| function funcname `(' [parlist1] `)' block end
| local declist [init] funcname ::= `name' | `name' `.' `name' | `name' `:' `name' varlist1 ::= var {`,' var} var ::= `name' | varorfunc `[' exp1 `]' | varorfunc `.' `name' varorfunc ::= var | functioncall declist ::= `name' {`,' `name'} init ::= `=' explist1 explist1 ::= {exp1 `,'} exp exp1 ::= exp exp ::= nil | `number' | `literal' | var | function | upvalue
| functioncall | tableconstructor | `(' exp `)' | exp binop exp | unop exp functioncall ::= varorfunc args | varorfunc `:' `name' args args ::= `(' [explist1] `)' | tableconstructor | `literal' function ::= function `(' [parlist1] `)' block end parlist1 ::= `...' | `name' {`,' `name'} [`,' `...'] upvalue ::= `%' `name' tableconstructor ::= `{' fieldlist `}' fieldlist ::= lfieldlist | ffieldlist | lfieldlist `;' ffieldlist | ffieldlist `;' lfieldlist lfieldlist ::= [lfieldlist1] ffieldlist ::= [ffieldlist1] lfieldlist1 ::= exp {`,' exp} [`,'] ffieldlist1 ::= ffield {`,' ffield} [`,'] ffield ::= `[' exp `]' `=' exp | `name' `=' exp binop ::= `+' | `-' | `*' | `/' | `\^{ ' | `..'
| `<' | `<=' | `>' | `>=' | `==' | `\ { '=}
| and | or} unop ::= `-' | not

4.13 lua: интерпретатор языка Lua

Синтаксис

lua [arguments]

Описание

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

arguments могут быть параметрами, назначениями или именами файлов. Они будут обработаны слева направо.

Параметры начинаются с тире (-) и описаны ниже.

Назначение представляет собой параметр формы a=b, который назначает b глобальной переменной a. Обратите внимание, что никакие кавычки не нужны вокруг строки, если она не содержит пробелы или другие символы, специальные для оболочки. Вообще, Вы должны быть внимательны при использовании кавычек и пробелов в командной строке потому, что они обычно обрабатываются оболочкой непосредственно.

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

Если никакие параметры не заданы, то принято -v -i, когда стандартный ввод представляет собой терминал, в противном случае используется -.

Опции

Тире (-) загрузить стандартный ввод как файл, то есть не в интерактивном режиме, даже когда стандартный ввод является терминалом.

-c Закрыть Lua перед выходом.

-e "stat" выполнить инструкцию stat. Вы должны цитировать stat, если она содержит пробелы или кавычки.

-f "file" собрать все последующие параметры как строку в глобальную таблицу arg, а затем выполнить файл file. Параметры в arg начинаются с 0, который содержит строку file. Индекс последнего параметра сохранен в arg.n.

-i ввести интерактивный режим, показывая подсказку. В этом режиме lua читает строки из стандартного ввода и выполняет их как они читаются. Каждая строка должна содержать полную инструкцию. Чтобы записать инструкцию, охватывающую несколько строк, закончите каждую строку наклонной чертой влево (\). Показываемая подсказка представляет собой значение глобальной переменной _PROMPT, если это значение строка. Чтобы изменить подсказку, задайте нужное значение _PROMPT. Вы можете делать это после вызова интерпретатора или в командной строке с помощью "_PROMPT=\'lua: \'". Обратите внимание на потребность в кавычках потому, что строка содержит пробел. Заданная по умолчанию подсказка: >.

-q ввести интерактивный режим, но не показывая подсказку.

-sn установить размер стека в n. Если представлено, это должно быть первой опцией. Обратите внимание, что n находится в том же самом параметре, что и -s. Например, чтобы определить размер стека в 2000, используйте -s2000.

-v вывести информацию о версии.

Также можно посмотреть

luac(1)
http://www.tecgraf.puc-rio.br/lua.

Диагностика

Сообщения пакета об ошибках должны быть самодостаточными.

luac: компилятор Lua

Синтаксис вызова

luac [options] [filenames]

Описание

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

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

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

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

Двоичные файлы, созданные luac, переносимы на любую архитектуру с тем же самым размером слова. Это означает, что двоичные файлы, созданные на 32-разрядной платформе (типа Intel) могут читаться без изменений на другой 32-разрядной платформе (типа Sparc), даже если порядок байт различен. С другой стороны, двоичные файлы, созданные на 16-разрядной платформе, не могут читаться на 32-разрядной платформе.

В командной строке Вы можете смешивать текстовые файлы, содержащие код на Lua, и двоичные файлы, содержащие прекомпилированные блоки. Это полезно: чтобы объединить несколько прекомпилированных блоков даже с различных (но совместимых) платформ в один блок.

Вы можете использовать "-", чтобы указать stdin как исходный файл.

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

Опции

Параметры должны быть отделены друг от друга. -l производит распечатку компилируемого байт-кода для виртуальной машины Lua. Если никакие файлы не даны, то luac загружает luac.out и вносит в список его полное содержание.

-o "file" выводит данные в file вместо значения по умолчанию luac.out. Выходной файл может быть исходным файл потому, что все файлы загружены прежде, чем выходной файл записан.

-p загружают файлы, но не генерируют никакой выходной файл. Использован главным образом для проверки синтаксиса или тестирования прекомпиляции: разрушенные файлы, вероятно, сгенерируют ошибки, когда будут загружены. Для полного теста целостности используйте опцию -t.

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

-t выполняет полный тест целостности прекомпилированного кода. Код, который признает нормальным этот тест, полностью безопасен в том смысле, что это не будет разрывать интерпретатор. Однако, не имеется никакой гарантии, что такой код делает что-нибудь полезное. Если никакие файлы не заданы, то luac загружает luac.out и проверяет его содержимое.

-v выводит сведения о версии.

Файлы

luac.out представляет собой заданный по умолчанию выходной файл

Также можно посмотреть

lua(1)
http://www.tecgraf.puc-rio.br/lua.

Диагностика

Сообщения пакета об ошибках должны быть самодостаточными.

Авторы пакета

R. Ierusalimschy,
L. H. de Figueiredo и
W. Celes (
lua@tecgraf.puc-rio.br).

4.14 Установка языка LUA

Построение Lua на системах Unix очень просто:

  • Отредактируйте файл config, чтобы соответствовать Вашей системе, если в этом есть необходимость.
  • Выполните команду make.
  • Если Вы хотите устанавливать Lua в "официальное" место в Вашей системе, то затем сделайте make install. Официальное место и способ устанавливать файлы определены в config. Вам, вероятно, придется регистрироваться как root, чтобы сделать это.

Ниже приведены инструкции для пользователей систем Windows и Macintosh.

4.14.1 Что Вы получаете

Если make выполнилась без проблем, Вы получите:

  • Интерпретатор ./bin/lua, а также прекомпилятор ./bin/luac.
  • Набор библиотек в ./lib.
  • Включаемые файлы в ./include.

Это единственные каталоги, в которых Вы нуждаетесь для разработки.

Man-страницы для lua и luac в nroff и html, а также справочное описание в html помещаются в ./doc, некоторый типовой код в ./test, а некоторые полезные дополнения в ./etc. Вы не нуждаетесь в этих каталогах для разработки.

Изучите также README-файлы в различных подкаталогах. Удобная отправная точка: ./doc/readme.html.

4.14.2 Проблемы и некоторые решения

Если вызов make ничего хорошего не сделал, пожалуйста, сообщите на lua@tecgraf.puc-rio.br. Если Вы делаете изменения для config или в файлах Makefile, пожалуйста, пошлите их туда же.

4.14.3 Разделяемые библиотеки

Если Вы управляете Linux, сделайте make so после успешного выполнения make. Это создаст общедоступные библиотеки в ./lib. Вероятно, лучше формировать общедоступные библиотеки прежде, чем выполнять make install.

Если Вы хотите переделать интерпретатор и транслятор так, чтобы использовать общедоступные библиотеки, то выполните также make sobin.

Вы, возможно, должны включить lib в системную переменную LD_LIBRAY_PATH, чтобы компоновать программы, которые используют общедоступные библиотеки, если Вы не помещаете их в официальные места с помощью make install.

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

4.14.4 Установка на Windows или Macintosh

Команды для формирования Lua на Mac или Windows-машине зависят от специфического компилятора, который Вы используете. Самый простой путь состоит в том, чтобы создать папку со всеми файлами .c и .h. Затем создайте проекты для основной библиотеки, стандартной библиотеки, интерпретатора и прекомпилятора следующим образом:

core lib:     lapi.c lcode.c ldebug.c ldo.c lfunc.c lgc.c llex.c lmem.c
              lobject.c lparser.c lstate.c lstring.c ltable.c ltests.c
              ltm.c lundump.c lvm.c lzio.c
standard lib: lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c lstrlib.c
interpreter:  core lib, standard lib, lua.c
compiler:     core lib, dump.c luac.c opt.c print.c stubs.c

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

4.14.5 INSTALL для mysql 3.23.32

  • Скачайте LUA 4.0 patched для использования с mysql (оригинальный пакет не годится).
  • Установите и откомпилируйте LUA 4.0, но не в том же самом каталоге, где и mysql. Я использую /usr/src/lua для LUA и /usr/src/mysql для MySQL.
  • В дереве исходного кода mysql сделайте:
    cd sql
    tar zxf /download/mylua.tar.gz
    cd ..
    ./configure --enable-assembler --prefix=/usr/local/mysql \
                --enable-assembler --with-mysqld-ldflags="-L/usr/src/lua/lib \
                -llua -llualib"
    
  • Опробуйте скрипт примера:
    mysql mysql
    mysql< SELECT user,host FROM user
                  PROCEDURE("/usr/src/mysql/sql/count.lua")
    

Поиск

 

Найди своих коллег!