Lua (linguagem de programação) - Lua (programming language)

Lua
Lua-Logo.svg
Paradigma Multi-paradigma : script , imperativo ( procedural , baseado em protótipo , orientado a objetos ), funcional
Projetado por Roberto Ierusalimschy
Waldemar Celes
Luiz Henrique de Figueiredo
Apareceu pela primeira vez 1993 ; 28 anos atrás ( 1993 )
Versão estável
5.4.3  Edite isso no Wikidata / 29 de março de 2021 ; 5 meses atrás ( 29 de março de 2021 )
Disciplina de digitação Dinâmico , forte , pato
Linguagem de implementação ANSI C
SO Plataforma cruzada
Licença Licença MIT
Extensões de nome de arquivo .lua
Local na rede Internet www .lua .org
Implementações principais
Lua , LuaJIT , LuaVela , MoonSharp , Luvit , LuaRT
Dialetos
Metalua , Idle , GSL Shell , Luau
Influenciado por
C ++ , CLU , Modula , Scheme , SNOBOL
Influenciado
GameMonkey , Io , JavaScript , Julia , MiniD, Red , Ring, Ruby , Squirrel , MoonScript, C--

Lua ( / l L ə / LOO ; de Português : lua [ˈLu. (W) ɐ] que significa lua ) é uma linguagem de programação leve , de alto nível e multiparadigma projetada principalmente para uso integrado em aplicativos. Lua é uma plataforma cruzada , uma vez que o interpretador do bytecode compilado é escrito em ANSI C , e Lua tem uma API C relativamente simplespara embuti-la em aplicativos.

Lua foi originalmente projetada em 1993 como uma linguagem para estender aplicativos de software para atender à crescente demanda por customização da época. Ele forneceu os recursos básicos da maioria das linguagens de programação procedural , mas os recursos mais complicados ou específicos do domínio não foram incluídos; em vez disso, incluiu mecanismos para estender a linguagem, permitindo que os programadores implementem tais recursos. Como Lua foi planejada para ser uma linguagem de extensão incorporável geral, os designers de Lua se concentraram em melhorar sua velocidade , portabilidade , extensibilidade e facilidade de uso no desenvolvimento.

História

Lua foi criada em 1993 por Roberto Ierusalimschy , Luiz Henrique de Figueiredo e Waldemar Celes, integrantes do Grupo de Tecnologia de Computação Gráfica (Tecgraf) da Pontifícia Universidade Católica do Rio de Janeiro , Brasil .

De 1977 a 1992, o Brasil teve uma política de fortes barreiras comerciais (chamadas de reserva de mercado) para hardware e software de computador. Nesse ambiente, os clientes do Tecgraf não podiam se dar ao luxo, política ou financeiramente, de comprar software customizado do exterior. Esses motivos levaram o Tecgraf a implantar do zero as ferramentas básicas de que precisava.

Os predecessores de Lua foram as linguagens de descrição / configuração de dados SOL (Simple Object Language) e DEL (linguagem de entrada de dados). Eles foram desenvolvidos de forma independente na Tecgraf em 1992–1993 para adicionar alguma flexibilidade a dois projetos diferentes (ambos eram programas gráficos interativos para aplicações de engenharia na empresa Petrobras ). Havia uma falta de quaisquer estruturas de controle de fluxo em SOL e DEL, e a Petrobras sentiu uma necessidade crescente de adicionar total poder de programação a elas.

Em The Evolution of Lua , os autores da linguagem escreveram:

Em 1993, o único contendor real era o Tcl , que havia sido explicitamente projetado para ser embutido em aplicativos. No entanto, o Tcl tinha uma sintaxe desconhecida, não oferecia um bom suporte para descrição de dados e era executado apenas em plataformas Unix. Não consideramos LISP ou Scheme por causa de sua sintaxe hostil. Python ainda estava em sua infância. Na atmosfera livre e do tipo faça você mesmo que reinava no Tecgraf, era bastante natural que tentássemos desenvolver nossa própria linguagem de script ... Como muitos usuários em potencial da linguagem não eram programadores profissionais, a linguagem deve evitar o enigmático sintaxe e semântica. A implementação da nova linguagem deve ser altamente portátil, pois os clientes do Tecgraf possuíam um acervo de plataformas de computador muito diversificado. Por fim, como esperávamos que outros produtos Tecgraf também precisassem incorporar uma linguagem de script, a nova linguagem deve seguir o exemplo do SOL e ser fornecida como uma biblioteca com uma API C.

Lua 1.0 foi projetada de tal forma que seus construtores de objetos, sendo então ligeiramente diferentes do estilo leve e flexível atual, incorporaram a sintaxe de descrição de dados de SOL (daí o nome Lua: Sol significa "Sol" em português, e Lua significa "Lua"). Lua sintaxe para estruturas de controle foi principalmente emprestado do Modula ( if, while, repeat/ until), mas também tinha tomado influência de CLU (várias atribuições e vários retornos de chamadas de função, como uma alternativa mais simples de parâmetros de referência ou explícitas ponteiros ), C ++ ( "puro ideia de permitir que uma variável local seja declarada apenas onde precisamos "), SNOBOL e AWK (matrizes associativas). Em um artigo publicado no Dr. Dobb's Journal , os criadores de Lua também afirmam que o LISP e o Scheme, com seu mecanismo de estrutura de dados único e onipresente (a lista ), foram uma grande influência em sua decisão de desenvolver a tabela como a estrutura de dados primária de Lua.

A semântica de Lua tem sido cada vez mais influenciada pelo Scheme ao longo do tempo, especialmente com a introdução de funções anônimas e escopo léxico completo . Vários recursos foram adicionados em novas versões do Lua.

As versões da Lua anteriores à versão 5.0 foram lançadas sob uma licença semelhante à licença BSD . Da versão 5.0 em diante, Lua foi licenciada sob a Licença MIT . Ambas são licenças de software livre permissivas e quase idênticas.

Recursos

Lua é comumente descrita como uma linguagem " multiparadigma ", fornecendo um pequeno conjunto de recursos gerais que podem ser estendidos para se adequar a diferentes tipos de problemas. Lua não contém suporte explícito para herança , mas permite que ela seja implementada com meta - tabelas . Da mesma forma, Lua permite que os programadores implementem namespaces , classes e outros recursos relacionados usando sua implementação de tabela única; funções de primeira classe permitem o emprego de muitas técnicas de programação funcional ; e o escopo léxico completo permite a ocultação de informações de baixa granularidade para fazer cumprir o princípio do menor privilégio .

Em geral, Lua se esforça para fornecer meta-recursos simples e flexíveis que podem ser estendidos conforme necessário, em vez de fornecer um conjunto de recursos específico para um paradigma de programação. Como resultado, a linguagem base é leve - o interpretador de referência completa tem apenas cerca de 247  kB compilado - e facilmente adaptável a uma ampla gama de aplicativos.

Uma linguagem digitada dinamicamente destinada ao uso como uma linguagem de extensão ou linguagem de script , Lua é compacta o suficiente para caber em uma variedade de plataformas hospedeiras. Ele suporta apenas um pequeno número de estruturas de dados atômicas, como valores booleanos , números ( ponto flutuante de precisão dupla e inteiros de 64 bits por padrão) e strings . Estruturas de dados típicas, como matrizes , conjuntos , listas e registros, podem ser representadas usando a única estrutura de dados nativa de Lua, a tabela, que é essencialmente uma matriz associativa heterogênea .

Lua implementa um pequeno conjunto de recursos avançados, como funções de primeira classe , coleta de lixo , encerramentos , chamadas finais adequadas , coerção (conversão automática entre valores de string e números em tempo de execução), corrotinas (multitarefa cooperativa) e carregamento de módulo dinâmico .

Sintaxe

O clássico "Hello, World!" programa pode ser escrito da seguinte forma:

print("Hello, World!")

ou como:

print 'Hello, World!'

Um comentário em Lua começa com um hífen duplo e vai até o final da linha, semelhante a Ada , Eiffel , Haskell , SQL e VHDL . Seqüências de caracteres com várias linhas e comentários são adornados com colchetes duplos.

A função fatorial é implementada como uma função neste exemplo:

function factorial(n)
  local x = 1
  for i = 2, n do
    x = x * i
  end
  return x
end

Controle de fluxo

Lua tem quatro tipos de loops : o whileloop , o repeatloop (semelhante a um do whileloop ), o forloop numérico e o forloop genérico .

--condition = true

while condition do
  --statements
end

repeat
  --statements
until condition

for i = first, last, delta do  --delta may be negative, allowing the for loop to count down or up
  --statements
  --example: print(i)
end

O forloop genérico :

for key, value in pairs(_G) do
  print(key, value)
end

iria iterar sobre a tabela _Gusando a função iteradora padrão pairs, até retornar nil.

Os loops também podem ser aninhados (colocados dentro de outro loop).

local grid = {
  { 11, 12, 13 },
  { 21, 22, 23 },
  { 31, 32, 33 }
}

for y, row in ipairs(grid) do
  for x, value in ipairs(row) do
    print(x, y, value)
  end
end

Funções

O tratamento de Lua das funções como valores de primeira classe é mostrado no exemplo a seguir, onde o comportamento da função de impressão é modificado:

do
  local oldprint = print
  -- Store current print function as oldprint
  function print(s)
    --[[ Redefine print function. The usual print function can still be used
      through oldprint. The new one has only one argument.]]
    oldprint(s == "foo" and "bar" or s)
  end
end

Todas as chamadas futuras para printagora serão roteadas por meio da nova função e, por causa do escopo léxico de Lua , a função de impressão antiga só estará acessível pela nova impressão modificada.

Lua também oferece suporte a encerramentos , conforme demonstrado abaixo:

function addto(x)
  -- Return a new function that adds x to the argument
  return function(y)
    --[=[ When we refer to the variable x, which is outside the current
      scope and whose lifetime would be shorter than that of this anonymous
      function, Lua creates a closure.]=]
    return x + y
  end
end
fourplus = addto(4)
print(fourplus(3))  -- Prints 7

--This can also be achieved by calling the function in the following way:
print(addto(4)(3))
--[[ This is because we are calling the returned function from 'addto(4)' with the argument '3' directly.
  This also helps to reduce data cost and up performance if being called iteratively.
]]

Um novo fechamento para a variável xé criado a cada vez que addtoé chamada, de forma que cada nova função anônima retornada sempre acessará seu próprio xparâmetro. O fechamento é gerenciado pelo coletor de lixo de Lua, assim como qualquer outro objeto.

Mesas

As tabelas são as estruturas de dados mais importantes (e, por design, o único tipo de dados composto embutido ) em Lua e são a base de todos os tipos criados pelo usuário. Eles são matrizes associativas com adição de chave numérica automática e sintaxe especial.

Uma tabela é uma coleção de pares de chave e dados, onde os dados são referenciados por chave; em outras palavras, é uma matriz associativa heterogênea em hash .

As tabelas são criadas usando a {}sintaxe do construtor.

a_table = {} -- Creates a new, empty table

As tabelas são sempre passadas por referência (ver Chamada por compartilhamento ).

Uma chave (índice) pode ser qualquer valor, exceto nile NaN , incluindo funções.

a_table = {x = 10}  -- Creates a new table, with one entry mapping "x" to the number 10.
print(a_table["x"]) -- Prints the value associated with the string key, in this case 10.
b_table = a_table
b_table["x"] = 20   -- The value in the table has been changed to 20.
print(b_table["x"]) -- Prints 20.
print(a_table["x"]) -- Also prints 20, because a_table and b_table both refer to the same table.

Uma tabela é freqüentemente usada como estrutura (ou registro ) usando strings como chaves. Como esse uso é muito comum, Lua apresenta uma sintaxe especial para acessar esses campos.

point = { x = 10, y = 20 }   -- Create new table
print(point["x"])            -- Prints 10
print(point.x)               -- Has exactly the same meaning as line above. The easier-to-read dot notation is just syntactic sugar.

Ao usar uma tabela para armazenar funções relacionadas, ela pode atuar como um namespace.

Point = {}

Point.new = function(x, y)
  return {x = x, y = y}  --  return {["x"] = x, ["y"] = y}
end

Point.set_x = function(point, x)
  point.x = x  --  point["x"] = x;
end

As tabelas são atribuídas automaticamente a uma tecla numérica, permitindo que sejam usadas como um tipo de dados de matriz . O primeiro índice automático é 1 em vez de 0, como é para muitas outras linguagens de programação (embora um índice explícito de 0 seja permitido).

Uma chave numérica 1é diferente de uma chave de string "1".

array = { "a", "b", "c", "d" }   -- Indices are assigned automatically.
print(array[2])                  -- Prints "b". Automatic indexing in Lua starts at 1.
print(#array)                    -- Prints 4.  # is the length operator for tables and strings.
array[0] = "z"                   -- Zero is a legal index.
print(#array)                    -- Still prints 4, as Lua arrays are 1-based.

O comprimento de uma tabela té definido como qualquer índice inteiro nque t[n]não é nile t[n+1]é nil; além disso, se t[1]for nil, npode ser zero. Para uma matriz regular, com valores não nulos de 1 a um dado n, seu comprimento é exatamente isso n, o índice de seu último valor. Se a matriz tiver "lacunas" (ou seja, valores nulos entre outros valores não nulos), então #tpode ser qualquer um dos índices que precede diretamente um nilvalor (ou seja, pode considerar qualquer valor nulo como o final da matriz )

ExampleTable =
{
  {1, 2, 3, 4},
  {5, 6, 7, 8}
}
print(ExampleTable[1][3]) -- Prints "3"
print(ExampleTable[2][4]) -- Prints "8"

Uma tabela pode ser uma matriz de objetos.

function Point(x, y)        -- "Point" object constructor
  return { x = x, y = y }   -- Creates and returns a new object (table)
end
array = { Point(10, 20), Point(30, 40), Point(50, 60) }   -- Creates array of points
                        -- array = { { x = 10, y = 20 }, { x = 30, y = 40 }, { x = 50, y = 60 } };
print(array[2].y)                                         -- Prints 40

Usar um mapa hash para emular uma matriz normalmente é mais lento do que usar uma matriz real; no entanto, as tabelas Lua são otimizadas para uso como matrizes para ajudar a evitar esse problema.

Meta-tabelas

A semântica extensível é um recurso-chave de Lua, e o conceito de metatabela permite uma personalização poderosa de tabelas. O exemplo a seguir demonstra uma tabela "infinita". Para qualquer um n, fibs[n]fornecerá o n-ésimo número de Fibonacci usando programação dinâmica e memoização .

fibs = { 1, 1 }                                -- Initial values for fibs[1] and fibs[2].
setmetatable(fibs, {
  __index = function(values, n)                --[[__index is a function predefined by Lua, 
                                                   it is called if key "n" does not exist.]]
    values[n] = values[n - 1] + values[n - 2]  -- Calculate and memorize fibs[n].
    return values[n]
  end
})

Programação orientada a objetos

Embora Lua não tenha um conceito embutido de classes , a programação orientada a objetos pode ser emulada usando funções e tabelas. Um objeto é formado colocando métodos e campos em uma tabela. A herança (única e múltipla) pode ser implementada com meta - tabelas , delegando métodos e campos inexistentes a um objeto pai.

Não existe um conceito como "classe" com essas técnicas; em vez disso, são usados protótipos , semelhantes a Self ou JavaScript . Novos objetos são criados com um método de fábrica (que constrói novos objetos do zero) ou pela clonagem de um objeto existente.

Criando um objeto vetorial básico :

local Vector = {}
local VectorMeta = { __index = Vector}

function Vector.new(x, y, z)    -- The constructor
  return setmetatable({x = x, y = y, z = z}, VectorMeta)
end

function Vector.magnitude(self)     -- Another method
  return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end

local vec = Vector.new(0, 1, 0) -- Create a vector
print(vec.magnitude(vec))       -- Call a method (output: 1)
print(vec.x)                    -- Access a member variable (output: 0)

Aqui, setmetatablediz a Lua para procurar um elemento na Vectortabela se ele não estiver presente na vectabela. , que é equivalente a , primeiro procura o elemento na tabela . A tabela não tem um elemento, mas sua metatabela delega à tabela para o elemento quando não é encontrado na tabela. vec.magnitudevec["magnitude"]vecmagnitudevecmagnitudeVectormagnitudevec

Lua fornece algum açúcar sintático para facilitar a orientação a objetos. Para declarar funções de membro dentro de uma tabela de protótipo, pode-se usar , que é equivalente a . Chamar métodos de classe também usa dois-pontos: é equivalente a . function table:func(args)function table.func(self, args)object:func(args)object.func(object, args)

Com isso em mente, aqui está uma classe correspondente com :açúcar sintático:

local Vector = {}
Vector.__index = Vector

function Vector:new(x, y, z)    -- The constructor
  -- Since the function definition uses a colon, 
  -- its first argument is "self" which refers
  -- to "Vector"
  return setmetatable({x = x, y = y, z = z}, self)
end

function Vector:magnitude()     -- Another method
  -- Reference the implicit object using self
  return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end

local vec = Vector:new(0, 1, 0) -- Create a vector
print(vec:magnitude())          -- Call a method (output: 1)
print(vec.x)                    -- Access a member variable (output: 0)

Herança

Lua suporta o uso de meta-tabelas para fornecer herança de classe. Neste exemplo, permitimos que os vetores tenham seus valores multiplicados por uma constante em uma classe derivada.

local Vector = {}
Vector.__index = Vector

function Vector:new(x, y, z)    -- The constructor
  -- Here, self refers to whatever class's "new"
  -- method we call.  In a derived class, self will
  -- be the derived class; in the Vector class, self
  -- will be Vector
  return setmetatable({x = x, y = y, z = z}, self)
end

function Vector:magnitude()     -- Another method
  -- Reference the implicit object using self
  return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end

-- Example of class inheritance
local VectorMult = {}
VectorMult.__index = VectorMult
setmetatable(VectorMult, Vector) -- Make VectorMult a child of Vector

function VectorMult:multiply(value) 
  self.x = self.x * value
  self.y = self.y * value
  self.z = self.z * value
  return self
end

local vec = VectorMult:new(0, 1, 0) -- Create a vector
print(vec:magnitude())          -- Call a method (output: 1)
print(vec.y)                    -- Access a member variable (output: 1)
vec:multiply(2)                 -- Multiply all components of vector by 2
print(vec.y)                    -- Access member again (output: 2)

Lua também suporta herança múltipla ; __indexpode ser uma função ou uma tabela. A sobrecarga do operador também pode ser feita; Metatables Lua pode ter elementos, tais como __add, __sube assim por diante.

Implementação

Os programas Lua não são interpretados diretamente do arquivo Lua textual, mas são compilados em bytecode, que é então executado na máquina virtual Lua . O processo de compilação é normalmente invisível para o usuário e é executado durante o tempo de execução , especialmente quando um compilador JIT é usado, mas pode ser feito offline para aumentar o desempenho de carregamento ou reduzir a pegada de memória do ambiente host, deixando de fora o compilador. O bytecode Lua também pode ser produzido e executado de dentro de Lua, usando a dumpfunção da biblioteca de strings e as load/loadstring/loadfilefunções. Lua versão 5.3.4 é implementada em aproximadamente 24.000 linhas de código C.

Como a maioria das CPUs, e ao contrário da maioria das máquinas virtuais (que são baseadas em pilha ), a Lua VM é baseada em registros e , portanto, se assemelha mais a um projeto de hardware real. A arquitetura de registro evita a cópia excessiva de valores e reduz o número total de instruções por função. A máquina virtual de Lua 5 é uma das primeiras VMs puras baseadas em registros a ter amplo uso. Parrot e Android 's Dalvik são dois outros conhecido-bem VMs à base de registo. A VM da PCScheme também era baseada em registro.

Este exemplo é a listagem de bytecode da função fatorial definida acima (conforme mostrado pelo luaccompilador 5.1):

function <factorial.lua:1,7> (9 instructions, 36 bytes at 0x8063c60)
1 param, 6 slots, 0 upvalues, 6 locals, 2 constants, 0 functions
	1	[2]	LOADK    	1 -1	; 1
	2	[3]	LOADK    	2 -2	; 2
	3	[3]	MOVE     	3 0
	4	[3]	LOADK    	4 -1	; 1
	5	[3]	FORPREP  	2 1	; to 7
	6	[4]	MUL      	1 1 5
	7	[3]	FORLOOP  	2 -2	; to 6
	8	[6]	RETURN   	1 2
	9	[7]	RETURN   	0 1

API C

Lua se destina a ser embarcada em outras aplicações e fornece uma API C para esse propósito. A API é dividida em duas partes: o núcleo de Lua e a biblioteca auxiliar de Lua. O design da API Lua elimina a necessidade de gerenciamento de referência manual no código C, ao contrário da API do Python . A API, assim como a linguagem, é minimalista. A funcionalidade avançada é fornecida pela biblioteca auxiliar, que consiste em grande parte em macros de pré-processador que auxiliam em operações complexas de tabela.

A API Lua C é baseada em pilha . Lua fornece funções para enviar e retirar os tipos de dados C mais simples (inteiros, flutuantes, etc.) de e para a pilha, bem como funções para manipular tabelas por meio da pilha. A pilha Lua é um pouco diferente de uma pilha tradicional; a pilha pode ser indexada diretamente, por exemplo. Índices negativos indicam deslocamentos do topo da pilha. Por exemplo, −1 é o topo (valor empurrado mais recentemente), enquanto os índices positivos indicam deslocamentos da parte inferior (valor mais antigo). O empacotamento de dados entre funções C e Lua também é feito usando a pilha. Para chamar uma função Lua, os argumentos são colocados na pilha e, em seguida, lua_callsão usados ​​para chamar a função real. Ao escrever uma função C para ser chamada diretamente de Lua, os argumentos são lidos da pilha.

Aqui está um exemplo de chamada de uma função Lua a partir de C:

#include <stdio.h>
#include <lua.h> // Lua main library (lua_*)
#include <lauxlib.h> // Lua auxiliary library (luaL_*)

int main(void)
{
    // create a Lua state
    lua_State *L = luaL_newstate();

    // load and execute a string
    if (luaL_dostring(L, "function foo (x,y) return x+y end")) {
        lua_close(L);
        return -1;
    }

    // push value of global "foo" (the function defined above)
    // to the stack, followed by integers 5 and 3
    lua_getglobal(L, "foo");
    lua_pushinteger(L, 5);
    lua_pushinteger(L, 3);
    lua_call(L, 2, 1); // call a function with two arguments and one return value
    printf("Result: %d\n", lua_tointeger(L, -1)); // print integer value of item at stack top
    lua_pop(L, 1); // return stack to original state
    lua_close(L); // close Lua state
    return 0;
}

A execução deste exemplo dá:

$ cc -o example example.c -llua
$ ./example
Result: 8

A API C também fornece algumas tabelas especiais, localizadas em vários "pseudo-índices" na pilha Lua. Na LUA_GLOBALSINDEXantes de Lua 5.2 é a tabela de globals, _Gde dentro Lua, que é o principal espaço de nomes . Também há um registro localizado LUA_REGISTRYINDEXonde os programas C podem armazenar valores Lua para recuperação posterior.

É possível escrever módulos de extensão usando a API Lua. Módulos de extensão são objetos compartilhados que podem ser usados ​​para estender a funcionalidade do interpretador, fornecendo recursos nativos para scripts Lua. Do lado de Lua, tal módulo aparece como uma tabela de namespace contendo suas funções e variáveis. Os scripts Lua podem carregar módulos de extensão usando require, assim como os módulos escritos na própria Lua. Uma coleção crescente de módulos conhecidos como rocks estão disponíveis por meio de um sistema de gerenciamento de pacotes chamado LuaRocks , no espírito de CPAN , RubyGems e Python eggs . Pré-escrita Lua bindings existem para a maioria das linguagens de programação populares, incluindo outras linguagens de script. Para C ++, há uma série de abordagens baseadas em modelo e alguns geradores de vinculação automática.

Formulários

No desenvolvimento de videogames , Lua é amplamente usada como linguagem de script por programadores , principalmente devido à sua facilidade de incorporação, execução rápida e curva de aprendizado curta . Uma das plataformas de jogos notáveis ​​é o Roblox, no qual seu próprio dialeto, Luau, é usado para criar scripts de desenvolvimento rápido de jogos. Outro é o World of Warcraft, que também usa uma versão reduzida de Lua.

Em 2003, uma pesquisa conduzida pela GameDev.net mostrou que Lua era a linguagem de script mais popular para programação de jogos. No dia 12 de janeiro de 2012, Lua foi anunciada como vencedora do Front Line Award 2011 da revista Game Developer na categoria Ferramentas de Programação.

Um grande número de aplicativos não relacionados a jogos também usa Lua para extensibilidade, como LuaTeX , uma implementação da linguagem de configuração de tipo TeX , Redis , um banco de dados de valor-chave , Neovim , um editor de texto, e Nginx , um servidor web .

Por meio da extensão Scribunto, Lua está disponível como uma linguagem de script do lado do servidor no software MediaWiki que alimenta a Wikipedia e outros wikis. Entre seus usos estão permitir a integração de dados do Wikidata em artigos e alimentar o sistema de taxobox automatizado .

Línguas derivadas

Linguagens que compilam para Lua

Dialetos

  • LuaJIT (veja abaixo), linguagem Lua 5.1 habilitada para JIT com goto(a partir de Lua 5.2) e um C FFI .
  • Luau de Roblox , linguagem Lua 5.1 com digitação gradual e acréscimos ergonômicos.
  • Ravi, linguagem Lua 5.3 habilitada para JIT com tipagem estática opcional. O JIT é guiado por informações de tipo.
  • Shine, um fork do LuaJIT com muitas extensões, incluindo um sistema de módulos e um sistema de macro.

Além disso, a comunidade de usuários de Lua fornece alguns patches avançados além da implementação C de referência.

LuaJIT

LuaJIT
Desenvolvedor (s) Mike Pall
Versão estável
2.0.5 / 1 de maio de 2017 ; 4 anos atras ( 01-05-2017 )
Repositório repo .ou .cz / w / luajit-2 .0 .git
Escrito em C , Lua
Sistema operacional ver lista
Modelo Compilador just in time
Licença Licença MIT
Local na rede Internet luajit .org

LuaJIT é um compilador just in time para Lua. Ele tem sido usado para incorporação ou para fins gerais. Na versão 2.0 do LuaJIT, o projeto foi reescrito para melhores otimizações de desempenho.

História

O projeto LuaJIT foi iniciado em 2005 pelo desenvolvedor Mike Pall, lançado sob a licença de código aberto do MIT. A versão mais recente, 2.0.5, foi lançada em 2017. Desde então, o projeto não é mantido por desenvolvedores além de colaboradores.

Instalação

LuaJIT é um código aberto e o projeto deve ser compilado para ser usado. O repositório terá que ser baixado com Git ou outros métodos de download de repositórios. Em seguida, ele é compilado com qualquer compilador C, geralmente com GNU make , mas outras opções estão disponíveis. Finalmente, o executável LuaJIT e a DLL Lua 5.1 devem estar no mesmo diretório para que o compilador LuaJIT seja usado.

Há um guia sobre como usar o compilador LuaJIT que inclui opções de linha de comando.

atuação

Quando comparado a outros tempos de execução Lua, LuaJIT é frequentemente o compilador Lua mais rápido.

Plataformas

LuaJIT pode ser usado em:

Ele pode ser compilado usando GCC , Clang ou MSVC .

Exemplos

A biblioteca FFi pode ser usada para chamar funções C e usar estruturas de dados C do Lua Code. Há um guia fornecido pela LuaJIT sobre o uso dessa biblioteca. Como tal, existem várias ligações LuaJIT para bibliotecas C que usam a Biblioteca FFI. Este exemplo chamaria uma função C, printf do código Lua puro e geraria Hello world! .

local ffi = require("ffi")
ffi.cdef[[
int printf(const char *fmt, ...);
]]
ffi.C.printf("Hello world!\n")

O compilador LuaJIT também adicionou algumas extensões à API C de Lua. Este exemplo escrito em C ++ seria usado para fins de depuração .

#include <exception>
#include "lua.hpp"

// Catch C++ exceptions and convert them to Lua error messages.
// Customize as needed for your own exception classes.
static int wrap_exceptions(lua_State *L, lua_CFunction f)
{
  try {
    return f(L);  // Call wrapped function and return result.
  } catch (const char *s) {  // Catch and convert exceptions.
    lua_pushstring(L, s);
  } catch (std::exception& e) {
    lua_pushstring(L, e.what());
  } catch (...) {
    lua_pushliteral(L, "caught (...)");
  }
  return lua_error(L);  // Rethrow as a Lua error.
}

static int myinit(lua_State *L)
{
  ...
  // Define wrapper function and enable it.
  lua_pushlightuserdata(L, (void *)wrap_exceptions);
  luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
  lua_pop(L, 1);
  ...
}

Veja também

Notas

Referências

Leitura adicional

links externos