Spec-Zone.ru › Lua 5.2

Руководство по Lua 5.2

авторы: Роберто Иерусалимский, Луис Энрике де Фигейредо, Валдемар Селес

1 – Введение

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

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

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

Как и любое другое справочное руководство, этот документ местами сух. Для обсуждения решений, стоящих за разработкой Lua, см. технические статьи, доступные на веб-сайте Lua. Для подробного введения в программирование на Lua см. книгу Роберто «Программирование на Lua».

2 – Основные понятия

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

2.1 – Значения и типы

Lua — это динамически типизированный язык. Это означает, что переменные не имеют типов; только значения имеют типы. В языке нет определений типов. Все значения несут свой собственный тип.

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

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

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

Тип userdata предоставлен для возможности хранения произвольных данных C в Lua-переменных. Значение userdata — это указатель на блок сырой памяти. Существует два вида userdata: полный userdata, где блок памяти управляется Lua, и лёгкий userdata, где блок памяти управляется хостом. Userdata не имеет предопределённых операций в Lua, за исключением присваивания и проверки тождества. Используя меттаблицы, программист может определить операции для полных значений userdata (см. §2.4). Значения userdata нельзя создавать или изменять в Lua, только через C API. Это гарантирует целостность данных, принадлежащих программе-хосту.

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

Тип table реализует ассоциативные массивы, то есть массивы, которые можно индексировать не только числами, но и любыми Lua-значениями, кроме nil и NaN (Not a Number, специальное числовое значение, используемое для представления неопределённых или непредставимых результатов, таких как 0/0). Таблицы могут быть неоднородными; то есть они могут содержать значения всех типов (кроме nil). Любой ключ со значением nil не считается частью таблицы. И наоборот, любой ключ, не являющийся частью таблицы, имеет связанное значение nil.

Таблицы являются единственным механизмом структурирования данных в Lua; они могут использоваться для представления обычных массивов, последовательностей, таблиц символов, множеств, записей, графов, деревьев и т. д. Для представления записей Lua использует имя поля в качестве индекса. Язык поддерживает это представление, предоставляя a.name в качестве синтаксического сахара для a["name"]. Существует несколько удобных способов создания таблиц в Lua (см. §3.4.8).

Мы используем термин последовательность для обозначения таблицы, где множество всех положительных числовых ключей равно {1..n} для некоторого целого числа n, которое называется длиной последовательности (см. §3.4.6).

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

Индексирование таблиц соответствует определению «сырого» равенства в языке. Выражения a[i] и a[j] обозначают один и тот же элемент таблицы тогда и только тогда, когда i и j сырово равны (то есть равны без метаметодов).

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

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

2.2 – Среды и глобальная среда

Как будет обсуждаться в §3.2 и §3.3.3, любая ссылка на глобальное имя var синтаксически преобразуется в _ENV.var. Кроме того, каждый фрагмент компилируется в области внешней локальной переменной, называемой _ENV (см. §3.3.2), поэтому _ENV само по себе никогда не является глобальным именем в фрагменте.

Несмотря на существование этой внешней переменной _ENV и преобразования глобальных имён, _ENV — это совершенно обычное имя. В частности, вы можете определять новые переменные и параметры с этим именем. Каждая ссылка на глобальное имя использует _ENV, которое видно в этот момент программы, следуя обычным правилам видимости Lua (см. §3.5).

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

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

При компиляции фрагмента Lua инициализирует значение его _ENV лексической переменной глобальной средой (см. load). Поэтому по умолчанию глобальные переменные в Lua-коде ссылаются на записи в глобальной среде. Кроме того, все стандартные библиотеки загружаются в глобальную среду, и несколько функций там работают с этой средой. Вы можете использовать load (или loadfile) для загрузки фрагмента с другой средой. (В C вам нужно загрузить фрагмент, а затем изменить значение его первой лексической переменной.)

Если вы измените глобальную среду в реестре (через C-код или библиотеку отладки), все фрагменты, загруженные после изменения, получат новую среду. Загруженные ранее фрагменты не изменяются, так как каждый из них имеет свою ссылку на среду в своей переменной _ENV. Кроме того, переменная _G (которая хранится в исходной глобальной среде) никогда не обновляется Lua.

2.3 – Обработка ошибок

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

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

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

При использовании xpcall или lua_pcall вы можете указать обработчик сообщений, который будет вызываться в случае возникновения ошибок. Эта функция вызывается с оригинальным сообщением об ошибке и возвращает новое сообщение об ошибке. Она вызывается до того, как ошибка разворачивает стек, так что она может собрать больше информации об ошибке, например, просмотрев стек и создав обратный отслеживающий стек вызовов. Этот обработчик сообщений всё ещё защищён защищённым вызовом; поэтому ошибка внутри обработчика сообщений вызовет обработчик сообщений снова. Если этот цикл продолжается, Lua прерывает его и возвращает соответствующее сообщение.

2.4 – Меттаблицы и метаметоды

Каждое значение в Lua может иметь меттаблицу. Эта меттаблица — это обычная Lua-таблица, которая определяет поведение исходного значения при определённых специальных операциях. Вы можете изменить различные аспекты поведения операций над значением, установив определённые поля в его меттаблице. Например, когда нечисловое значение является операндом сложения, Lua проверяет наличие функции в поле "__add" меттаблицы значения. Если она найдена, Lua вызывает эту функцию для выполнения сложения.

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

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

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

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

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

Метатаблицы управляют операциями, перечисленными ниже. Каждая операция идентифицируется по соответствующему имени. Ключ для каждой операции — строка с префиксом из двух подчеркиваний, '__'; например, ключ для операции "add" — это строка "__add".

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

metatable(obj)[event]

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

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

Это означает, что доступ к метаметоду не вызывает других метаметодов, и доступ к объектам без метатаблиц не приводит к ошибке (он просто возвращает nil).

Для унарных операторов - и # метаметод вызывается со вторым аргументом-заглушкой. Этот дополнительный аргумент служит только для упрощения внутренней реализации Lua; он может быть удален в будущих версиях и поэтому не присутствует в следующем коде. (Для большинства применений этот дополнительный аргумент не имеет значения.)

  • "add": операция +.

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

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

    Используя эту функцию, поведение операции op1 + op2

    function add_event (op1, op2)
      local o1, o2 = tonumber(op1), tonumber(op2)
      if o1 and o2 then  -- both operands are numeric?
        return o1 + o2   -- '+' here is the primitive 'add'
      else  -- at least one of the operands is not numeric
        local h = getbinhandler(op1, op2, "__add")
        if h then
          -- call the handler with both operands
          return (h(op1, op2))
        else  -- no handler available: default behavior
          error(···)
        end
      end
    end
  • "sub": операция -. Поведение аналогично операции "add".
  • "mul": операция *. Поведение аналогично операции "add".
  • "div": операция /. Поведение аналогично операции "add".
  • "mod": операция %. Поведение аналогично операции "add", с операцией o1 - floor(o1/o2)*o2 в качестве примитивной операции.
  • "pow": операция ^ (возведение в степень). Поведение аналогично операции "add", с функцией pow (из библиотеки математики C) в качестве примитивной операции.
  • "unm": унарная операция -.
    function unm_event (op)
      local o = tonumber(op)
      if o then  -- operand is numeric?
        return -o  -- '-' here is the primitive 'unm'
      else  -- the operand is not numeric.
        -- Try to get a handler from the operand
        local h = metatable(op).__unm
        if h then
          -- call the handler with the operand
          return (h(op))
        else  -- no handler available: default behavior
          error(···)
        end
      end
    end
  • "concat": операция .. (конкатенация).
    function concat_event (op1, op2)
      if (type(op1) == "string" or type(op1) == "number") and
         (type(op2) == "string" or type(op2) == "number") then
        return op1 .. op2  -- primitive string concatenation
      else
        local h = getbinhandler(op1, op2, "__concat")
        if h then
          return (h(op1, op2))
        else
          error(···)
        end
      end
    end
  • "len": операция #.
    function len_event (op)
      if type(op) == "string" then
        return strlen(op)      -- primitive string length
      else
        local h = metatable(op).__len
        if h then
          return (h(op))       -- call handler with the operand
        elseif type(op) == "table" then
          return #op              -- primitive table length
        else  -- no handler available: error
          error(···)
        end
      end
    end

    См. §3.4.6 для описания длины таблицы.

  • "eq": операция ==. Функция getequalhandler определяет, как Lua выбирает метаметод для равенства. Метаметод выбирается только тогда, когда оба сравниваемых значения имеют один и тот же тип и тот же метаметод для выбранной операции, и значения являются либо таблицами, либо полными пользовательскими данными.
    function getequalhandler (op1, op2)
      if type(op1) ~= type(op2) or
         (type(op1) ~= "table" and type(op1) ~= "userdata") then
        return nil     -- different values
      end
      local mm1 = metatable(op1).__eq
      local mm2 = metatable(op2).__eq
      if mm1 == mm2 then return mm1 else return nil end
    end

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

    function eq_event (op1, op2)
      if op1 == op2 then   -- primitive equal?
        return true   -- values are equal
      end
      -- try metamethod
      local h = getequalhandler(op1, op2)
      if h then
        return not not h(op1, op2)
      else
        return false
      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 h = getbinhandler(op1, op2, "__lt")
        if h then
          return not not h(op1, op2)
        else
          error(···)
        end
      end
    end

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

  • "le": операция <=.
    function le_event (op1, op2)
      if type(op1) == "number" and type(op2) == "number" then
        return op1 <= op2   -- numeric comparison
      elseif type(op1) == "string" and type(op2) == "string" then
        return op1 <= op2   -- lexicographic comparison
      else
        local h = getbinhandler(op1, op2, "__le")
        if h then
          return not not h(op1, op2)
        else
          h = getbinhandler(op1, op2, "__lt")
          if h then
            return not h(op2, op1)
          else
            error(···)
          end
        end
      end
    end

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

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

  • "index": Доступ по индексу table[key]. Обратите внимание, что метаметод используется только тогда, когда key отсутствует в table. (Когда table не является таблицей, никакой ключ никогда не присутствует, поэтому метаметод всегда используется.)
    function gettable_event (table, key)
      local h
      if type(table) == "table" then
        local v = rawget(table, key)
        -- if key is present, return raw value
        if v ~= nil then return v end
        h = metatable(table).__index
        if h == nil then return nil end
      else
        h = metatable(table).__index
        if h == nil then
          error(···)
        end
      end
      if type(h) == "function" then
        return (h(table, key))     -- call the handler
      else return h[key]           -- or repeat operation on it
      end
    end
  • "newindex": Присвоение по индексу table[key] = value. Обратите внимание, что метаметод используется только тогда, когда key отсутствует в table.
    function settable_event (table, key, value)
      local h
      if type(table) == "table" then
        local v = rawget(table, key)
        -- if key is present, do raw assignment
        if v ~= nil then rawset(table, key, value); return end
        h = metatable(table).__newindex
        if h == nil then rawset(table, key, value); return end
      else
        h = metatable(table).__newindex
        if h == nil then
          error(···)
        end
      end
      if type(h) == "function" then
        h(table, key,value)           -- call the handler
      else h[key] = value             -- or repeat operation on it
      end
    end
  • "call": вызывается, когда Lua вызывает значение.
    function function_event (func, ...)
      if type(func) == "function" then
        return func(...)   -- primitive call
      else
        local h = metatable(func).__call
        if h then
          return h(func, ...)
        else
          error(···)
        end
      end
    end

2.5 – Сбор мусора

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

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

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

Множитель шага сборщика мусора контролирует относительную скорость сборщика по отношению к выделению памяти. Более высокие значения делают сборщик более агрессивным, но также увеличивают размер каждого инкрементального шага. Значения меньше 100 делают сборщик слишком медленным и могут привести к тому, что сборщик никогда не завершит цикл. По умолчанию значение 200, что означает, что сборщик работает в "два раза" быстрее, чем выделение памяти.

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

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

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

2.5.1 – Метаметоды сбора мусора

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

Чтобы объект (таблица или пользовательские данные) был финализирован при сборе, его необходимо пометить для финализации. Вы помечаете объект для финализации, когда вы устанавливаете его метатаблицу, и в метатаблице есть поле, индексированное строкой "__gc". Обратите внимание, что если вы установите метатаблицу без поля __gc и позже создадите это поле в метатаблице, объект не будет помечен для финализации. Однако после того, как объект помечен, вы можете свободно изменять поле __gc его метатаблицы.

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

function gc_event (obj)
  local h = metatable(obj).__gc
  if type(h) == "function" then
    h(obj)
  end
end

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

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

При закрытии состояния (см. lua_close) Lua вызывает финализаторы всех объектов, помеченных для финализации, в обратном порядке, в котором они были помечены. Если какой-либо финализатор отмечает новые объекты для сбора во время этой фазы, эти новые объекты не будут финализированы.

2.5.2 – Слабые таблицы

Слабая таблица — это таблица, элементы которой являются слабыми ссылками. Слабая ссылка игнорируется сборщиком мусора. Другими словами, если единственными ссылками на объект являются слабые ссылки, сборщик мусора соберет этот объект.

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

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

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

Из слабых таблиц удаляются только объекты, имеющие явное построение. Значения, такие как числа и лёгкие C-функции, не подлежат сборке мусора и, следовательно, не удаляются из слабых таблиц (если не удаляется связанное с ними значение). Хотя строки подлежат сборке мусора, они не имеют явного построения и, следовательно, не удаляются из слабых таблиц.

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

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

2.6 – Корутины

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

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

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

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

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

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

В качестве примера работы корутин рассмотрим следующий код:

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

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

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

При его выполнении он выведет следующий результат:

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

Вы также можете создавать и управлять корутинами через API на C: см. функции lua_newthread, lua_resume и lua_yield.

3 – Язык

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

Конструкции языка будут объяснены с использованием обычной расширенной нотации БНФ, в которой {a} означает 0 или более a, а [a] — необязательное a. Нетерминалы показаны как нетерминал, ключевые слова показаны как kword, а другие терминальные символы — как ‘=’.

Полный синтаксис Lua можно найти в §9 в конце данного руководства.

3.1 – Лексические соглашения

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

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

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

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

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

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

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

Литеральные строки могут быть ограничены совпадающими одинарными или двойными кавычками и могут содержать следующие подобные C последовательности escape: '\a' (звонок), '\b' (backspace), '\f' (form feed), '\n' (новая строка), '\r' (возврат каретки), '\t' (горизонтальная табуляция), '\v' (вертикальная табуляция), '\\' (обратный слэш), '\"' (знак кавычек [двойная кавычка]), и '\'' (апостроф [одинарная кавычка]). Обратный слэш, за которым следует реальная новая строка, приводит к новой строке в строке. Последовательность escape '\z' пропускает следующий пробел, включая символы перевода строки; это особенно полезно для разбиения и отступа длинной литеральной строки на несколько строк без добавления новых строк и пробелов в содержимое строки.

Байт в литеральной строке также может быть указан по его числовому значению. Это можно сделать с помощью последовательности escape \xXX, где XX — последовательность ровно двух шестнадцатеричных цифр, или с помощью последовательности escape \ddd, где ddd — последовательность от 0 до 3 десятичных цифр. (Обратите внимание, что если за десятичной escape последовательностью должна следовать цифра, она должна быть выражена ровно тремя цифрами.) Строки в Lua могут содержать любое 8-битовое значение, включая вложенные нули, которые могут быть указаны как '\0'.

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

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

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

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

Числовое значение может быть записано с необязательной дробной частью и необязательным десятичным показателем, обозначенным буквой 'e' или 'E'. Lua также принимает шестнадцатеричные константы, которые начинаются с 0x или 0X. Шестнадцатеричные константы также принимают необязательную дробную часть плюс необязательный двоичный показатель, обозначенный буквой 'p' или 'P'. Примеры допустимых числовых констант:

3     3.0     3.1416     314.16e-2     0.31416E1
0xff  0x0.1E  0xA23p-4   0X1.921FB54442D18P+1

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

3.2 – Переменные

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

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

var ::= Name

Имя обозначает идентификаторы, как определено в §3.1.

Любое имя переменной предполагается глобальным, если явно не объявлено как локальное (см. §3.3.7). Локальные переменные имеют лексическую область видимости: локальные переменные могут свободно использоваться функциями, определёнными внутри их области видимости (см. §3.5).

Перед первой привязкой значения к переменной её значение равно nil.

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

var ::= prefixexp ‘[’ exp ‘]’

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

Синтаксис var.Name — это просто синтаксический сахар для var["Name"]:

var ::= prefixexp ‘.’ Name

Доступ к глобальной переменной x эквивалентен _ENV.x. Из-за способа компиляции блоков _ENV никогда не является глобальным именем (см. §2.2).

3.3 – Операторы

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

3.3.1 – Блоки

Блок — это список операторов, выполняемых последовательно:

block ::= {stat}

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

stat ::= ‘;’

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

a = b + c
(print or io.write)('done')

Грамматика может интерпретировать его двумя способами:

a = b + c(print or io.write)('done')

a = b + c; (print or io.write)('done')

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

;(print or io.write)('done')

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

stat ::= do block end

Явные блоки полезны для управления областью видимости объявления переменных. Явные блоки также иногда используются для добавления оператора return в середине другого блока (см. §3.3.4).

3.3.2 – Блоки кода

Единицей компиляции в Lua является блок кода. Синтаксически блок кода — это просто блок:

chunk ::= block

Lua обрабатывает блок кода как тело анонимной функции с переменным числом аргументов (см. §3.4.10). Таким образом, блоки кода могут определять локальные переменные, получать аргументы и возвращать значения. Более того, такая анонимная функция компилируется в области видимости внешней локальной переменной, называемой _ENV (см. §2.2). Результирующая функция всегда имеет _ENV в качестве единственного значения upvalue, даже если она не использует эту переменную.

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

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

3.3.3 – Присваивание

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

stat ::= varlist ‘=’ explist
varlist ::= var {‘,’ var}
explist ::= exp {‘,’ exp}

Выражения обсуждаются в §3.4.

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

Оператор присваивания сначала вычисляет все свои выражения, и только затем выполняются присваивания. Таким образом, код

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

устанавливает a[3] в 20, не влияя на a[4], потому что i в a[i] вычисляется (до 3), прежде чем ему присваивается 4. Аналогично, строка

x, y = y, x

меняет значения x и y, а

x, y, z = y, z, x

циклически переставляет значения x, y, и z.

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

Присваивание глобальной переменной x = val эквивалентно присваиванию _ENV.x = val (см. §2.2).

3.3.4 – Управляющие структуры

Управляющие структуры if, while и repeat имеют обычное значение и знакомый синтаксис:

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

Lua также имеет оператор for, в двух вариантах (см. §3.3.5).

Выражение условия управляющей структуры может возвращать любое значение. Как false, так и nil считаются ложными. Все значения, отличные от nil и false, считаются истинными (в частности, число 0 и пустая строка также являются истинными).

В цикле repeat–until внутренний блок не заканчивается на ключевом слове until, а только после условия. Таким образом, условие может ссылаться на локальные переменные, объявленные внутри блока цикла.

Оператор goto передает управление программе метке. По синтаксическим соображениям, метки в Lua также считаются операторами:

stat ::= goto Name
stat ::= label
label ::= ‘::’ Name ‘::’

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

Метки и пустые операторы называются пустыми операторами, так как они не выполняют никаких действий.

Оператор break завершает выполнение цикла while, repeat или for, переходя к следующему оператору после цикла:

stat ::= break

break завершает ближайший вложенный цикл.

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

stat ::= return [explist] [‘;’]

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

3.3.5 – Оператор For

Оператор for имеет две формы: числовую и общую.

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

stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end

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

for v = e1, e2, e3 do block end

эквивалентен следующему коду:

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

Обратите внимание на следующее:

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

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

stat ::= for namelist in explist do block end
namelist ::= Name {‘,’ Name}

Оператор for, такой как

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

эквивалентен следующему коду:

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

Обратите внимание на следующее:

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

3.3.6 – Вызовы функций как операторы

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

stat ::= functioncall

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

3.3.7 – Объявление локальных переменных

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

stat ::= local namelist [‘=’ explist]

Если присутствует начальное присваивание, оно имеет те же семантику, что и множественное присваивание (см. §3.3.3). В противном случае все переменные инициализируются nil.

Блок кода также является блоком (см. §3.3.2), и поэтому локальные переменные могут быть объявлены в блоке кода вне любого явного блока.

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

3.4 – Выражения

Основные выражения в Lua следующие:

exp ::= prefixexp
exp ::= nil | false | true
exp ::= Number
exp ::= String
exp ::= functiondef
exp ::= tableconstructor
exp ::= ‘...’
exp ::= exp binop exp
exp ::= unop exp
prefixexp ::= var | functioncall | ‘(’ exp ‘)’

Числа и литеральные строки объяснены в §3.1; переменные объяснены в §3.2; определения функций объяснены в §3.4.10; вызовы функций объяснены в §3.4.9; конструкторы таблиц объяснены в §3.4.8. Выражения vararg, обозначаемые тремя точками ('...'), могут использоваться только непосредственно внутри функции vararg; они объяснены в §3.4.10.

Бинарные операторы включают арифметические операторы (см. §3.4.1), реляционные операторы (см. §3.4.3), логические операторы (см. §3.4.4) и оператор конкатенации (см. §3.4.5). Унарные операторы включают унарный минус (см. §3.4.1), унарный not (см. §3.4.4) и унарный оператор длины (см. §3.4.6).

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

Вот несколько примеров:

f()                -- adjusted to 0 results
g(f(), x)          -- f() is adjusted to 1 result
g(x, f())          -- g gets x plus all results from f()
a,b,c = f(), x     -- f() is adjusted to 1 result (c gets nil)
a,b = ...          -- a gets the first vararg parameter, b gets
                   -- the second (both a and b can get nil if there
                   -- is no corresponding vararg parameter)

a,b,c = x, f()     -- f() is adjusted to 2 results
a,b,c = f()        -- f() is adjusted to 3 results
return f()         -- returns all results from f()
return ...         -- returns all received vararg parameters
return x,y,f()     -- returns x, y, and all results from f()
{f()}              -- creates a list with all results from f()
{...}              -- creates a list with all vararg parameters
{f(), nil}         -- f() is adjusted to 1 result

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

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

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

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

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

3.4.2 – Преобразование типов

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

3.4.3 – Операторы сравнения

Операторы сравнения в Lua:

==    ~=    <     >     <=    >=

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

Оператор равенства (==) сначала сравнивает типы своих операндов. Если типы разные, результат — false. В противном случае сравниваются значения операндов. Числа и строки сравниваются обычным способом. Таблицы, пользовательские данные и потоки сравниваются по ссылке: два объекта считаются равными только в том случае, если они являются одним и тем же объектом. Каждый раз, когда вы создаёте новый объект (таблицу, пользовательские данные или поток), этот новый объект отличается от любого ранее существовавшего объекта. Закрытия с одной и той же ссылкой всегда равны. Закрытия с любыми различимыми особенностями (разное поведение, разное определение) всегда разные.

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

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

Оператор ~= — это просто отрицание равенства (==).

Операторы порядка работают следующим образом. Если оба аргумента являются числами, они сравниваются как числа. В противном случае, если оба аргумента являются строками, их значения сравниваются в соответствии с текущей локалью. В противном случае Lua пытается вызвать метаметод "lt" или "le" (см. §2.4). Сравнение a > b переводится в b < a, а a >= b — в b <= a.

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

Логические операторы в Lua — это and, or и not. Как и управляющие структуры (см. §3.3.4), все логические операторы рассматривают как false, так и nil как ложь, а все остальное — как истину.

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

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

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

3.4.5 – Конкатенация

Оператор конкатенации строк в Lua обозначается двумя точками ('..'). Если оба операнда являются строками или числами, они преобразуются в строки в соответствии с правилами, упомянутыми в §3.4.2. В противном случае вызывается метаметод __concat (см. §2.4).

3.4.6 – Оператор длины

Оператор длины обозначается унарным префиксным оператором #. Длина строки — это количество байтов (то есть, обычное значение длины строки, когда каждый символ — один байт).

Программа может изменить поведение оператора длины для любого значения, кроме строк, через метаметод __len (см. §2.4).

Если не задан метаметод __len, длина таблицы t определена только в том случае, если таблица является последовательностью, то есть множество её положительных числовых ключей равно {1..n} для некоторого неотрицательного целого числа n. В этом случае n является её длиной. Обратите внимание, что таблица, подобная

{10, 20, nil, 40}

не является последовательностью, потому что она имеет ключ 4, но не имеет ключа 3. (Поэтому нет такого n, что множество {1..n} равно множеству положительных числовых ключей этой таблицы.) Заметьте, однако, что нечисловые ключи не влияют на то, является ли таблица последовательностью.

3.4.7 – Приоритет

Приоритет операторов в Lua следует следующей таблице, от низшего к высшему приоритету:

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

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

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

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

tableconstructor ::= ‘{’ [fieldlist] ‘}’
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
fieldsep ::= ‘,’ | ‘;’

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

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

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

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

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

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

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

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

functioncall ::= prefixexp args

При вызове функции сначала вычисляются prefixexp и args. Если значение prefixexp имеет тип функция, то эта функция вызывается с заданными аргументами. В противном случае вызывается метаметод "call" prefixexp, имеющий в качестве первого параметра значение prefixexp, за которым следуют исходные аргументы вызова (см. §2.4).

Форма

functioncall ::= prefixexp ‘:’ Name args

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

Аргументы имеют следующий синтаксис:

args ::= ‘(’ [explist] ‘)’
args ::= tableconstructor
args ::= String

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

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

return (f(x))        -- results adjusted to 1
return 2 * f(x)
return x, f(x)       -- additional results
f(x); return         -- results discarded
return x or f(x)     -- results adjusted to 1

3.4.10 – Определения функций

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

functiondef ::= function funcbody
funcbody ::= ‘(’ [parlist] ‘)’ block end

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

stat ::= function funcname funcbody
stat ::= local function Name funcbody
funcname ::= Name {‘.’ Name} [‘:’ Name]

Оператор

function f () body end

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

f = function () body end

Оператор

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

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

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

Оператор

local function f () body end

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

local f; f = function () body end

а не

local f = function () body end

(Это имеет значение только в том случае, если тело функции содержит ссылки на f.)

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

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

parlist ::= namelist [‘,’ ‘...’] | ‘...’

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

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

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

Тогда у нас есть следующее отображение аргументов на параметры и на выражение vararg:

CALL            PARAMETERS

f(3)             a=3, b=nil
f(3, 4)          a=3, b=4
f(3, 4, 5)       a=3, b=4
f(r(), 10)       a=1, b=10
f(r())           a=1, b=2

g(3)             a=3, b=nil, ... -->  (nothing)
g(3, 4)          a=3, b=4,   ... -->  (nothing)
g(3, 4, 5, 8)    a=3, b=4,   ... -->  5  8
g(5, r())        a=5, b=1,   ... -->  2  3

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

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

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

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

является синтаксическим сахаром для

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

3.5 – Правила видимости

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

x = 10                -- global variable
do                    -- new block
  local x = x         -- new 'x', with value 10
  print(x)            --> 10
  x = x+1
  do                  -- another block
    local x = x+1     -- another 'x'
    print(x)          --> 12
  end
  print(x)            --> 11
end
print(x)              --> 10  (the global one)

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

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

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

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

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

4 – Интерфейс прикладной программы

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

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

Как и во многих C библиотеках, функции Lua API не проверяют свои аргументы на корректность и согласованность. Однако вы можете изменить это поведение, скомпилировав Lua с определённым макросом LUA_USE_APICHECK.

4.1 – Стек

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

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

Для удобства большинство операций запроса в API не следуют строгой дисциплине стека. Вместо этого они могут ссылаться на любой элемент стека с помощью индекса: Положительный индекс представляет абсолютную позицию в стеке (начиная с 1); отрицательный индекс представляет смещение относительно вершины стека. Более конкретно, если стек содержит n элементов, то индекс 1 представляет первый элемент (то есть элемент, который был помещён в стек первым), а индекс n представляет последний элемент; индекс -1 также представляет последний элемент (то есть элемент на вершине) и индекс -n представляет первый элемент.

4.2 – Размер стека

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

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

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

4.3 – Действительные и допустимые индексы

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

Действительный индекс — это индекс, который ссылается на реальную позицию в стеке, то есть его позиция лежит между 1 и вершиной стека (1 ≤ abs(index) ≤ top). Обычно функции, которые могут изменять значение по индексу, требуют действительных индексов.

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

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

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

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

4.4 – C Замыкания

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

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

4.5 – Регистр

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

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

При создании нового состояния Lua его реестр поставляется с некоторыми предопределёнными значениями. Эти предопределённые значения индексируются целочисленными ключами, определёнными как константы в lua.h. Следующие константы определены:

  • LUA_RIDX_MAINTHREAD: По этому индексу в реестре находится главный поток состояния. (Главный поток — это тот, который создаётся вместе с состоянием.)
  • LUA_RIDX_GLOBALS: По этому индексу в реестре находится глобальная среда.

4.6 – Обработка ошибок в C

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

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

Функция паники выполняется так, как будто это обработчик сообщений (см. §2.3); в частности, сообщение об ошибке находится вверху стека. Однако нет гарантий относительно пространства стека. Чтобы поместить что-либо в стек, функция паники должна сначала проверить доступное пространство (см. §4.2).

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

Внутри функции C вы можете сгенерировать ошибку, вызвав lua_error.

4.7 – Обработка приостановок в C

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

Чтобы избежать этого типа проблем, Lua генерирует ошибку всякий раз, когда пытается приостановить выполнение через вызов API, за исключением трёх функций: lua_yieldk, lua_callk и lua_pcallk. Все эти функции принимают функцию продолжения (как параметр, называемый k) для продолжения выполнения после приостановки.

Нам нужно установить некоторую терминологию, чтобы объяснить продолжения. У нас есть функция C, вызываемая из Lua, которую мы будем называть исходной функцией. Эта исходная функция затем вызывает одну из этих трёх функций в C API, которую мы будем называть функцией вызова, которая затем приостанавливает выполнение текущей нити. (Это может произойти, когда функция вызова является lua_yieldk, или когда функция вызова является либо lua_callk, либо lua_pcallk, и вызываемая ими функция приостанавливает выполнение.)

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

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

Единственное различие в состоянии Lua между исходной функцией и её функцией продолжения — результат вызова lua_getctx.

4.8 – Функции и типы[-o, +p, x]

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

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

lua_absindex[-0, +0, –]

int lua_absindex (lua_State *L, int idx);

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

lua_Alloc

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

Тип функции выделения памяти, используемой состояниями Lua. Функция-аллокатор должна обеспечивать функциональность, аналогичную realloc, но не точно такую же. Её аргументы — ud, неявный указатель, переданный lua_newstate; ptr, указатель на блок, который выделяется/перевыделяется/освобождается; osize, исходный размер блока или некоторый код, относящийся к тому, что выделяется; nsize, новый размер блока.

Когда ptr не равно NULL, osize — это размер блока, на который указывает ptr, то есть размер, заданный при его выделении или перевыделении.

Когда ptr равно NULL, osize кодирует тип объекта, который Lua выделяет. osize может принимать значения LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA или LUA_TTHREAD при (и только при) создании Lua нового объекта этого типа. Когда osize принимает другое значение, Lua выделяет память для чего-то другого.

Lua предполагает следующее поведение от функции-аллокатора:

Когда nsize равно нулю, аллокатор должен вести себя как free и возвращать NULL.

Когда nsize не равно нулю, аллокатор должен вести себя как realloc. Аллокатор возвращает NULL только в том случае, если он не может выполнить запрос. Lua предполагает, что аллокатор никогда не терпит неудачу, когда osize >= nsize.

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

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

Обратите внимание, что стандартный C гарантирует, что free(NULL) не имеет эффекта и что realloc(NULL, size) эквивалентно malloc(size). Этот код предполагает, что realloc не терпит неудачу при уменьшении размера блока. (Хотя стандартный C не гарантирует этого поведения, это кажется разумным предположением.)

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

void lua_arith (lua_State *L, int op);

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

Значение op должно быть одним из следующих констант:

  • LUA_OPADD: выполняет сложение (+)
  • LUA_OPSUB: выполняет вычитание (-)
  • LUA_OPMUL: выполняет умножение (*)
  • LUA_OPDIV: выполняет деление (/)
  • LUA_OPMOD: выполняет операцию modulo (%)
  • LUA_OPPOW: выполняет возведение в степень (^)
  • LUA_OPUNM: выполняет математическое отрицание (унарное -)

lua_atpanic[-0, +0, –]

lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);

Устанавливает новую функцию обработки паники и возвращает старую (см. §4.6).

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

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

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

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

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

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

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

Вот он на C:

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

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

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

void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
                lua_CFunction k);

Эта функция ведет себя точно так же, как lua_call, но позволяет вызываемой функции уступать выполнение (см. §4.7).

lua_CFunction

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

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

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

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

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

lua_checkstack[-0, +0, –]

int lua_checkstack (lua_State *L, int extra);

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

lua_close[-0, +0, –]

void lua_close (lua_State *L);

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

lua_compare[-0, +0, e]

int lua_compare (lua_State *L, int index1, int index2, int op);

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

Значение op должно быть одним из следующих констант:

  • LUA_OPEQ: сравнивает на равенство (==)
  • LUA_OPLT: сравнивает на меньше чем (<)
  • LUA_OPLE: сравнивает на меньше или равно (<=)

lua_concat[-n, +1, e]

void lua_concat (lua_State *L, int n);

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

lua_copy[-0, +0, –]

void lua_copy (lua_State *L, int fromidx, int toidx);

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

lua_createtable[-0, +1, e]

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

Создаёт новую пустую таблицу и помещает её на стек. Параметр narr указывает предполагаемое количество элементов в последовательности; параметр nrec — предполагаемое количество других элементов. Lua может использовать эти подсказки для предварительной выделения памяти для новой таблицы. Это предварительное выделение памяти полезно для производительности, если заранее известно, сколько элементов будет содержать таблица. В противном случае можно использовать функцию lua_newtable.

lua_dump[-0, +0, e]

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

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

Возвращаемое значение — код ошибки, возвращённый последним вызовом функции записи; 0 означает отсутствие ошибок.

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

lua_error[-1, +0, v]

int lua_error (lua_State *L);

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

lua_gc[-0, +0, e]

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

Управляет сборщиком мусора.

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

  • LUA_GCSTOP: останавливает сборщик мусора.
  • LUA_GCRESTART: возобновляет сборщик мусора.
  • LUA_GCCOLLECT: выполняет полный цикл сбора мусора.
  • LUA_GCCOUNT: возвращает текущее количество используемой памяти (в Кбайтах) Lua.
  • LUA_GCCOUNTB: возвращает остаток от деления текущего количества байтов используемой памяти Lua на 1024.
  • LUA_GCSTEP: выполняет инкрементный шаг сбора мусора. Размер шага контролируется data (большие значения означают больше шагов) непредсказуемым образом. Если вы хотите контролировать размер шага, вам нужно экспериментально настроить значение data. Функция возвращает 1, если шаг завершил цикл сбора мусора.
  • LUA_GCSETPAUSE: устанавливает data как новое значение паузы сборщика (см. §2.5). Функция возвращает предыдущее значение паузы.
  • LUA_GCSETSTEPMUL: устанавливает data как новое значение множителя шага сборщика (см. §2.5). Функция возвращает предыдущее значение множителя шага.
  • LUA_GCISRUNNING: возвращает логическое значение, указывающее, работает ли сборщик мусора (т.е. не остановлен).
  • LUA_GCGEN: меняет сборщик на генерационный режим (см. §2.5).
  • LUA_GCINC: меняет сборщик на инкрементальный режим. Это — режим по умолчанию.

Более подробную информацию об этих опциях см. в collectgarbage.

lua_getallocf[-0, +0, –]

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

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

lua_getctx[-0, +0, –]

int lua_getctx (lua_State *L, int *ctx);

Эта функция вызывается функцией продолжения (см. §4.7) для получения состояния потока и контекстной информации.

При вызове в исходной функции lua_getctx всегда возвращает LUA_OK и не изменяет значение своего аргумента ctx. При вызове внутри функции продолжения lua_getctx возвращает LUA_YIELD и устанавливает значение ctx в контекстную информацию (значение, переданное в качестве аргумента ctx вызываемой функции вместе с функцией продолжения).

Когда вызываемой функцией является lua_pcallk, Lua может также вызвать свою функцию продолжения для обработки ошибок во время вызова. То есть при ошибке в функции, вызываемой lua_pcallk, Lua может не вернуться к исходной функции, а вместо этого может вызвать функцию продолжения. В этом случае вызов lua_getctx вернёт код ошибки (значение, которое вернула бы lua_pcallk); значение ctx будет установлено в контекстную информацию, как и в случае с приостановкой.

lua_getfield[-0, +1, e]

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

Помещает на стек значение t[k], где t — значение по заданному индексу. Как и в Lua, эта функция может вызвать метаметод для события "индекса" (см. §2.4).

lua_getglobal[-0, +1, e]

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

Помещает на стек значение глобальной переменной name.

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

int lua_getmetatable (lua_State *L, int index);

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

lua_gettable[-1, +1, e]

void lua_gettable (lua_State *L, int index);

Помещает на стек значение t[k], где t — значение по заданному индексу, а k — значение в верхней части стека.

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

lua_gettop[-0, +0, –]

int lua_gettop (lua_State *L);

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

lua_getuservalue[-0, +1, –]

void lua_getuservalue (lua_State *L, int index);

Помещает на стек Lua-значение, связанное с пользовательской переменной данных по заданному индексу. Это Lua-значение должно быть таблицей или nil.

lua_insert[-1, +1, –]

void lua_insert (lua_State *L, int index);

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

lua_Integer

typedef ptrdiff_t lua_Integer;

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

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

lua_isboolean[-0, +0, –]

int lua_isboolean (lua_State *L, int index);

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

lua_iscfunction[-0, +0, –]

int lua_iscfunction (lua_State *L, int index);

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

lua_isfunction[-0, +0, –]

int lua_isfunction (lua_State *L, int index);

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

lua_islightuserdata[-0, +0, –]

int lua_islightuserdata (lua_State *L, int index);

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

lua_isnil[-0, +0, –]

int lua_isnil (lua_State *L, int index);

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

lua_isnone[-0, +0, –]

int lua_isnone (lua_State *L, int index);

Возвращает 1, если заданный индекс недействителен, и 0 в противном случае.

lua_isnoneornil[-0, +0, –]

int lua_isnoneornil (lua_State *L, int index);

Возвращает 1, если заданный индекс недействителен или значение по этому индексу равно nil, и 0 в противном случае.

lua_isnumber[-0, +0, –]

int lua_isnumber (lua_State *L, int index);

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

lua_isstring[-0, +0, –]

int lua_isstring (lua_State *L, int index);

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

lua_istable[-0, +0, –]

int lua_istable (lua_State *L, int index);

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

lua_isthread[-0, +0, –]

int lua_isthread (lua_State *L, int index);

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

lua_isuserdata[-0, +0, –]

int lua_isuserdata (lua_State *L, int index);

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

lua_len[-0, +1, e]

void lua_len (lua_State *L, int index);

Возвращает "длину" значения по заданному индексу; эквивалентно оператору '#' в Lua (см. §3.4.6). Результат помещается на стек.

lua_load[-0, +1, –]

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

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

Возвращаемые значения lua_load:

  • LUA_OK: нет ошибок;
  • LUA_ERRSYNTAX: синтаксическая ошибка при предварительной компиляции;
  • LUA_ERRMEM: ошибка выделения памяти;
  • LUA_ERRGCMM: ошибка при выполнении метаметода __gc. (Эта ошибка не связана с загружаемым фрагментом. Она генерируется сборщиком мусора.)

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

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

lua_load автоматически определяет, является ли фрагмент текстовым или двоичным, и загружает его соответственно (см. программу luac). Строка mode работает так же, как и в функции load, с добавлением того, что значение NULL эквивалентно строке "bt".

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

Если полученная функция имеет одну локальную переменную, эта локальная переменная устанавливается в значение глобальной среды, хранящейся по индексу LUA_RIDX_GLOBALS в реестре (см. §4.5). При загрузке основных фрагментов эта локальная переменная будет переменной _ENV (см. §2.2).

lua_newstate[-0, +0, –]

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

Создаёт новый поток, выполняющийся в новом независимом состоянии. Возвращает NULL, если не удаётся создать поток или состояние (из-за нехватки памяти). Аргумент f — функция выделения памяти; Lua выполняет все выделения памяти для этого состояния через эту функцию. Второй аргумент, ud, — неопределённый указатель, который Lua передаёт выделению памяти при каждом вызове.

lua_newtable[-0, +1, e]

void lua_newtable (lua_State *L);

Создаёт новую пустую таблицу и помещает её в стек. Это эквивалентно lua_createtable(L, 0, 0).

lua_newthread[-0, +1, e]

lua_State *lua_newthread (lua_State *L);

Создаёт новый поток, помещает его в стек и возвращает указатель на lua_State, который представляет этот новый поток. Новый поток, возвращаемый этой функцией, разделяет с исходным потоком глобальную среду, но имеет независимый стек выполнения.

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

lua_newuserdata[-0, +1, e]

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

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

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

int lua_next (lua_State *L, int index);

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

Типичный обход выглядит так:

/* table is in the stack at index 't' */
lua_pushnil(L);  /* first key */
while (lua_next(L, t) != 0) {
  /* uses 'key' (at index -2) and 'value' (at index -1) */
  printf("%s - %s\n",
         lua_typename(L, lua_type(L, -2)),
         lua_typename(L, lua_type(L, -1)));
  /* removes 'value'; keeps 'key' for next iteration */
  lua_pop(L, 1);
}

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

См. функцию next для замечаний о модификации таблицы во время её обхода.

lua_Number

typedef double lua_Number;

Тип чисел в Lua. По умолчанию это double, но это можно изменить в luaconf.h. С помощью этого конфигурационного файла можно изменить Lua, чтобы он работал с другим типом чисел (например, float или long).

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

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

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

И nargs, и nresults имеют то же значение, что и в lua_call. Если при вызове ошибок не возникает, lua_pcall ведёт себя точно так же, как lua_call. Однако, если возникает какая-либо ошибка, lua_pcall перехватывает её, помещает единственное значение в стек (сообщение об ошибке) и возвращает код ошибки. Как и lua_call, lua_pcall всегда удаляет функцию и её аргументы из стека.

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

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

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

  • LUA_OK (0): успех.
  • LUA_ERRRUN: ошибка выполнения.
  • LUA_ERRMEM: ошибка выделения памяти. В таких случаях Lua не вызывает обработчик сообщений.
  • LUA_ERRERR: ошибка при выполнении обработчика сообщений.
  • LUA_ERRGCMM: ошибка при выполнении метаметода __gc. (Эта ошибка обычно не связана с вызываемой функцией. Она генерируется сборщиком мусора.)

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

int lua_pcallk (lua_State *L,
                int nargs,
                int nresults,
                int errfunc,
                int ctx,
                lua_CFunction k);

Эта функция работает точно так же, как lua_pcall, но позволяет вызываемой функции приостанавливаться (см. §4.7).

lua_pop[-n, +0, –]

void lua_pop (lua_State *L, int n);

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

lua_pushboolean[-0, +1, –]

void lua_pushboolean (lua_State *L, int b);

Помещает булевое значение со значением b в стек.

lua_pushcclosure[-n, +1, e]

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

Помещает новую C-замыкание в стек.

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

Максимальное значение для n составляет 255.

Когда n равно нулю, эта функция создаёт лёгкую C-функцию, которая представляет собой просто указатель на C-функцию. В этом случае ошибка памяти никогда не возникает.

lua_pushcfunction[-0, +1, –]

void lua_pushcfunction (lua_State *L, lua_CFunction f);

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

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

lua_pushcfunction определяется как макрос:

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

Обратите внимание, что f используется дважды.

lua_pushfstring[-0, +1, e]

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

Помещает в стек отформатированную строку и возвращает указатель на эту строку. Она похожа на функцию ISO C sprintf, но имеет некоторые важные отличия:

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

lua_pushglobaltable[-0, +1, –]

void lua_pushglobaltable (lua_State *L);

Помещает глобальную среду в стек.

lua_pushinteger[-0, +1, –]

void lua_pushinteger (lua_State *L, lua_Integer n);

Помещает число со значением n в стек.

lua_pushlightuserdata[-0, +1, –]

void lua_pushlightuserdata (lua_State *L, void *p);

Помещает лёгкие пользовательские данные в стек.

Пользовательские данные представляют C-значения в Lua. Лёгкие пользовательские данные представляют указатель, C-значение. Это значение (как число): вы его не создаёте, у него нет индивидуального метатаблицы, и оно не собирается мусор (поскольку никогда не создавалось). Лёгкие пользовательские данные равны «любым» лёгким пользовательским данным с тем же C-адресом.

lua_pushliteral[-0, +1, e]

const char *lua_pushliteral (lua_State *L, const char *s);

Этот макрос эквивалентен lua_pushlstring, но может использоваться только когда s — это строковая литерал. Он автоматически предоставляет длину строки.

lua_pushlstring[-0, +1, e]

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

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

Возвращает указатель на внутреннюю копию строки.

lua_pushnil[-0, +1, –]

void lua_pushnil (lua_State *L);

Помещает значение nil в стек.

lua_pushnumber[-0, +1, –]

void lua_pushnumber (lua_State *L, lua_Number n);

Помещает число со значением n в стек.

lua_pushstring[-0, +1, e]

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

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

Возвращает указатель на внутреннюю копию строки.

Если s равно NULL, то выталкивает nil и возвращает NULL.

lua_pushthread[-0, +1, –]

int lua_pushthread (lua_State *L);

Выталкивает на стек поток, представленный L. Возвращает 1, если этот поток является основным потоком его состояния.

lua_pushunsigned[-0, +1, –]

void lua_pushunsigned (lua_State *L, lua_Unsigned n);

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

lua_pushvalue[-0, +1, –]

void lua_pushvalue (lua_State *L, int index);

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

lua_pushvfstring[-0, +1, e]

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

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

lua_rawequal[-0, +0, –]

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

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

lua_rawget[-1, +1, –]

void lua_rawget (lua_State *L, int index);

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

lua_rawgeti[-0, +1, –]

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

Выталкивает на стек значение t[n], где t - таблица по заданному индексу. Доступ является прямым; то есть, он не вызывает метаметоды.

lua_rawgetp[-0, +1, –]

void lua_rawgetp (lua_State *L, int index, const void *p);

Выталкивает на стек значение t[k], где t - таблица по заданному индексу, а k - указатель p, представленный как лёгкое пользовательское данные. Доступ является прямым; то есть, он не вызывает метаметоды.

lua_rawlen[-0, +0, –]

size_t lua_rawlen (lua_State *L, int index);

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

lua_rawset[-2, +0, e]

void lua_rawset (lua_State *L, int index);

Аналогично lua_settable, но выполняет присваивание без метаметодов.

lua_rawseti[-1, +0, e]

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

Выполняет эквивалент t[n] = v, где t - таблица по заданному индексу, а v - значение сверху стека.

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

lua_rawsetp[-1, +0, e]

void lua_rawsetp (lua_State *L, int index, const void *p);

Выполняет эквивалент t[k] = v, где t - таблица по заданному индексу, k - указатель p в виде лёгких пользовательских данных, а v - значение сверху стека.

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

lua_Reader

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

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

lua_register[-0, +0, e]

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

Устанавливает C-функцию f в качестве нового значения глобальной переменной name. Она определена как макрос:

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

lua_remove[-1, +0, –]

void lua_remove (lua_State *L, int index);

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

lua_replace[-1, +0, –]

void lua_replace (lua_State *L, int index);

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

lua_resume[-?, +?, –]

int lua_resume (lua_State *L, lua_State *from, int nargs);

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

Для запуска сопрограммы вы помещаете на стек потока основную функцию плюс любые аргументы; затем вызываете lua_resume с nargs в качестве количества аргументов. Этот вызов возвращается, когда сопрограмма приостанавливается или завершает своё выполнение. Когда он возвращается, стек содержит все значения, переданные в lua_yield, или все значения, возвращённые функцией тела. lua_resume возвращает LUA_YIELD, если сопрограмма приостанавливается, LUA_OK, если сопрограмма завершает своё выполнение без ошибок, или код ошибки в случае ошибок (см. lua_pcall).

В случае ошибок стек не разворачивается, поэтому вы можете использовать API отладки над ним. Сообщение об ошибке находится в верхней части стека.

Чтобы возобновить сопрограмму, удалите любые результаты от последнего lua_yield, поместите на её стек только значения, которые должны быть переданы как результаты из yield, а затем вызовите lua_resume.

Параметр from представляет сопрограмму, которая возобновляет L. Если такой сопрограммы нет, этот параметр может быть NULL.

lua_setallocf[-0, +0, –]

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

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

lua_setfield[-1, +0, e]

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

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

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

lua_setglobal[-1, +0, e]

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

Удаляет значение со стека и устанавливает его в качестве нового значения глобальной переменной name.

lua_setmetatable[-1, +0, –]

void lua_setmetatable (lua_State *L, int index);

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

lua_settable[-2, +0, e]

void lua_settable (lua_State *L, int index);

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

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

lua_settop[-?, +?, –]

void lua_settop (lua_State *L, int index);

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

lua_setuservalue[-1, +0, –]

void lua_setuservalue (lua_State *L, int index);

Удаляет таблицу или nil со стека и устанавливает её в качестве нового значения, связанного с пользовательскими данными по заданному индексу.

lua_State

typedef struct lua_State lua_State;

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

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

lua_status[-0, +0, –]

int lua_status (lua_State *L);

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

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

Вы можете вызывать функции только в потоках со статусом LUA_OK. Вы можете возобновить потоки со статусом LUA_OK (для запуска новой сопрограммы) или LUA_YIELD (для возобновления сопрограммы).

lua_toboolean[-0, +0, –]

int lua_toboolean (lua_State *L, int index);

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

lua_tocfunction[-0, +0, –]

lua_CFunction lua_tocfunction (lua_State *L, int index);

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

lua_tointeger[-0, +0, –]

lua_Integer lua_tointeger (lua_State *L, int index);

Эквивалентно lua_tointegerx с isnum равным NULL.

lua_tointegerx[-0, +0, –]

lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);

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

Если число не является целым, оно усекается каким-то неопределённым способом.

Если isnum не равно NULL, его референт получает булевое значение, которое указывает, выполнилась ли операция успешно.

lua_tolstring[-0, +0, e]

const char *lua_tolstring (lua_State *L, int index, size_t *len);

Преобразует значение Lua по заданному индексу в строку C. Если len не равно NULL, также устанавливает *len с длиной строки. Значение Lua должно быть строкой или числом; в противном случае функция возвращает NULL. Если значение является числом, то lua_tolstring также изменяет фактическое значение в стеке на строку. (Это изменение создаёт путаницу для lua_next, когда lua_tolstring применяется к ключам во время обхода таблицы.)

lua_tolstring возвращает полностью выровненный указатель на строку внутри состояния Lua. Эта строка всегда имеет ноль ('\0') после последнего символа (как в C), но может содержать другие нули в своём теле. Поскольку Lua имеет сборку мусора, нет гарантии, что указатель, возвращённый lua_tolstring, будет валидным после удаления соответствующего значения из стека.

lua_tonumber[-0, +0, –]

lua_Number lua_tonumber (lua_State *L, int index);

Эквивалентно lua_tonumberx с isnum равным NULL.

lua_tonumberx[-0, +0, –]

lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);

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

Если isnum не равно NULL, его ссылка получает булево значение, указывающее, был ли успешно произведён операция.

lua_topointer[-0, +0, –]

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

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

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

lua_tostring[-0, +0, e]

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

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

lua_tothread[-0, +0, –]

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

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

lua_tounsigned[-0, +0, –]

lua_Unsigned lua_tounsigned (lua_State *L, int index);

Эквивалентно lua_tounsignedx с isnum равным NULL.

lua_tounsignedx[-0, +0, –]

lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);

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

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

Если isnum не равно NULL, его ссылка получает булево значение, указывающее, был ли успешно произведён операция.

lua_touserdata[-0, +0, –]

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

Если значение по заданному индексу является полным userdata, возвращает его адрес блока. Если значение является лёгким userdata, возвращает его указатель. В противном случае, возвращает NULL.

lua_type[-0, +0, –]

int lua_type (lua_State *L, int index);

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

lua_typename[-0, +0, –]

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

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

lua_Unsigned

typedef unsigned long lua_Unsigned;

Тип, используемый API Lua для представления беззнаковых целочисленных значений. Он должен иметь по крайней мере 32 бита.

По умолчанию это unsigned int или unsigned long, какой из них может хранить 32-битные значения.

lua_upvalueindex[-0, +0, –]

int lua_upvalueindex (int i);

Возвращает псевдоиндекс, представляющий i-й замыкающий параметр запускаемой функции (см. §4.4).

lua_version[-0, +0, v]

const lua_Number *lua_version (lua_State *L);

Возвращает адрес номера версии, хранящегося в ядре Lua. При вызове с валидным lua_State, возвращает адрес версии, используемой для создания этого состояния. При вызове с NULL, возвращает адрес версии, выполняющей вызов.

lua_Writer

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

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

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

lua_xmove[-?, +?, –]

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

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

Эта функция извлекает n значения из стека from, и помещает их в стек to.

lua_yield[-?, +?, –]

int lua_yield (lua_State *L, int nresults);

Эта функция эквивалентна lua_yieldk, но не имеет продолжения (см. §4.7). Поэтому, когда поток возобновляется, он возвращается к функции, которая вызвала функцию, вызвавшую lua_yield.

lua_yieldk[-?, +?, –]

int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k);

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

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

return lua_yieldk (L, n, i, k);

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

Когда сопрограмма возобновляется, Lua вызывает заданную функцию продолжения k для продолжения выполнения C-функции, которая приостановилась (см. §4.7). Эта функция продолжения получает тот же стек, что и предыдущая функция, с удалёнными результатами и замещёнными аргументами, переданными в lua_resume. Кроме того, функция продолжения может получить доступ к значению ctx, вызвав lua_getctx.

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

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

lua_Debug

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

Структура, используемая для передачи различных фрагментов информации о функции или записи активации. lua_getstack заполняет только частную часть этой структуры, для последующего использования. Чтобы заполнить другие поля lua_Debug полезной информацией, вызовите lua_getinfo.

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

  • source: источник фрагмента, который создал функцию. Если source начинается с '@', это означает, что функция была определена в файле, где имя файла следует за '@'. Если source начинается с '=', оставшаяся часть его содержимого описывает источник с учётом настроек пользователя. В противном случае функция была определена в строке, где source — эта строка.
  • short_src: "печать" версии source, используемая в сообщениях об ошибках.
  • linedefined: номер строки, с которой начинается определение функции.
  • lastlinedefined: номер строки, на которой заканчивается определение функции.
  • what: строка "Lua", если функция — функция Lua, "C", если это функция C, "main", если это главная часть фрагмента.
  • currentline: текущая строка, в которой выполняется данная функция. Если информация о строке недоступна, currentline установлено в -1.
  • name: приемлемое имя для данной функции. Поскольку функции в Lua являются значениями первого класса, у них нет фиксированного имени: некоторые функции могут быть значением нескольких глобальных переменных, а другие — храниться только в поле таблицы. Функция lua_getinfo проверяет, как вызывалась функция, чтобы найти подходящее имя. Если имя не найдено, то name устанавливается в NULL.
  • namewhat: объясняет поле name. Значение namewhat может быть "global", "local", "method", "field", "upvalue", или "" (пустая строка), в зависимости от того, как вызывалась функция. (Lua использует пустую строку, когда ни один другой вариант не подходит.)
  • istailcall: истина, если вызов этой функции был вызван через хвостовую рекурсию. В этом случае вызывающая функция на этом уровне не находится в стеке.
  • nups: количество замыканий (upvalues) функции.
  • nparams: количество фиксированных параметров функции (всегда 0 для функций C).
  • isvararg: истина, если функция является функцией с переменным числом аргументов (всегда истинно для функций C).

lua_gethook[-0, +0, –]

lua_Hook lua_gethook (lua_State *L);

Возвращает текущую функцию отладчика.

lua_gethookcount[-0, +0, –]

int lua_gethookcount (lua_State *L);

Возвращает текущее количество вызовов отладчика.

lua_gethookmask[-0, +0, –]

int lua_gethookmask (lua_State *L);

Возвращает текущую маску отладчика.

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

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

Получает информацию о конкретной функции или вызове функции.

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

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

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

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

  • 'n': заполняет поля name и namewhat;
  • 'S': заполняет поля source, short_src, linedefined, lastlinedefined, и what;
  • 'l': заполняет поле currentline;
  • 't': заполняет поле istailcall;
  • 'u': заполняет поля nups, nparams, и isvararg;
  • 'f': помещает в стек функцию, выполняющуюся на данном уровне;
  • 'L': помещает в стек таблицу, индексами которой являются номера строк, допустимые для функции. (Допустимая строка — это строка с связанным кодом, то есть строка, в которую можно поместить точку останова. К недопустимым строкам относятся пустые строки и комментарии.)

Эта функция возвращает 0 при ошибке (например, при недопустимом параметре в what).

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

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

Получает информацию о локальной переменной заданной записи активации или данной функции.

В первом случае параметр ar должен быть корректной записью активации, заполненной предыдущим вызовом lua_getstack или переданной в качестве аргумента отладчику (см. lua_Hook). Индекс n выбирает, какую локальную переменную следует проверить; см. debug.getlocal для подробностей об индексах и именах переменных.

lua_getlocal помещает значение переменной в стек и возвращает её имя.

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

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

lua_getstack[-0, +0, –]

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

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

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

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

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

Получает информацию о замыкании (upvalue) замыкания. (Для функций Lua замыкания (upvalues) — это внешние локальные переменные, которые использует функция, и которые, следовательно, включены в её замыкание.) lua_getupvalue получает индекс n upvalue, помещает значение upvalue в стек и возвращает его имя. funcindex указывает на замыкание в стеке. (Upvalues не имеют определённого порядка, так как они активны на протяжении всей функции. Поэтому они нумеруются в произвольном порядке.)

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

lua_Hook

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

Тип функций отладчика.

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

Для событий вызова event может быть LUA_HOOKCALL, нормальным значением, или LUA_HOOKTAILCALL, для хвостового вызова; в этом случае не будет соответствующего события возврата.

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

Функции отладчиков не могут иметь продолжения, то есть они не могут вызывать lua_yieldk, lua_pcallk или lua_callk с ненулевым k.

Функции отладчика могут приостанавливать выполнение в следующих случаях: только события счётчика и строки могут быть приостановлены, и они не могут приостанавливаться с возвращаемым значением; для приостановки функции отладчика должно закончить выполнение, вызвав lua_yield с nresults равным нулю.

lua_sethook[-0, +0, –]

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

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

Аргумент f — функция отладчика. mask определяет события, при которых будет вызываться отладчик: он формируется путём побитового ИЛИ констант LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE и LUA_MASKCOUNT. Аргумент count имеет смысл только тогда, когда маска включает LUA_MASKCOUNT. При каждом событии отладчик вызывается, как описано ниже:

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

Отладчик отключается путём установки mask в ноль.

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

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

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

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

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

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

Устанавливает значение закрытого значения замыкания. Она присваивает значение, находящееся в верхней части стека, закрытому значению и возвращает его имя. Также она извлекает значение из стека. Параметры funcindex и n такие же, как в lua_getupvalue (см. lua_getupvalue).

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

lua_upvalueid[-0, +0, –]

void *lua_upvalueid (lua_State *L, int funcindex, int n);

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

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

lua_upvaluejoin[-0, +0, –]

void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
                                    int funcindex2, int n2);

Приводит n1-е закрытое значение Lua-замыкания по индексу funcindex1 к n2-му закрытому значению Lua-замыкания по индексу funcindex2.

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

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

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

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

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

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

Функции, вызываемые luaL_check* , всегда вызывают ошибку, если проверка не выполняется.

5.1 – Функции и типы

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

luaL_addchar[-?, +?, e]

void luaL_addchar (luaL_Buffer *B, char c);

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

luaL_addlstring[-?, +?, e]

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

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

luaL_addsize[-?, +?, e]

void luaL_addsize (luaL_Buffer *B, size_t n);

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

luaL_addstring[-?, +?, e]

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

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

luaL_addvalue[-1, +?, e]

void luaL_addvalue (luaL_Buffer *B);

Добавляет значение в верхней части стека в буфер B (см. luaL_Buffer). Извлекает значение.

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

luaL_argcheck[-0, +0, v]

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

Проверяет, является ли cond истинным. Если нет, генерирует ошибку со стандартным сообщением.

luaL_argerror[-0, +0, v]

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

Генерирует ошибку со стандартным сообщением, которое включает extramsg в качестве комментария.

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

luaL_Buffer

typedef struct luaL_Buffer luaL_Buffer;

Тип строчного буфера.

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

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

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

  • Сначала объявите переменную b типа luaL_Buffer.
  • Затем инициализируйте её и предварительно выделите память размером sz вызовом luaL_buffinitsize(L, &b, sz).
  • Затем скопируйте строку в эту область.
  • Завершите вызовом luaL_pushresultsize(&b, sz), где sz - общий размер итоговой строки, скопированной в эту область.

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

luaL_buffinit[-0, +0, –]

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

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

luaL_buffinitsize[-?, +?, e]

char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz);

Эквивалентно последовательности luaL_buffinit, luaL_prepbuffsize.

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

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

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

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

luaL_checkany[-0, +0, v]

void luaL_checkany (lua_State *L, int arg);

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

luaL_checkint[-0, +0, v]

int luaL_checkint (lua_State *L, int arg);

Проверяет, является ли аргумент функции arg числом, и возвращает это число, преобразованное к int.

luaL_checkinteger[-0, +0, v]

lua_Integer luaL_checkinteger (lua_State *L, int arg);

Проверяет, является ли аргумент функции arg числом, и возвращает это число, преобразованное в lua_Integer.

luaL_checklong[-0, +0, v]

long luaL_checklong (lua_State *L, int arg);

Проверяет, является ли аргумент функции arg числом, и возвращает это число, преобразованное в long.

luaL_checklstring[-0, +0, v]

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

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

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

luaL_checknumber[-0, +0, v]

lua_Number luaL_checknumber (lua_State *L, int arg);

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

luaL_checkoption[-0, +0, v]

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

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

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

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

luaL_checkstack[-0, +0, v]

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

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

luaL_checkstring[-0, +0, v]

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

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

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

luaL_checktype[-0, +0, v]

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

Проверяет, имеет ли аргумент функции arg тип t. См. lua_type для кодирования типов для t.

luaL_checkudata[-0, +0, v]

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

Проверяет, является ли аргумент функции arg пользовательским данными типа tname (см. luaL_newmetatable) и возвращает адрес пользовательских данных (см. lua_touserdata).

luaL_checkunsigned[-0, +0, v]

lua_Unsigned luaL_checkunsigned (lua_State *L, int arg);

Проверяет, является ли аргумент функции arg числом и возвращает это число, преобразованное к типу lua_Unsigned.

luaL_checkversion[-0, +0, –]

void luaL_checkversion (lua_State *L);

Проверяет, используют ли ядро, выполняющее вызов, ядро, создавшее состояние Lua, и код, производящий вызов, одну и ту же версию Lua. Также проверяет, используют ли ядро, выполняющее вызов, и ядро, создавшее состояние Lua, одно и то же адресное пространство.

luaL_dofile[-0, +?, e]

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

Загружает и выполняет указанный файл. Он определён как макрос:

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

Возвращает false, если нет ошибок, или true в случае ошибок.

luaL_dostring[-0, +?, –]

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

Загружает и выполняет указанную строку. Он определён как макрос:

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

Возвращает false, если нет ошибок, или true в случае ошибок.

luaL_error[-0, +0, v]

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

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

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

luaL_execresult[-0, +3, e]

int luaL_execresult (lua_State *L, int stat);

Эта функция формирует возвращаемые значения для функций, связанных с процессами, в стандартной библиотеке (os.execute и io.close).

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

int luaL_fileresult (lua_State *L, int stat, const char *fname);

Эта функция формирует возвращаемые значения для функций, связанных с файлами, в стандартной библиотеке (io.open, os.rename, file:seek и т.д.).

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

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

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

luaL_getmetatable[-0, +1, –]

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

Помещает на стек таблицу метаданных, связанную с именем tname в реестре (см. luaL_newmetatable).

luaL_getsubtable[-0, +1, e]

int luaL_getsubtable (lua_State *L, int idx, const char *fname);

Гарантирует, что значение t[fname], где t — значение по индексу idx, является таблицей, и помещает эту таблицу на стек. Возвращает true, если находит предыдущую таблицу, и false, если создаёт новую таблицу.

luaL_gsub[-0, +1, e]

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

Создаёт копию строки s, заменяя все вхождения строки p на строку r. Помещает получившуюся строку на стек и возвращает её.

luaL_len[-0, +0, e]

int luaL_len (lua_State *L, int index);

Возвращает «длину» значения по заданному индексу как число; она эквивалентна оператору '#' в Lua (см. §3.4.6). Вызывает ошибку, если результат операции не является числом. (Этот случай может произойти только через метаметоды.)

luaL_loadbuffer[-0, +1, –]

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

Эквивалентно luaL_loadbufferx с mode равным NULL.

luaL_loadbufferx[-0, +1, –]

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

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

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

luaL_loadfile[-0, +1, e]

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

Эквивалентно luaL_loadfilex с mode равным NULL.

luaL_loadfilex[-0, +1, e]

int luaL_loadfilex (lua_State *L, const char *filename,
                                            const char *mode);

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

Строка mode работает так же, как в функции lua_load.

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

Как и lua_load, эта функция только загружает фрагмент; она его не выполняет.

luaL_loadstring[-0, +1, –]

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

Загружает строку как фрагмент Lua. Эта функция использует lua_load для загрузки фрагмента в строке с нулевым завершением s.

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

Также, как и lua_load, эта функция только загружает фрагмент; она его не выполняет.

luaL_newlib[-0, +1, e]

void luaL_newlib (lua_State *L, const luaL_Reg *l);

Создаёт новую таблицу и регистрирует в ней функции из списка l. Он реализован как макрос:

(luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))

luaL_newlibtable[-0, +1, e]

void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);

Создаёт новую таблицу с размером, оптимизированным для хранения всех элементов в массиве l (но фактически не хранит их). Предназначен для совместного использования с luaL_setfuncs (см. luaL_newlib).

Реализован как макрос. Массив l должен быть фактическим массивом, а не указателем на него.

luaL_newmetatable[-0, +1, e]

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

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

В обоих случаях помещает на стек конечное значение, связанное с tname в реестре.

luaL_newstate[-0, +0, –]

lua_State *luaL_newstate (void);

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

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

luaL_openlibs[-0, +0, e]

void luaL_openlibs (lua_State *L);

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

luaL_optint[-0, +0, v]

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

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

luaL_optinteger[-0, +0, v]

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

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

luaL_optlong[-0, +0, v]

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

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

luaL_optlstring[-0, +0, v]

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

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

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

luaL_optnumber[-0, +0, v]

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

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

luaL_optstring[-0, +0, v]

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

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

luaL_optunsigned[-0, +0, v]

lua_Unsigned luaL_optunsigned (lua_State *L,
                               int arg,
                               lua_Unsigned u);

Если аргумент функции arg является числом, возвращает это число, преобразованное к типу lua_Unsigned. Если этот аргумент отсутствует или равен nil, возвращает u. В противном случае вызывает ошибку.

luaL_prepbuffer[-?, +?, e]

char *luaL_prepbuffer (luaL_Buffer *B);

Эквивалентно luaL_prepbuffsize с предопределённым размером LUAL_BUFFERSIZE.

luaL_prepbuffsize[-?, +?, e]

char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz);

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

luaL_pushresult[-?, +1, e]

void luaL_pushresult (luaL_Buffer *B);

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

luaL_pushresultsize[-?, +1, e]

void luaL_pushresultsize (luaL_Buffer *B, size_t sz);

Эквивалентно последовательности luaL_addsize, luaL_pushresult.

luaL_ref[-1, +0, e]

int luaL_ref (lua_State *L, int t);

Создаёт и возвращает ссылку в таблице по индексу t, для объекта в верхней части стека (и удаляет объект из стека).

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

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

luaL_Reg

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

Тип для массивов функций, которые должны быть зарегистрированы функцией luaL_setfuncs. name — имя функции, а func — указатель на функцию. Любой массив типа luaL_Reg должен заканчиваться специальной записью, в которой как name, так и func равны NULL.

luaL_requiref[-0, +1, e]

void luaL_requiref (lua_State *L, const char *modname,
                    lua_CFunction openf, int glb);

Вызывает функцию openf со строкой modname в качестве аргумента и устанавливает результат вызова в package.loaded[modname], как если бы эта функция была вызвана через require.

Если glb истинно, то также сохраняет результат в глобальной переменной modname.

Оставляет копию результата в стеке.

luaL_setfuncs[-nup, +0, e]

void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);

Регистрирует все функции в массиве l (см. luaL_Reg) в таблице в верхней части стека (ниже необязательных дополнительных параметров, см. далее).

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

luaL_setmetatable[-0, +0, –]

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

Устанавливает метатаблицу объекта в верхней части стека как метатаблицу, связанную с именем tname в реестре (см. luaL_newmetatable).

luaL_testudata[-0, +0, e]

void *luaL_testudata (lua_State *L, int arg, const char *tname);

Эта функция работает как luaL_checkudata, за исключением того, что при неудачном тесте возвращает NULL вместо выброса ошибки.

luaL_tolstring[-0, +1, e]

const char *luaL_tolstring (lua_State *L, int idx, size_t *len);

Преобразует любое значение Lua по указанному индексу в строку C в разумном формате. Результирующая строка помещается в стек и также возвращается функцией. Если len не равно NULL, функция также устанавливает *len с длиной строки.

Если значение имеет метатаблицу со свойством "__tostring", то luaL_tolstring вызывает соответствующий метаметод со значением в качестве аргумента и использует результат вызова в качестве своего результата.

luaL_traceback[-0, +1, e]

void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
                     int level);

Создаёт и помещает в стек трассировку стека L1. Если msg не равно NULL, оно добавляется в начало трассировки. Параметр level указывает, с какого уровня начинать трассировку.

luaL_typename[-0, +0, –]

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

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

luaL_unref[-0, +0, –]

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

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

Если ref равно LUA_NOREF или LUA_REFNIL, функция luaL_unref ничего не делает.

luaL_where[-0, +1, e]

void luaL_where (lua_State *L, int lvl);

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

chunkname:currentline:

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

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

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

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

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

  • базовая библиотека (§6.1);
  • библиотека корутин (§6.2);
  • библиотека пакетов (§6.3);
  • библиотека для работы со строками (§6.4);
  • библиотека для работы со таблицами (§6.5);
  • библиотека математических функций (§6.6) (sin, log и т. д.);
  • библиотека побитовых операций (§6.7);
  • библиотека ввода/вывода (§6.8);
  • библиотека функций операционной системы (§6.9);
  • библиотека отладки (§6.10).

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

Для доступа к этим библиотекам программа на C-хосте должна вызвать функцию luaL_openlibs, которая открывает все стандартные библиотеки. В качестве альтернативы, хост-программа может открыть их по отдельности, используя luaL_requiref для вызова luaopen_base (для базовой библиотеки), luaopen_package (для библиотеки пакетов), luaopen_coroutine (для библиотеки корутин), luaopen_string (для библиотеки строк), luaopen_table (для библиотеки таблиц), luaopen_math (для математической библиотеки), luaopen_bit32 (для библиотеки битовых операций), luaopen_io (для библиотеки ввода/вывода), luaopen_os (для библиотеки функций операционной системы) и luaopen_debug (для библиотеки отладки). Эти функции объявлены в lualib.h.

6.1 – Базовые функции

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

assert (v [, message])

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

collectgarbage ([opt [, arg]])

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

  • "collect": выполняет цикл полной работы сборщика мусора. Это опция по умолчанию.
  • "stop": останавливает автоматическое выполнение сборщика мусора. Сборщик будет работать только при явном вызове до вызова для его перезапуска.
  • "restart": перезапускает автоматическое выполнение сборщика мусора.
  • "count": возвращает общее используемое Lua память (в Кбайтах) и второе значение с общей памятью в байтах по модулю 1024. Первое значение имеет дробную часть, поэтому следующее равенство всегда верно:
    k, b = collectgarbage("count")
    assert(k*1024 == math.floor(k)*1024 + b)

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

  • "step": выполняет шаг сборки мусора. Размер шага контролируется arg (большие значения означают больше шагов) непредсказуемым образом. Если вы хотите контролировать размер шага, вы должны экспериментально настроить значение arg. Возвращает true, если шаг завершил цикл сбора.
  • "setpause": устанавливает arg в качестве нового значения для паузы сборщика (см. §2.5). Возвращает предыдущее значение для паузы.
  • "setstepmul": устанавливает arg в качестве нового значения для множителя шага сборщика (см. §2.5). Возвращает предыдущее значение для шага.
  • "isrunning": возвращает булево значение, указывающее, работает ли сборщик (то есть не остановлен).
  • "generational": изменяет сборщик на генерационный режим. Это экспериментальная функция (см. §2.5).
  • "incremental": изменяет сборщик на инкрементальный режим. Это режим по умолчанию.

dofile ([filename])

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

error (message [, level])

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

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

_G

Глобальная переменная (не функция), которая хранит глобальную среду (см. §2.2). Сам Lua не использует эту переменную; изменение ее значения не влияет на какую-либо среду, и наоборот.

getmetatable (object)

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

ipairs (t)

Если у t есть метаметод __ipairs, вызывает его с t в качестве аргумента и возвращает первые три результата вызова.

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

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

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

load (ld [, source [, mode [, env]]])

Загружает блок.

Если ld — строка, то блок — это эта строка. Если ld — функция, load вызывает ее многократно, чтобы получить фрагменты блока. Каждый вызов ld должен вернуть строку, которая конкатенируется с предыдущими результатами. Возвращение пустой строки, nil или отсутствие значения сигнализирует об окончании блока.

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

Если у полученной функции есть значения-уровни, первое значение-уровень устанавливается в значение env, если этот параметр задан, или в значение глобальной среды. (Когда вы загружаете основной блок, полученная функция всегда будет иметь ровно один уровень-значение, переменную _ENV (см. §2.2). Когда вы загружаете бинарный блок, созданный из функции (см. string.dump), полученная функция может иметь произвольные значения-уровни.)

source используется в качестве источника блока для сообщений об ошибках и отладки (см. §4.9). При отсутствии используется ld, если ld — строка, или "=(load)" в противном случае.

Строка mode контролирует, может ли блок быть текстовым или бинарным (то есть, предварительно скомпилированный блок). Она может быть строкой "b" (только бинарные блоки), "t" (только текстовые блоки) или "bt" (и бинарные, и текстовые). По умолчанию "bt".

loadfile ([filename [, mode [, env]]])

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

next (table [, index])

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

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

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

pairs (t)

Если у t есть метаметод __pairs, вызывает его с t в качестве аргумента и возвращает первые три результата вызова.

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

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

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

См. функцию next для замечаний по изменению таблицы во время ее обхода.

pcall (f [, arg1, ···])

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

print (···)

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

rawequal (v1, v2)

Проверяет, равно ли v1 v2, не вызывая метаметодов. Возвращает булево значение.

rawget (table, index)

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

rawlen (v)

Возвращает длину объекта v, который должен быть таблицей или строкой, не вызывая метаметодов. Возвращает целое число.

rawset (table, index, value)

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

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

select (index, ···)

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

setmetatable (table, metatable)

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

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

tonumber (e [, base])

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

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

tostring (v)

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

Если метатаблица v имеет поле "__tostring", то tostring вызывает соответствующее значение с v в качестве аргумента и использует результат вызова как свой результат.

type (v)

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

_VERSION

Глобальная переменная (не функция), которая хранит строку с текущей версией интерпретатора. Текущее содержимое этой переменной — "Lua 5.2".

xpcall (f, msgh [, arg1, ···])

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

6.2 – Управление сопрограммами

Операции, связанные с сопрограммами, составляют подбиблиотеку базовой библиотеки и находятся внутри таблицы coroutine. См. §2.6 для общего описания сопрограмм.

coroutine.create (f)

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

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

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

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

coroutine.running ()

Возвращает текущую корутину и булево значение, равное true, если текущая корутина — главная.

coroutine.status (co)

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

coroutine.wrap (f)

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

coroutine.yield (···)

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

6.3 – Модули

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

require (modname)

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

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

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

После нахождения загрузчика, require вызывает загрузчик с двумя аргументами: modname и дополнительным значением, зависящим от того, как был найден загрузчик. (Если загрузчик был найден в файле, это дополнительное значение — имя файла.) Если загрузчик возвращает любое ненулевое значение, require присваивает возвращённое значение package.loaded[modname]. Если загрузчик не возвращает ненулевого значения и не присвоил никакого значения package.loaded[modname], тогда require присваивает true этому элементу. В любом случае, require возвращает конечное значение package.loaded[modname].

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

package.config

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

  • Первая строка — строка разделителя каталогов. По умолчанию это '\' для Windows и '/' для всех других систем.
  • Вторая строка — символ, разделяющий шаблоны в пути. По умолчанию это ';'.
  • Третья строка — строка, отмечающая точки подстановки в шаблоне. По умолчанию это '?'.
  • Четвёртая строка — строка, которая в пути Windows заменяется каталогом исполняемого файла. По умолчанию это '!'.
  • Пятая строка — метка для игнорирования всего текста перед ней при построении имени функции luaopen_ . По умолчанию это '-'.

package.cpath

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

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

package.loaded

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

Эта переменная является лишь ссылкой на реальную таблицу; присвоение значений этой переменной не изменяет таблицу, используемую функцией require.

package.loadlib (libname, funcname)

Динамически связывает программу-хост с библиотекой C libname.

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

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

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

package.path

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

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

package.preload

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

Эта переменная является лишь ссылкой на реальную таблицу; присвоение значений этой переменной не изменяет таблицу, используемую функцией require.

package.searchers

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

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

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

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

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

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

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

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

Четвёртый поиск пытается использовать универсальный загрузчик. Он ищет библиотеку C для корневого имени данного модуля. Например, при загрузке модуля a.b.c, он будет искать библиотеку C для a. Если найдена, он ищет в ней функцию для подмодуля; в нашем примере, это будет luaopen_a_b_c. С помощью этой возможности, пакет может упаковать несколько подмодулей C в одну библиотеку, при этом каждый подмодуль сохраняет свою оригинальную функцию открытия.

Все функции поиска, кроме первой (preload), возвращают в качестве дополнительного значения имя файла, где был найден модуль, как возвращает package.searchpath. Первый поиск не возвращает дополнительного значения.

package.searchpath (name, path [, sep [, rep]])

Ищет заданный name в заданном path.

Путь — строка, содержащая последовательность шаблонов, разделенных точкой с запятой. Для каждого шаблона функция заменяет каждый вопросительный знак (если есть) в шаблоне копией name, где все вхождения sep (точка, по умолчанию) заменены на rep (разделитель каталогов системы, по умолчанию), а затем пытается открыть получившееся имя файла.

Например, если путь — строка

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

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

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

6.4 – Обработка строк

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

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

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

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

Возвращает внутренние числовые коды символов s[i], s[i+1], ..., s[j]. Значение по умолчанию для i равно 1; значение по умолчанию для j равно i. Эти индексы корректируются согласно тем же правилам, что и функция string.sub.

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

string.char (···)

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

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

string.dump (function)

Возвращает строку, содержащую двоичное представление данной функции, так что последующее применение load к этой строке возвращает копию функции (но с новыми значениями upvalue).

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

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

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

string.format (formatstring, ···)

Возвращает отформатированную версию своих аргументов, следуя описанию, заданному в первом аргументе (который должен быть строкой). Строка формата следует тем же правилам, что и функция ISO C sprintf. Единственные отличия заключаются в том, что опции/модификаторы *, h, L, l, n, и p не поддерживаются, а есть дополнительная опция, q. Опция q форматирует строку в двойных кавычках, используя последовательности экранирования, когда это необходимо, чтобы убедиться, что её можно безопасно считать обратно интерпретатором Lua. Например, вызов

string.format('%q', 'a string with "quotes" and \n new line')

может произвести строку:

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

Опции A и a (если доступны), E, e, f, G, и g все ожидают число в качестве аргумента. Опции c, d, i, o, u, X, и x также ожидают число, но диапазон этого числа может быть ограничен реализацией на уровне C. Для опций o, u, X, и x, число не может быть отрицательным. Опция q ожидает строку; опция s ожидает строку без встроенных нулей. Если аргументом опции s не является строка, она преобразуется в строку, следуя тем же правилам, что и tostring.

string.gmatch (s, pattern)

Возвращает функцию-итератор, которая при каждом вызове возвращает следующие захваты от pattern над строкой s. Если pattern не задаёт никаких захватов, то в каждом вызове возвращается всё совпадение.

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

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

Следующий пример собирает все пары key=value из заданной строки в таблицу:

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

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

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

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

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

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

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

В любом случае, если шаблон не задаёт захваты, то он ведёт себя так, как будто весь шаблон находится внутри захвата.

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

Вот несколько примеров:

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

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

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

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

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

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

string.len (s)

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

string.lower (s)

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

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

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

string.rep (s, n [, sep])

Возвращает строку, которая представляет собой конкатенацию n копий строки s разделённых строкой sep. Значение по умолчанию для sep — пустая строка (т.е. без разделителя).

string.reverse (s)

Возвращает строку, являющуюся обратной строке s.

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

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

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

string.upper (s)

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

6.4.1 – Шаблоны

Класс символов:

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

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

    Взаимодействие между диапазонами и классами не определено. Следовательно, такие шаблоны, как [%a-z] или [a-%%], не имеют смысла.

  • [^set]: представляет дополнение к множеству, где множество интерпретируется как описано выше.

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

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

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

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

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

Шаблон:

Шаблон - это последовательность элементов шаблона. Квадратная скобка '^' в начале шаблона привязывает сопоставление к началу строки-предмета. Знак '$' в конце шаблона привязывает сопоставление к концу строки-предмета. В других позициях '^' и '$' не имеют специального значения и представляют сами себя.

Захваты:

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

В качестве специального случая, пустой захват () захватывает текущую позицию строки (число). Например, если мы применяем шаблон "()aa()" к строке "flaaap", будут два захвата: 3 и 5.

6.5 – Обработка таблиц

Эта библиотека предоставляет общие функции для обработки таблиц. Все её функции находятся внутри таблицы table.

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

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

table.concat (list [, sep [, i [, j]]])

Принимая список, где все элементы являются строками или числами, возвращает строку list[i]..sep..list[i+1] ··· sep..list[j]. Значение по умолчанию для sep - пустая строка, значение по умолчанию для i - 1, и значение по умолчанию для j - #list. Если i больше j, возвращает пустую строку.

table.insert (list, [pos,] value)

Вставляет элемент value в позицию pos в list, сдвигая вверх элементы list[pos], list[pos+1], ···, list[#list]. Значение по умолчанию для pos - #list+1, так что вызов table.insert(t,x) вставляет x в конец списка t.

table.pack (···)

Возвращает новую таблицу со всеми параметрами, сохранёнными в ключах 1, 2 и т. д., и с полем "n" с общим количеством параметров. Обратите внимание, что полученная таблица может не быть последовательностью.

table.remove (list [, pos])

Удаляет из list элемент в позиции pos, возвращая значение удалённого элемента. Когда pos - целое число от 1 до #list, он сдвигает вниз элементы list[pos+1], list[pos+2], ···, list[#list] и стирает элемент list[#list]; индекс pos также может быть 0, когда #list равно 0, или #list + 1; в этих случаях функция стирает элемент list[pos].

Значение по умолчанию для pos - #list, так что вызов table.remove(t) удаляет последний элемент списка t.

table.sort (list [, comp])

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

Алгоритм сортировки не является стабильным; то есть элементы, считающиеся равными по заданному порядку, могут изменить своё относительное положение при сортировке.

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

Возвращает элементы из заданной таблицы. Эта функция эквивалентна

return list[i], list[i+1], ···, list[j]

По умолчанию i - 1, а j - #list.

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

Эта библиотека является интерфейсом к стандартной математической библиотеке C. Она предоставляет все свои функции внутри таблицы math.

math.abs (x)

Возвращает абсолютное значение x.

math.acos (x)

Возвращает арккосинус x (в радианах).

math.asin (x)

Возвращает арксинус x (в радианах).

math.atan (x)

Возвращает арктангенс x (в радианах).

math.atan2 (y, x)

Возвращает арктангенс y/x (в радианах), но использует знаки обоих параметров для определения квадранта результата. (Она также правильно обрабатывает случай, когда x равно нулю.)

math.ceil (x)

Возвращает наименьшее целое число, большее или равное x.

math.cos (x)

Возвращает косинус x (предполагается, что в радианах).

math.cosh (x)

Возвращает гиперболический косинус x.

math.deg (x)

Возвращает угол x (заданный в радианах) в градусах.

math.exp (x)

Возвращает значение ex.

math.floor (x)

Возвращает наибольшее целое число, меньшее или равное x.

math.fmod (x, y)

Возвращает остаток от деления x на y при округлении частного к нулю.

math.frexp (x)

Возвращает m и e такие, что x = m2e, e - целое число, и абсолютное значение m находится в диапазоне [0.5, 1) (или ноль, когда x равно нулю).

math.huge

Значение HUGE_VAL, значение, большее или равное любому другому числовому значению.

math.ldexp (m, e)

Возвращает m2e (e должно быть целым числом).

math.log (x [, base])

Возвращает логарифм x по заданному основанию. Значение по умолчанию для base - e (так что функция возвращает натуральный логарифм x).

math.max (x, ···)

Возвращает максимальное значение среди своих аргументов.

math.min (x, ···)

Возвращает минимальное значение среди своих аргументов.

math.modf (x)

Возвращает две числа: целую часть x и дробную часть x.

math.pi

Значение π.

math.pow (x, y)

Возвращает xy. (Вы также можете использовать выражение x^y для вычисления этого значения.)

math.rad (x)

Возвращает угол x (в градусах) в радианах.

math.random ([m [, n]])

Эта функция является интерфейсом к простой функции псевдослучайной генерации rand, предоставленной Стандартным C. (Не гарантируются её статистические свойства.)

При вызове без аргументов возвращает равномерно распределённое псевдослучайное вещественное число в диапазоне [0,1). При вызове с целым числом m, math.random возвращает равномерно распределённое псевдослучайное целое число в диапазоне [1, m]. При вызове с двумя целыми числами m и n, math.random возвращает равномерно распределённое псевдослучайное целое число в диапазоне [m, n].

math.randomseed (x)

Устанавливает x в качестве "семени" для псевдослучайного генератора: одинаковые семена порождают одинаковые последовательности чисел.

math.sin (x)

Возвращает синус от x (предполагается, что в радианах).

math.sinh (x)

Возвращает гиперболический синус от x.

math.sqrt (x)

Возвращает квадратный корень из x. (Вы также можете использовать выражение x^0.5 для вычисления этого значения.)

math.tan (x)

Возвращает тангенс от x (предполагается, что в радианах).

math.tanh (x)

Возвращает гиперболический тангенс от x.

6.7 – Побитовые операции

Эта библиотека предоставляет побитовые операции. Все функции содержатся в таблице bit32.

Если не указано иное, все функции принимают числовые аргументы в диапазоне (-251,+251); каждый аргумент нормализуется до остатка от деления на 232 и усекается до целого числа (некоторым неопределённым способом), так что его конечное значение попадает в диапазон [0,232 - 1]. Аналогично, все результаты находятся в диапазоне [0,232 - 1]. Обратите внимание, что bit32.bnot(0) это 0xFFFFFFFF, что отличается от -1.

bit32.arshift (x, disp)

Возвращает число x сдвинутое на disp бит вправо. Число disp может быть любым представимым целым числом. Отрицательные сдвиги сдвигают влево.

Эта операция сдвига называется арифметическим сдвигом. Свободные биты слева заполняются копиями старшего бита x; свободные биты справа заполняются нулями. В частности, сдвиги со значениями абсолютной величиной, превышающими 31, приводят к нулю или 0xFFFFFFFF (все исходные биты сдвигаются наружу).

bit32.band (···)

Возвращает побитовую конъюнкцию своих операндов.

bit32.bnot (x)

Возвращает побитовое отрицание x. Для любого целого числа x, выполняется следующее тождество:

assert(bit32.bnot(x) == (-1 - x) % 2^32)

bit32.bor (···)

Возвращает побитовую дизъюнкцию своих операндов.

bit32.btest (···)

Возвращает булево значение, указывающее, является ли побитовая конъюнкция своих операндов отличной от нуля.

bit32.bxor (···)

Возвращает побитовое исключающее ИЛИ своих операндов.

bit32.extract (n, field [, width])

Возвращает целое без знака, образованное битами field по field + width - 1 из n. Биты нумеруются с 0 (самый младший) до 31 (самый старший). Все доступные биты должны находиться в диапазоне [0, 31].

По умолчанию width равно 1.

bit32.replace (n, v, field [, width])

Возвращает копию n с битами field по field + width - 1 заменёнными значением v. Смотрите bit32.extract для деталей о field и width.

bit32.lrotate (x, disp)

Возвращает число x сдвинутое на disp бит влево. Число disp может быть любым представимым целым числом.

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

assert(bit32.lrotate(x, disp) == bit32.lrotate(x, disp % 32))

В частности, отрицательные сдвиги вращают вправо.

bit32.lshift (x, disp)

Возвращает число x сдвинутое на disp бит влево. Число disp может быть любым представимым целым числом. Отрицательные сдвиги сдвигают вправо. В любом направлении свободные биты заполняются нулями. В частности, сдвиги со значениями абсолютной величиной, превышающими 31, приводят к нулю (все биты сдвигаются наружу).

Для положительных сдвигов выполняется следующее равенство:

assert(bit32.lshift(b, disp) == (b * 2^disp) % 2^32)

bit32.rrotate (x, disp)

Возвращает число x сдвинутое на disp бит вправо. Число disp может быть любым представимым целым числом.

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

assert(bit32.rrotate(x, disp) == bit32.rrotate(x, disp % 32))

В частности, отрицательные сдвиги вращают влево.

bit32.rshift (x, disp)

Возвращает число x сдвинутое на disp бит вправо. Число disp может быть любым представимым целым числом. Отрицательные сдвиги сдвигают влево. В любом направлении свободные биты заполняются нулями. В частности, сдвиги со значениями абсолютной величиной, превышающими 31, приводят к нулю (все биты сдвигаются наружу).

Для положительных сдвигов выполняется следующее равенство:

assert(bit32.rshift(b, disp) == math.floor(b % 2^32 / 2^disp))

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

6.8 – Утилиты ввода-вывода

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

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

Таблица io также предоставляет три предопределённых дескриптора файлов со своими обычными значениями из C: io.stdin, io.stdout и io.stderr. Библиотека ввода-вывода никогда не закрывает эти файлы.

Если не указано иное, все функции ввода-вывода возвращают nil при ошибке (плюс сообщение об ошибке как второй результат и системно-зависимый код ошибки как третий результат) и значение, отличное от nil при успехе. На системах, не поддерживающих Posix, вычисление сообщения об ошибке и кода ошибки в случае ошибок может быть не потокобезопасным, так как они полагаются на глобальную переменную C errno.

io.close ([file])

Эквивалентно file:close(). Без file, закрывает файл вывода по умолчанию.

io.flush ()

Эквивалентно io.output():flush().

io.input ([file])

При вызове с именем файла открывает указанный файл (в текстовом режиме) и устанавливает его дескриптор как файл ввода по умолчанию. При вызове с дескриптором файла просто устанавливает этот дескриптор как файл ввода по умолчанию. При вызове без параметров возвращает текущий файл ввода по умолчанию.

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

io.lines ([filename ···])

Открывает указанный файл для чтения и возвращает функцию-итератор, которая работает как file:lines(···) над открытым файлом. Когда функция-итератор обнаруживает конец файла, она возвращает nil (чтобы завершить цикл) и автоматически закрывает файл.

Вызов io.lines() (без имени файла) эквивалентен io.input():lines(); то есть он перебирает строки файла по умолчанию для ввода. В этом случае файл не закрывается при завершении цикла.

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

io.open (filename [, mode])

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

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

  • "r": режим чтения (по умолчанию);
  • "w": режим записи;
  • "a": режим добавления;
  • "r+": режим обновления, все предыдущие данные сохраняются;
  • "w+": режим обновления, все предыдущие данные удаляются;
  • "a+": режим добавления и обновления, предыдущие данные сохраняются, запись разрешена только в конце файла.

Строка mode также может иметь 'b' в конце, что требуется на некоторых системах для открытия файла в двоичном режиме.

io.output ([file])

Аналогично io.input, но работает с файлом вывода по умолчанию.

io.popen (prog [, mode])

Эта функция зависит от системы и не доступна на всех платформах.

Запускает программу prog в отдельном процессе и возвращает дескриптор файла, который можно использовать для чтения данных из этой программы (если mode равно "r", по умолчанию) или для записи данных в эту программу (если mode равно "w").

io.read (···)

Эквивалентно io.input():read(···).

io.tmpfile ()

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

io.type (obj)

Проверяет, является ли obj допустимым дескриптором файла. Возвращает строку "file" если obj является открытым дескриптором файла, "closed file" если obj является закрытым дескриптором файла, или nil если obj не является дескриптором файла.

io.write (···)

Эквивалентно io.output():write(···).

file:close ()

Закрывает file. Обратите внимание, что файлы автоматически закрываются при сборке мусора их дескрипторов, но это занимает непредсказуемое время.

При закрытии дескриптора файла, созданного с помощью io.popen, file:close возвращает те же значения, что и os.execute.

file:flush ()

Сохраняет все записанные данные в file.

file:lines (···)

Возвращает функцию-итератор, которая при каждом вызове считывает файл в соответствии с заданными форматами. Если форматы не указаны, используется "*l" по умолчанию. Например, конструкция

for c in file:lines(1) do body end

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

В случае ошибок эта функция генерирует исключение вместо возвращения кода ошибки.

file:read (···)

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

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

  • "*n": считывает число; это единственный формат, возвращающий число вместо строки.
  • "*a": считывает весь файл, начиная с текущей позиции. При достижении конца файла возвращает пустую строку.
  • "*l": считывает следующую строку, игнорируя символ конца строки, возвращает nil при достижении конца файла. Это формат по умолчанию.
  • "*L": считывает следующую строку, включая символ конца строки (если он присутствует), возвращает nil при достижении конца файла.
  • число: считывает строку длиной до указанного числа байтов, возвращает nil при достижении конца файла. Если число равно нулю, ничего не считывает и возвращает пустую строку, или nil при достижении конца файла.

file:seek ([whence [, offset]])

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

  • "set": база — позиция 0 (начало файла);
  • "cur": база — текущая позиция;
  • "end": база — конец файла;

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

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

file:setvbuf (mode [, size])

Устанавливает режим буферизации для выходного файла. Доступны три режима:

  • "no": отсутствует буферизация; результат любой операции вывода появляется немедленно.
  • "full": полная буферизация; операция вывода выполняется только при заполнении буфера или при явном flush файла (см. io.flush).
  • "line": строчная буферизация; вывод буферизуется до вывода символа перевода строки или при любом вводе из специальных файлов (например, терминального устройства).

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

file:write (···)

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

В случае успеха функция возвращает file. В противном случае она возвращает nil плюс строку с описанием ошибки.

6.9 – Утилиты операционной системы

Эта библиотека реализована через таблицу os.

os.clock ()

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

os.date ([format [, time]])

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

Если присутствует аргумент time, это время для форматирования (см. функцию os.time для описания этого значения). В противном случае date форматирует текущее время.

Если format начинается с '!', то дата форматируется в координированном универсальном времени. После этого необязательного символа, если format является строкой "*t", то date возвращает таблицу со следующими полями: year (четыре цифры), month (от 1 до 12), day (от 1 до 31), hour (от 0 до 23), min (от 0 до 59), sec (от 0 до 61), wday (день недели, воскресенье — 1), yday (день в году), и isdst (флаг летнего времени, булево значение). Последнее поле может отсутствовать, если информация недоступна.

Если format не равно "*t", то date возвращает дату в виде строки, отформатированной по тем же правилам, что и функция ISO C strftime.

При вызове без аргументов date возвращает разумное представление даты и времени, зависящее от системы и текущего языка (то есть os.date() эквивалентно os.date("%c")).

В не-Posix системах, эта функция может быть не потокобезопасной из-за своей зависимости от C функции gmtime и C функции localtime.

os.difftime (t2, t1)

Возвращает число секунд от времени t1 до времени t2. В POSIX, Windows и некоторых других системах, это значение точно t2-t1.

os.execute ([command])

Эта функция эквивалентна функции ISO C system. Она передаёт command для выполнения операционной системой. Первый результат — true, если команда завершилась успешно, или nil в противном случае. После этого первого результата функция возвращает строку и число, следующим образом:

  • "exit": команда завершилась нормально; следующее число — код завершения команды.
  • "signal": команда была завершена сигналом; следующее число — сигнал, который завершил команду.

Если вызов производится без command, os.execute возвращает boolean, равный true, если оболочка доступна.

os.exit ([code [, close])

Вызывает функцию ISO C exit для завершения программы. Если code равно true, возвращаемый код — EXIT_SUCCESS; если code равно false, возвращаемый код — EXIT_FAILURE; если code — число, возвращаемый код — это число. Значение по умолчанию для code — true.

Если необязательный второй аргумент close равен true, закрывает состояние Lua перед выходом.

os.getenv (varname)

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

os.remove (filename)

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

os.rename (oldname, newname)

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

os.setlocale (locale [, category])

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

Если locale — пустая строка, текущий язык устанавливается на язык по умолчанию. Если locale — строка "C", текущий язык устанавливается на стандартный язык C.

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

Эта функция может быть не потокобезопасной из-за её зависимости от C функции setlocale.

os.time ([table])

Возвращает текущее время при вызове без аргументов или время, представляющее дату и время, указанные в заданной таблице. Эта таблица должна иметь поля year, month, и day, и может иметь поля hour (по умолчанию 12), min (по умолчанию 0), sec (по умолчанию 0), и isdst (по умолчанию nil). Для описания этих полей см. функцию os.date.

Возвращаемое значение — число, смысл которого зависит от вашей системы. В POSIX, Windows и некоторых других системах это число учитывает количество секунд с начала отсчёта времени (эпоха). В других системах смысл не определён, и число, возвращаемое time, может использоваться только как аргумент для функций os.date и os.difftime.

os.tmpname ()

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

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

Когда это возможно, вы можете предпочесть использовать io.tmpfile, который автоматически удаляет файл по завершении программы.

6.10 – Библиотека отладки

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

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

debug.debug ()

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

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

debug.gethook ([thread])

Возвращает текущие настройки хука потока в виде трёх значений: текущую функцию хука, текущую маску хука и текущий счётчик хука (как задано функцией debug.sethook).

debug.getinfo ([thread,] f [, what])

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

Возвращаемая таблица может содержать все поля, возвращаемые lua_getinfo, при этом строка what описывает, какие поля заполнить. По умолчанию для what извлекается вся доступная информация, кроме таблицы допустимых строк. Если указан параметр 'f', добавляется поле с именем func с самой функцией. Если указан параметр 'L', добавляется поле с именем activelines с таблицей допустимых строк.

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

debug.getlocal ([thread,] f, local)

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

Первый параметр или локальная переменная имеет индекс 1 и так далее, пока не достигнут последней активной переменной. Отрицательные индексы относятся к параметрам vararg; -1 — первый параметр vararg. Функция возвращает nil, если переменной с данным индексом нет, и вызывает ошибку при вызове с уровнем, выходящим за пределы диапазона. (Вы можете вызвать debug.getinfo, чтобы проверить, является ли уровень допустимым.)

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

Параметр f также может быть функцией. В этом случае getlocal возвращает только имена параметров функции.

debug.getmetatable (value)

Возвращает метатаблицу данного value или nil, если у него нет метатаблицы.

debug.getregistry ()

Возвращает таблицу реестра (см. §4.5).

debug.getupvalue (f, up)

Эта функция возвращает имя и значение значения upvalue с индексом up функции f. Функция возвращает nil, если upvalue с данным индексом не существует.

debug.getuservalue (u)

Возвращает Lua-значение, связанное с u. Если u не является userdata, возвращает nil.

debug.sethook ([thread,] hook, mask [, count])

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

  • 'c': хук вызывается всякий раз, когда Lua вызывает функцию;
  • 'r': хук вызывается всякий раз, когда Lua возвращается из функции;
  • 'l': хук вызывается всякий раз, когда Lua входит в новую строку кода.

Кроме того, при значении count отличном от нуля, хук вызывается также после каждой count инструкции.

При вызове без аргументов debug.sethook отключает хук.

При вызове хука, его первый параметр — строка, описывающая событие, которое его вызвало: "call" (или "tail call"), "return", "line", и "count". Для событий строк хук также получает новый номер строки в качестве второго параметра. Внутри хука вы можете вызвать getinfo с уровнем 2, чтобы получить более подробную информацию о выполняемой функции (уровень 0 — функция getinfo, а уровень 1 — функция хука).

debug.setlocal ([thread,] level, local, value)

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

См. debug.getlocal для получения дополнительной информации об индексах и именах переменных.

debug.setmetatable (value, table)

Устанавливает метатаблицу для данного value в заданную table (которая может быть nil). Возвращает value.

debug.setupvalue (f, up, value)

Эта функция присваивает значение value значению upvalue с индексом up функции f. Функция возвращает nil, если upvalue с данным индексом не существует. В противном случае она возвращает имя upvalue.

debug.setuservalue (udata, value)

Устанавливает данное value в качестве Lua-значения, связанного с данным udata. value должен быть таблицей или nil; udata должен быть полным userdata.

Возвращает udata.

debug.traceback ([thread,] [message [, level]])

Если message указано, но не является строкой и не является nil, эта функция возвращает message без дальнейшей обработки. В противном случае возвращает строку со стеком вызовов. Необязательная строка message добавляется в начало стека вызовов. Необязательное число level указывает, с какого уровня начать стек вызовов (по умолчанию 1, функция, вызывающая traceback).

debug.upvalueid (f, n)

Возвращает уникальный идентификатор (в качестве лёгкого userdata) для upvalue с номером n из заданной функции.

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

debug.upvaluejoin (f1, n1, f2, n2)

Сделайте n1-е upvalue Lua-замыкания f1 ссылающимся на n2-е upvalue Lua-замыкания f2.

7 – Lua Standalone

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

lua [options] [script [args]]

Параметры:

  • -e stat: выполняет строку stat;
  • -l mod: "требует" mod;
  • -i: входит в интерактивный режим после выполнения script;
  • -v: выводит информацию о версии;
  • -E: игнорирует переменные окружения;
  • --: останавливает обработку параметров;
  • -: выполняет stdin как файл и останавливает обработку параметров.

После обработки параметров lua выполняет заданный script, передавая ему заданные args в качестве строковых аргументов. При вызове без аргументов lua ведет себя как lua -v -i, когда стандартный ввод (stdin) является терминалом, и как lua - в противном случае.

При вызове без опции -E, интерпретатор проверяет переменную окружения LUA_INIT_5_2 (или LUA_INIT, если она не определена) перед выполнением любого аргумента. Если содержимое переменной имеет формат @filename, то lua выполняет файл. В противном случае lua выполняет саму строку.

При вызове с опцией -E, помимо игнорирования LUA_INIT, Lua также игнорирует значения LUA_PATH и LUA_CPATH, устанавливая значения package.path и package.cpath с помощью стандартных путей, определённых в luaconf.h.

Все опции обрабатываются в порядке следования, за исключением -i и -E. Например, вызов

$ lua -e'a=1' -e 'print(a)' script.lua

сначала установит a в 1, затем выведет значение a, и, наконец, выполнит файл script.lua без аргументов. (Здесь $ — приглашение оболочки. Ваше приглашение может быть другим.)

Перед запуском скрипта lua собирает все аргументы в командной строке в глобальную таблицу под названием arg. Имя скрипта хранится под индексом 0, первый аргумент после имени скрипта — под индексом 1 и так далее. Любые аргументы до имени скрипта (то есть, имя интерпретатора плюс опции) находятся под отрицательными индексами. Например, при вызове

$ lua -la b.lua t1 t2

интерпретатор сначала выполняет файл a.lua, затем создаёт таблицу

arg = { [-2] = "lua", [-1] = "-la",
        [0] = "b.lua",
        [1] = "t1", [2] = "t2" }

и, наконец, выполняет файл b.lua. Скрипт вызывается с arg[1], arg[2], ... в качестве аргументов; он также может получить доступ к этим аргументам с помощью выражения vararg '...'.

В интерактивном режиме, если вы напишете неполное выражение, интерпретатор ждёт его завершения, выдав другое приглашение.

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

При нормальном завершении интерпретатор закрывает основное состояние Lua (см. lua_close). Скрипт может избежать этой операции, вызвав os.exit для завершения.

Чтобы разрешить использование Lua как интерпретатора скриптов в системах Unix, автономный интерпретатор пропускает первую строку фрагмента, если она начинается с #. Таким образом, скрипты Lua можно преобразовать в исполняемые программы, используя chmod +x и форму #!, как в

#!/usr/local/bin/lua

(Конечно, расположение интерпретатора Lua может отличаться в вашей системе. Если lua находится в вашем PATH, то

#!/usr/bin/env lua

является более портабельным решением.)

8 – Несовместимости с Предыдущей Версией

Здесь мы перечисляем несовместимости, которые вы можете встретить при переносе программы из Lua 5.1 в Lua 5.2. Вы можете избежать некоторых несовместимостей, скомпилировав Lua с соответствующими параметрами (см. файл luaconf.h). Однако все эти параметры совместимости будут удалены в следующей версии Lua. Аналогично, все функции, помеченные как устаревшие в Lua 5.1, были удалены в Lua 5.2.

8.1 – Изменения в Языке

  • Концепция окружения изменилась. Только функции Lua имеют окружения. Чтобы установить окружение функции Lua, используйте переменную _ENV или функцию load.

    Функции C больше не имеют окружений. Используйте значение upvalue со связанной таблицей, если вам нужно сохранить общее состояние между несколькими функциями C. (Вы можете использовать luaL_setfuncs для открытия библиотеки C со всеми функциями, использующими общее upvalue.)

    Для управления «окружением» объекта userdata (который теперь называется значением user value), используйте новые функции lua_getuservalue и lua_setuservalue.

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

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

  • Функция module устарела. Легко создать модуль с обычным Lua-кодом. Модули не должны устанавливать глобальные переменные.
  • Функции setfenv и getfenv были удалены из-за изменений в окружениях.
  • Функция math.log10 устарела. Используйте math.log с 10 в качестве второго аргумента вместо неё.
  • Функция loadstring устарела. Используйте load вместо неё; она теперь принимает строковые аргументы и точно эквивалентна loadstring.
  • Функция table.maxn устарела. Напишите её на Lua, если вам это действительно нужно.
  • Функция os.execute теперь возвращает true при успешном завершении команды и nil плюс информацию об ошибке в противном случае.
  • Функция unpack была перемещена в библиотеку таблиц и поэтому должна вызываться как table.unpack.
  • Класс символов %z в шаблонах устарел, так как теперь шаблоны могут содержать '\0' как обычный символ.
  • Таблица package.loaders была переименована в package.searchers.
  • Lua больше не имеет проверки байткода. Таким образом, все функции, которые загружают код (load и loadfile), потенциально небезопасны при загрузке недоверенных двоичных данных. (На самом деле, эти функции уже были небезопасны из-за недостатков в алгоритме проверки.) В случае сомнений используйте аргумент mode этих функций, чтобы ограничить их загрузкой текстовых фрагментов.
  • Стандартные пути в официальном дистрибутиве могут меняться между версиями.

8.3 – Изменения в API

  • Псевдоиндекс LUA_GLOBALSINDEX был удален. Вы должны получить глобальную среду из реестра (см. §4.5).
  • Псевдоиндекс LUA_ENVIRONINDEX и функции lua_getfenv/lua_setfenv были удалены, так как функции C больше не имеют окружений.
  • Функция luaL_register устарела. Используйте luaL_setfuncs, чтобы ваш модуль не создавал глобальных переменных. (Модули больше не должны устанавливать глобальные переменные.)
  • Аргумент osize функции выделения не может быть нулем при создании нового блока, то есть когда ptr является NULL (см. lua_Alloc). Используйте только тест ptr == NULL для проверки того, является ли блок новым.
  • Финализаторы (__gc метаметоды) для userdata вызываются в обратном порядке, в котором они были помечены для финализации, а не в порядке их создания (см. §2.5.1). (Большинство userdata помечаются сразу после создания.) Кроме того, если в таблице метаданных нет поля __gc при установке, финализатор не будет вызван, даже если он будет установлен позже.
  • luaL_typerror был удален. Напишите свою собственную версию, если вам это нужно.
  • Функция lua_cpcall устарела. Вы можете просто поместить функцию с помощью lua_pushcfunction и вызвать её с помощью lua_pcall.
  • Функции lua_equal и lua_lessthan устарели. Используйте новую lua_compare с соответствующими параметрами вместо них.
  • Функция lua_objlen была переименована в lua_rawlen.
  • Функция lua_load имеет дополнительный параметр, mode. Передайте NULL для имитации старого поведения.
  • Функция lua_resume имеет дополнительный параметр, from. Передайте NULL или нить, выполняющую вызов.

9 – Полный Синтаксис Lua

Вот полный синтаксис Lua в расширенном BNF. (Он не описывает приоритеты операторов.)

chunk ::= block

block ::= {stat} [retstat]

stat ::=  ‘;’ | 
	 varlist ‘=’ explist | 
	 functioncall | 
	 label | 
	 break | 
	 goto Name | 
	 do block end | 
	 while exp do block end | 
	 repeat block until exp | 
	 if exp then block {elseif exp then block} [else block] end | 
	 for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end | 
	 for namelist in explist do block end | 
	 function funcname funcbody | 
	 local function Name funcbody | 
	 local namelist [‘=’ explist] 

retstat ::= return [explist] [‘;’]

label ::= ‘::’ Name ‘::’

funcname ::= Name {‘.’ Name} [‘:’ Name]

varlist ::= var {‘,’ var}

var ::=  Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name 

namelist ::= Name {‘,’ Name}

explist ::= exp {‘,’ exp}

exp ::=  nil | false | true | Number | String | ‘...’ | functiondef | 
	 prefixexp | tableconstructor | exp binop exp | unop exp 

prefixexp ::= var | functioncall | ‘(’ exp ‘)’

functioncall ::=  prefixexp args | prefixexp ‘:’ Name args 

args ::=  ‘(’ [explist] ‘)’ | tableconstructor | String 

functiondef ::= function funcbody

funcbody ::= ‘(’ [parlist] ‘)’ block end

parlist ::= namelist [‘,’ ‘...’] | ‘...’

tableconstructor ::= ‘{’ [fieldlist] ‘}’

fieldlist ::= field {fieldsep field} [fieldsep]

field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp

fieldsep ::= ‘,’ | ‘;’

binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘^’ | ‘%’ | ‘..’ | 
	 ‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ | 
	 and | or

unop ::= ‘-’ | not | ‘#’

© 1994–2017 Lua.org, PUC-Rio.
Licensed under the MIT License.
https://www.lua.org/manual/5.2/manual.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API