Lua (programmeringssprog) - Lua (programming language)

Lua
Lua-Logo.svg
Paradigme Multi-paradigme : scripting , imperativ ( proceduremæssigt , prototype-baseret , objektorienteret ), funktionel
Designet af Roberto Ierusalimschy
Waldemar Celes
Luiz Henrique de Figueiredo
Første gang dukkede op 1993 ; 28 år siden ( 1993 )
Stabil udgivelse
5.4.3  Rediger dette på Wikidata / 29. marts 2021 ; for 5 måneder siden ( 29. marts 2021 )
Skrive disciplin Dynamisk , stærk , and
Implementeringssprog ANSI C
OS På tværs af platforme
Licens MIT -licens
Filnavn udvidelser .lua
Internet side www .lua .org
Store implementeringer
Lua , LuaJIT , LuaVela , MoonSharp , Luvit , LuaRT
Dialekter
Metalua , Idle , GSL Shell , Luau
Påvirket af
C ++ , CLU , Modula , Scheme , SNOBOL
Påvirket
GameMonkey , Io , JavaScript , Julia , MiniD, Red , Ring, Ruby , Squirrel , MoonScript, C--

Lua ( / l U ə / LOO ; fra portugisisk : lua [ˈLu. (W) ɐ] betyder måne ) er et let , højt niveau , multi-paradigm programmeringssprog designet primært til integreret brug i applikationer. Lua er tværplatform , da tolken af kompileret bytecode er skrevet i ANSI C , og Lua har en relativt enkel C API til at integrere den i applikationer.

Lua blev oprindeligt designet i 1993 som et sprog til udvidelse af softwareapplikationer for at imødekomme den stigende efterspørgsel efter tilpasning på det tidspunkt. Det gav grundlæggende faciliteter i de fleste procedureprogrammerende sprog, men mere komplicerede eller domænespecifikke funktioner var ikke inkluderet; den inkluderede snarere mekanismer til at udvide sproget, så programmerere kunne implementere sådanne funktioner. Da Lua var tiltænkt at være et generelt indbyggeligt udvidelsessprog, fokuserede designerne på Lua på at forbedre dets hastighed , bærbarhed , udvidelse og brugervenlighed i udviklingen.

Historie

Lua blev oprettet i 1993 af Roberto Ierusalimschy , Luiz Henrique de Figueiredo og Waldemar Celes, medlemmer af Computer Graphics Technology Group (Tecgraf) ved det pavelige katolske universitet i Rio de Janeiro , i Brasilien .

Fra 1977 til 1992 havde Brasilien en politik med stærke handelshindringer (kaldet en markedsreserve) for computerhardware og -software. I den atmosfære havde Tecgrafs kunder hverken politisk eller økonomisk råd til at købe tilpasset software fra udlandet. Disse årsager fik Tecgraf til at implementere de grundlæggende værktøjer, det havde brug for fra bunden.

Luas forgængere var databeskrivelses-/konfigurationssprogene SOL (Simple Object Language) og DEL (data-entry-sprog). De var uafhængigt blevet udviklet hos Tecgraf i 1992–1993 for at tilføje en vis fleksibilitet til to forskellige projekter (begge var interaktive grafiske programmer til ingeniørprogrammer hos Petrobras -virksomheden ). Der manglede nogen flowkontrolstrukturer i SOL og DEL, og Petrobras følte et stigende behov for at tilføje fuld programmeringskraft til dem.

I The Evolution of Lua skrev sprogets forfattere:

I 1993 var den eneste rigtige konkurrent Tcl , som eksplicit var designet til at blive integreret i applikationer. Tcl havde imidlertid en ukendt syntaks, tilbød ikke god support til databeskrivelse og kørte kun på Unix -platforme. Vi overvejede ikke LISP eller Scheme på grund af deres uvenlige syntaks. Python var stadig i sin vorden. I den frie gør-det-selv-atmosfære, der dengang herskede i Tecgraf, var det helt naturligt, at vi forsøgte at udvikle vores eget scriptsprog ... Fordi mange potentielle brugere af sproget ikke var professionelle programmører, skulle sproget undgå kryptisk syntaks og semantik. Implementeringen af ​​det nye sprog bør være meget bærbar, fordi Tecgrafs klienter havde en meget forskelligartet samling af computerplatforme. Da vi endelig forventede, at andre Tecgraf -produkter også skulle integrere et scriptsprog, skulle det nye sprog følge eksemplet med SOL og leveres som et bibliotek med en C API.

Lua 1.0 blev designet på en sådan måde, at dets objektkonstruktører, da den var en smule anderledes end den nuværende lette og fleksible stil, inkorporerede databeskrivelsessyntaksen for SOL (deraf navnet Lua: Sol, der betyder "Sol" på portugisisk, og Lua betyder "Måne"). Lua syntaks for kontrolstrukturer var for det meste lånt fra Modula ( if, while, repeat/ until), men også havde taget indflydelse fra CLU (flere opgaver og flere vender tilbage fra funktionskald, som et enklere alternativ til referenceparametre eller eksplicitte pegepinde ), C ++ ( "pæn idé at tillade, at en lokal variabel kun deklareres, hvor vi har brug for det "), SNOBOL og AWK (associative arrays). I en artikel, der blev offentliggjort i Dr. Dobb's Journal , oplyser Luas skabere også, at LISP og Scheme med deres eneste, allestedsnærværende datastrukturmekanisme ( listen ) var en stor indflydelse på deres beslutning om at udvikle tabellen som Luas primære datastruktur.

Lua semantik er blevet mere og mere påvirket af Scheme over tid, især med introduktionen af anonyme funktioner og fuld leksikalsk scoping . Flere funktioner blev tilføjet i nye Lua -versioner.

Versioner af Lua før version 5.0 blev frigivet under en licens, der ligner BSD -licensen . Fra version 5.0 og fremefter er Lua blevet licenseret under MIT -licensen . Begge er tilladte gratis softwarelicenser og er næsten identiske.

Funktioner

Lua beskrives almindeligvis som et " multi-paradigm " sprog, der giver et lille sæt generelle funktioner, der kan udvides til at passe til forskellige problemtyper. Lua indeholder ikke eksplicit støtte til arv , men gør det muligt at implementere det med metatabeller . På samme måde tillader Lua programmører at implementere navneområder , klasser og andre relaterede funktioner ved hjælp af dens implementering af enkeltbord; førsteklasses funktioner gør det muligt at anvende mange teknikker fra funktionel programmering ; og fuldt leksikalt omfang gør det muligt at skjule finkornet information for at håndhæve princippet om mindst privilegium .

Generelt bestræber Lua sig på at levere enkle, fleksible metafunktioner, der kan udvides efter behov, frem for at levere et funktionssæt, der er specifikt for et programmeringsparadigme. Som et resultat, grundsproget er lys -den fuld reference tolk er kun omkring 247  kB kompilerede-og let at tilpasse til en bred vifte af anvendelser.

Lua er et dynamisk indtastet sprog beregnet til brug som et udvidelsessprog eller scriptsprog , og er kompakt nok til at passe på en lang række værtsplatforme. Det understøtter kun et lille antal atomare datastrukturer, såsom boolske værdier, tal (dobbelt præcision flydende punkt og 64-bit heltal som standard) og strenge . Typiske datastrukturer såsom arrays , sæt , lister og poster kan repræsenteres ved hjælp af Luas enkelt native datastruktur, tabellen, som i det væsentlige er en heterogen associativ matrix .

Lua implementerer et lille sæt af avancerede funktioner som førsteklasses funktioner , garbage collection , lukninger , ordentlig hale opkald , tvang (automatisk konvertering mellem snor og talværdier under kørslen), korutine (kooperativ multitasking) og dynamisk modulindlæsning .

Syntaks

Den klassiske "Hej, verden!" programmet kan skrives som følger:

print("Hello, World!")

eller som:

print 'Hello, World!'

En kommentar i Lua starter med en bindestreg og løber til slutningen af ​​linjen, svarende til Ada , Eiffel , Haskell , SQL og VHDL . Multi-line strenge og kommentarer er prydet med dobbelt firkantede parenteser.

Den faktorielle funktion implementeres som en funktion i dette eksempel:

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

Kontroller flow

Lua har fire typer sløjfer : whilesløjfen , repeatsløjfen (ligner en do whilesløjfe ), den numeriske forsløjfe og den generiske forsløjfe.

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

Den generiske forsløjfe:

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

ville iterere over tabellen _Gved hjælp af standard iterator -funktionen pairs, indtil den vender tilbage nil.

Sløjfer kan også indlejres (sættes inde i en anden sløjfe).

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

Funktioner

Luas behandling af funktioner som førsteklasses værdier er vist i følgende eksempel, hvor udskriftsfunktionens adfærd ændres:

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

Eventuelle fremtidige opkald til printvil nu blive dirigeret gennem den nye funktion, og på grund af Luas leksikale omfang vil den gamle udskriftsfunktion kun være tilgængelig med det nye, modificerede print.

Lua understøtter også lukninger , som vist nedenfor:

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.
]]

Der xoprettes en ny lukning for variablen , hver gang addtoder kaldes, så hver ny anonym funktion, der returneres, altid får adgang til sin egen xparameter. Lukningen administreres af Luas affaldssamler, ligesom ethvert andet objekt.

Tabeller

Tabeller er de vigtigste datastrukturer (og udformet den eneste indbyggede sammensatte datatype ) i Lua og er grundlaget for alle brugeroprettede typer. De er associative arrays med tilføjelse af automatisk numerisk nøgle og speciel syntaks.

En tabel er en samling af nøgle- og datapar, hvor dataene refereres af nøgle; med andre ord, det er et hasket heterogent associativt array.

Tabeller oprettes ved hjælp af {}konstruktorsyntaksen.

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

Tabeller sendes altid som reference (se Opkald ved deling ).

En nøgle (indeks) kan være enhver værdi undtagen nilog NaN , inklusive funktioner.

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.

En tabel bruges ofte som struktur (eller post ) ved at bruge strenge som nøgler. Fordi en sådan brug er meget almindelig, har Lua en særlig syntaks til adgang til sådanne felter.

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.

Ved at bruge en tabel til at gemme relaterede funktioner kan den fungere som et navneområde.

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

Tabeller tildeles automatisk en numerisk nøgle, så de kan bruges som en matrixdatatype . Det første automatiske indeks er 1 i stedet for 0, som det er for mange andre programmeringssprog (selvom et eksplicit indeks på 0 er tilladt).

En numerisk tast 1er forskellig fra en strengnøgle "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.

Længden af ​​en tabel ter defineret til at være et hvilket som helst heltalsindeks n, t[n]der ikke er nilog t[n+1]er nil; desuden, hvis det t[1]er nil, nkan være nul. For en almindelig matrix med ikke-nulværdier fra 1 til en given ner dens længde nøjagtigt det n, indekset for dens sidste værdi. Hvis matrixen har "huller" (det vil sige nulværdier mellem andre ikke-nulværdier), #tkan det være et hvilket som helst af de indeks, der direkte går forud for en nilværdi (det vil sige, at det kan betragte enhver sådan nulværdi som slutningen af ​​arrayet ).

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

En tabel kan være en række objekter.

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

Brug af et hash -kort til at efterligne et array er normalt langsommere end at bruge et egentligt array; Lua -tabeller er dog optimeret til brug som arrays for at undgå dette problem.

Metatabeller

Udvidelig semantik er et centralt træk ved Lua, og det metatable koncept tillader kraftfuld tilpasning af tabeller. Følgende eksempel viser en "uendelig" tabel. For enhver n, fibs[n]vil give nth Fibonacci-tal ved hjælp af dynamisk programmering og memoization .

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

Objektorienteret programmering

Selvom Lua ikke har et indbygget klassekoncept , kan objektorienteret programmering emuleres ved hjælp af funktioner og tabeller. Et objekt dannes ved at sætte metoder og felter i en tabel. Arv (både enkelt og flere) kan implementeres med metatabeller og delegere ikke -eksisterende metoder og felter til et overordnet objekt.

Der er ikke et begreb som "klasse" med disse teknikker; der bruges snarere prototyper , der ligner Self eller JavaScript . Nye objekter oprettes enten med en fabriksmetode (der konstruerer nye objekter fra bunden) eller ved at klone et eksisterende objekt.

Oprettelse af et grundlæggende vektorobjekt :

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)

Her setmetatablefortæller Lua at lede efter et element i Vectortabellen, hvis det ikke er til stede i vectabellen. , hvilket svarer til , ser først i tabellen efter elementet. Den tabellen har ikke en element, men dens metatable delegerede til tabellen for element, når det ikke findes i tabellen. vec.magnitudevec["magnitude"]vecmagnitudevecmagnitudeVectormagnitudevec

Lua giver noget syntaktisk sukker for at lette objektorientering. For at deklarere medlemsfunktioner inde i en prototypetabel kan man bruge , hvilket svarer til . At kalde klassemetoder gør også brug af tyktarmen: svarer til . function table:func(args)function table.func(self, args)object:func(args)object.func(object, args)

I tankerne her er en tilsvarende klasse med :syntaktisk sukker:

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)

Arv

Lua understøtter brug af metatabeller til at give Lua -klasse arv. I dette eksempel tillader vi, at vektorer får deres værdier ganget med en konstant i en afledt klasse.

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 understøtter også flere arv ; __indexkan enten være en funktion eller en tabel. Operatøroverbelastning kan også udføres; Lua metatables kan have elementer som __add, __subog så videre.

Implementering

Lua -programmer tolkes ikke direkte fra den tekstmæssige Lua -fil, men samles til bytecode, som derefter køres på den virtuelle Lua -maskine . Kompileringsprocessen er typisk usynlig for brugeren og udføres i løbetid , især når der bruges en JIT-kompilator , men det kan gøres offline for at øge indlæsningseffekten eller reducere hukommelsesaftrykket i værtsmiljøet ved at udelade kompilator. Lua bytecode kan også produceres og eksekveres indefra Lua ved hjælp af dumpfunktionen fra strengbiblioteket og load/loadstring/loadfilefunktionerne. Lua version 5.3.4 er implementeret i cirka 24.000 linjer C -kode.

Ligesom de fleste CPU'er og i modsætning til de fleste virtuelle maskiner (som er stakbaserede ), er Lua VM registerbaseret og ligner derfor mere et egentligt hardwaredesign. Registerarkitekturen undgår både overdreven kopiering af værdier og reducerer det samlede antal instruktioner pr. Funktion. Den virtuelle maskine i Lua 5 er en af ​​de første registerbaserede rene VM'er, der har en bred anvendelse. Parrot og Android 's Dalvik er to andre velkendte registerbaserede VM'er. PCSchemes VM var også registerbaseret.

Dette eksempel er bytecode -listen over den faktorielle funktion, der er defineret ovenfor (som vist af luac5.1 -kompilatoren):

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

C API

Lua er beregnet til at blive integreret i andre applikationer og giver et C API til dette formål. API'en er opdelt i to dele: Lua -kernen og Lua -hjælpebiblioteket. Lua APIs design eliminerer behovet for manuel referencehåndtering i C -kode, i modsætning til Pythons API. API'en er ligesom sproget minimalistisk. Avanceret funktionalitet er leveret af den ekstra bibliotek, som hovedsageligt består af præprocessordirektiver makroer , der bistår med komplekse bord operationer.

Lua C API er stakbaseret . Lua giver funktioner til at skubbe og pope de fleste simple C -datatyper (heltal, floats osv.) Til og fra stakken samt funktioner til manipulation af tabeller gennem stakken. Lua -stakken er noget anderledes end en traditionel stak; stakken kan f.eks. indekseres direkte. Negative indeks angiver forskydninger fra toppen af ​​stakken. For eksempel er -1 den øverste (senest skubbede værdi), mens positive indeks angiver forskydninger fra bunden (ældste værdi). Marshalling -data mellem C- og Lua -funktioner udføres også ved hjælp af stakken. For at kalde en Lua -funktion skubbes argumenter ind på stakken, og derefter lua_callbruges den til at kalde den faktiske funktion. Når man skriver en C -funktion, der skal kaldes direkte fra Lua, læses argumenterne fra stakken.

Her er et eksempel på at kalde en Lua -funktion fra 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;
}

At køre dette eksempel giver:

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

C API indeholder også nogle specielle tabeller, der er placeret på forskellige "pseudo-indekser" i Lua-stakken. Ved LUA_GLOBALSINDEXforud for Lua 5.2 er globals tabellen, _Gindefra Lua, som er den vigtigste navneområde . Der er også et register, LUA_REGISTRYINDEXhvor C -programmer kan gemme Lua -værdier til senere hentning.

Det er muligt at skrive udvidelsesmoduler ved hjælp af Lua API. Udvidelsesmoduler er delte objekter, der kan bruges til at udvide tolkens funktionalitet ved at levere indbyggede faciliteter til Lua -scripts. Fra Lua -siden vises et sådant modul som et navneområde, der indeholder dets funktioner og variabler. Lua -scripts kan indlæse udvidelsesmoduler ved hjælp af require, ligesom moduler skrevet i Lua selv. En voksende samling af moduler kendt som sten er tilgængelige via et pakkehåndteringssystem kaldet LuaRocks , i ånden fra CPAN , RubyGems og Python -æg . Prewritten Lua bindinger findes for de fleste populære programmeringssprog, herunder andre scriptsprog. For C ++ er der en række skabelonbaserede fremgangsmåder og nogle automatiske bindingsgeneratorer.

Ansøgninger

I videospiludvikling bruges Lua i vid udstrækning som et scriptsprog af programmører , hovedsageligt på grund af dets opfattede lette at integrere, hurtige udførelse og korte indlæringskurve . En af de bemærkelsesværdige spilplatforme er Roblox , hvor deres egen dialekt, Luau, bruges til scripting hurtig udvikling af spil. En anden er World of Warcraft, som også bruger en nedskaleret version af Lua.

I 2003 viste en meningsmåling foretaget af GameDev.net, at Lua var det mest populære scriptsprog til spilprogrammering. Den 12. januar 2012 blev Lua annonceret som vinder af Front Line Award 2011 fra magasinet Game Developer i kategorien Programmeringsværktøjer.

Et stort antal ikke- spilapplikationer bruger også Lua til udvidelse, f.eks. LuaTeX , en implementering af TeX - typesætningssproget , Redis , en nøgleværdidatabase , Neovim , en tekstredigerer og Nginx , en webserver .

Via Scribunto-udvidelsen er Lua tilgængelig som et scriptsprog på serversiden i MediaWiki- softwaren, der driver Wikipedia og andre wikier. Blandt dens anvendelser er at tillade integration af data fra Wikidata i artikler og at drive det automatiserede taxobox -system .

Afledte sprog

Sprog, der kompileres til Lua

  • MoonScript er en dynamisk , whitespace -sensitivt scriptsprog inspireret af CoffeeScript , der er kompileret ind Lua. Dette betyder, at den i stedet for at bruge doog end(eller {og }) til at afgrænse sektioner af kode bruger linjeskift og indrykningsstil . En bemærkelsesværdig brug af MoonScript er et videospil fordeling hjemmeside Itch.io .
  • Haxe understøtter kompilering til et Lua-mål, der understøtter Lua 5.1-5.3 samt LuaJIT 2.0 og 2.1.
  • Fennikel, en Lisp -dialekt, der er målrettet mod Lua.
  • Urn, en Lisp -dialekt, der er bygget på Lua.
  • Amulet, et ML -lignende funktionssprog , hvis kompiler sender Lua -filer.

Dialekter

  • LuaJIT (se nedenfor), JIT-aktiveret Lua 5.1-sprog med goto(fra Lua 5.2) og et C FFI .
  • Luau fra Roblox , Lua 5.1 sprog med gradvis indtastning og ergonomiske tilføjelser.
  • Ravi, JIT-aktiveret Lua 5.3 sprog med valgfri statisk typning. JIT styres af typeinformation.
  • Shine, en gaffel af LuaJIT med mange udvidelser, herunder et modulsystem og et makrosystem.

Derudover leverer Lua -brugerfællesskabet nogle strømrettelser oven på reference C -implementeringen.

LuaJIT

LuaJIT
Udvikler (er) Mike Pall
Stabil udgivelse
2.0.5 / 1. maj 2017 ; for 4 år siden ( 2017-05-01 )
Depot repo .or .cz /w /luajit-2 .0 .git
Skrevet i C , Lua
Operativ system se liste
Type Bare i tide kompilator
Licens MIT -licens
Internet side luajit .org

LuaJIT er en just in time compiler til Lua. Det har været brugt til indlejring eller til generelle formål. I version 2.0 af LuaJIT er projektet blevet omskrevet til bedre optimeringer af ydeevnen.

Historie

LuaJIT -projektet er startet i 2005 af udvikleren Mike Pall, frigivet under MIT open source -licensen. Den seneste udgivelse, 2.0.5 udkommer i 2017. Siden da er projektet i øjeblikket ikke vedligeholdt af andre udviklere end bidragsydere.

Installation

LuaJIT er open source, og projektet skal kompileres, for at det kan bruges. Depotet skal downloades med Git eller andre metoder til download af lagre. Derefter kompileres den med en hvilken som helst C -kompiler, normalt med GNU -fabrikat , men andre muligheder er tilgængelige. Endelig skal LuaJIT -eksekverbare filer og Lua 5.1 DLL være i samme bibliotek, for at LuaJIT -kompilatoren kan bruges.

Der er en vejledning til brug af LuaJIT -kompilatoren, som indeholder kommandolinjemuligheder.

Ydeevne

Sammenlignet med andre Lua-løbetider er LuaJIT ofte den hurtigste Lua-kompilator.

Platforme

LuaJIT kan bruges i:

Det kan kompileres ved hjælp af enten GCC , Clang eller MSVC .

Eksempler

FFi -biblioteket kan bruges til at kalde C -funktioner og bruge C -datastrukturer fra Lua Code. Der er en vejledning fra LuaJIT om brug af dette bibliotek. Som sådan er der flere LuaJIT -bindinger til C -biblioteker, der bruger FFI -biblioteket. Dette eksempel vil kalde en C -funktion, printf fra ren Lua -kode og udsender Hello world! .

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

LuaJIT -kompilatoren har også tilføjet nogle udvidelser til Luas C API. Dette eksempel skrevet i C ++ ville blive brugt til fejlfinding .

#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);
  ...
}

Se også

Noter

Referencer

Yderligere læsning

eksterne links