3 – Язык

ENG

3 - Язык

 

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

Языковые конструкции поясняется с помощью обычной расширенной нотации BNF, в котором {a} означает 0 или больше 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).

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

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

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

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

UTF-8 кодирование символа Unicode можно вставить в строку символов с управляющей последовательностью (обратите внимание на обязательные скобки), где XXX представляет собой последовательность из одного или более шестнадцатеричных цифр , представляющих код символа. \u{XXX}

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

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

Для удобства при открытии длинный кронштейн немедленно следует символ новой строки, символ новой строки не входит в строку. В качестве примера, в системе , использующей 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   345   0xff   0xBEBADA

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

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

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

3.2 - Переменные

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

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

var ::= Name

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

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

Перед первым назначением переменной, его значение равно нулю .

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

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

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

3.3.2 - Куски

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

chunk ::= block

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

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

Куски также могут быть прекомпилирована в двоичной форме; см программы luac и функции string.dump для деталей. Программы в источнике и скомпилированные формы являются взаимозаменяемыми; Lua автоматически определяет тип файла и действует соответственно (см load).

3.3.3 - Назначение

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

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

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

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

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

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

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

x, y = y, x

обмены значения xи y, и

x, y, z = y, z, x

циклически переставляет значения x, и 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 - повторите имеют обычное значение и знакомый синтаксис:

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

Lua также имеет для заявления, в двух вариантах (см §3.3.5 ).

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

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

Гото заявление передает управление программой на этикетке. По синтаксических причинам, метки в Lua рассматриваются заявления тоже:

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

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

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

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

stat ::= break

Перерыв заканчивается внутренний цикл ограждающую.

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

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

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

3.3.5 - для постановки

Для заявления имеет две формы: один численный и один общий.

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

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

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

 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
      var = var - step
      while true do
         var = var + step
         if (step >= 0 and var > limit) or (step < 0 and var < limit) then
           break
         end
         local v = var
         block
       end
     end

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

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

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

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

Для заявления как

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

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

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

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

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

3.3.6 - Вызовы функций в отчетности

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

stat ::= functioncall

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

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

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

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

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

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

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

3.4 - Выражения

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

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

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

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

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

Вот некоторые примеры:

     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     
     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(x,y,z)) первое значение , возвращаемое f или ноль , если fне возвращает значения.)

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

Lua поддерживает следующие арифметические операторы:

  • +:  добавление
  • -:  вычитание
  • *:  умножение
  • /:  Поплавок деление
  • //:  Пол деление
  • %:  по модулю
  • ^:  экспоненцирование
  • -:  Унарный минус

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

Возведение и поплавка деление ( /) всегда преобразуют операнды к поплавки и результат всегда поплавок. Возведение использует функцию ISO Cpow, так что он работает для нецелых индексов тоже.

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

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

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

3.4.2 - Битовые операторы

Lua поддерживает следующие битовые операторы:

  • &:  Поразрядное И
  • |:  Побитовое ИЛИ
  • ~:  Побитовое исключающее ИЛИ
  • >>:  Сдвиг вправо
  • <<:  Сдвиг влево
  • ~:   Унарный побитовое НЕ

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

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

3.4.3 - Приведение и преобразование

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

Lua также преобразует строки в числа, всякий раз, когда число, как ожидается.

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

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

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

Все преобразования из строк в числа принимают как точку и текущую метку локализованную как поразрядной характер. (Лексер Lua, однако, принимает только точку.)

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

3.4.4 - Операторы отношения

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

  • ==:  равенство
  • ~=:  неравенство
  • <:  Меньше
  • > Больше
  • <=:  Меньше или равно
  • >=:  Больше или равно

Эти операторы всегда приводят к ложным или истинным .

Равенство ( ==) сравнивает первый тип операндов. Если типы различны, то результатом является ложным . В противном случае, значения операндов сравниваются. Строки сравниваются очевидным образом. Числа равны , если они обозначают один и тот же математическое значение.

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

Вы можете изменить способ , которым Lua сравнивает таблицы и UserData с помощью "Эквалайзер" метаметод (см п.2.4 ).

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

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

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

Согласно стандарту IEEE 754, NaN не считается ни меньше, ни равным, ни больше, чем любое значение (в том числе и себя).

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

Логические операторы в Lua являются и , или , а не . Как и управляющие структуры (см §3.3.4 ), все логические операторы рассматривают какложные и ноль , как ложь и все остальное , как истинный.

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

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

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

3.4.6 - конкатенация

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

3.4.7 - Длина оператора

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

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

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

{10, 20, nil, 40}

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

3.4.8 - Внеочередные

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

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

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

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

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

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

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

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

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

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

Порядок заданий в конструктор не определен. (Этот порядок будет уместен только тогда, когда повторяются ключи.)

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

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

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

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

	functioncall ::= prefixexp args

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

Форма

functioncall ::= prefixexp ‘:’ Name args

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

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

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

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

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

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.11 - Определения функций

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

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

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

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

Заявление

function f () body end

переводится

f = function () body end

Заявление

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

переводится

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

Заявление

local function f () body end

переводится

local f; f = function () body end

не

local f = function () body end

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

Определение функции является исполняемым выражение, значение которого имеет тип функции . Когда Lua precompiles кусок, все его функции тела прекомпилирована тоже. Затем, когда 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

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

Существует система зависящих от ограничений по количеству значений, что функция может возвращать. Этот предел гарантированно будет больше, чем 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объявляется не в объеме еще, и поэтому второй относится к внешней переменной.

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

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

     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.

Дале --->

Translate »