Lua (programovací jazyk) - Lua (programming language)

Lua
Lua-Logo.svg
Paradigma Multi-paradigma : skriptovací , imperativní ( procedurální , založené na prototypech , objektově orientované ), funkční
Navrhl Roberto Ierusalimschy
Waldemar Celes
Luiz Henrique de Figueiredo
Poprvé se objevil 1993 ; Před 28 lety ( 1993 )
Stabilní uvolnění
5.4.3  Upravte to na Wikidata / 29. března 2021 ; před 5 měsíci ( 29. března 2021 )
Kázeň při psaní Dynamický , silný , kachna
Implementační jazyk ANSI C.
OS Cross-platform
Licence Licence MIT
Rozšíření názvu souboru .lua
webová stránka www .lua .org
Hlavní implementace
Lua , LuaJIT , LuaVela , MoonSharp , Luvit , LuaRT
Nářečí
Metalua , Idle , GSL Shell , Luau
Ovlivněn
C ++ , CLU , Modula , Scheme , SNOBOL
Ovlivněn
GameMonkey , Io , JavaScript , Julia , MiniD, Red , Ring, Ruby , Squirrel , MoonScript, C--

Lua ( / l Ü ə / LOO , z portugalštiny : Lua [Lu. (W) ɐ] význam měsíc ) je lehký , high-level , multi-paradigma programovací jazyk, určený především pro embedded použití v aplikacích. Lua je cross-platform , protože interpret z zkompilovaný bytecode je napsán v ANSI C a Lua má poměrně jednoduchý C API vložit jej do aplikace.

Lua byl původně navržen v roce 1993 jako jazyk pro rozšiřování softwarových aplikací, aby uspokojil rostoucí poptávku po přizpůsobení v té době. Poskytovalo základní vybavení většiny procedurálních programovacích jazyků, ale komplikovanější funkce nebo funkce specifické pro doménu nebyly zahrnuty; spíše obsahoval mechanismy pro rozšíření jazyka, což programátorům umožňuje implementovat takové funkce. Vzhledem k tomu, že Lua byl zamýšlen jako obecný rozšiřitelný jazyk pro vložení, zaměřili se návrháři Lua na zlepšení jeho rychlosti , přenositelnosti , rozšiřitelnosti a snadnosti použití při vývoji.

Dějiny

Lua vytvořil v roce 1993 Roberto Ierusalimschy , Luiz Henrique de Figueiredo a Waldemar Celes, členové skupiny Computer Graphics Technology Group (Tecgraf) na Papežské katolické univerzitě v Rio de Janeiru v Brazílii .

Od roku 1977 do roku 1992 měla Brazílie politiku silných obchodních překážek (nazývaná tržní rezerva) pro počítačový hardware a software. V této atmosféře si klienti společnosti Tecgraf nemohli dovolit, politicky ani finančně, kupovat software na míru ze zahraničí. Tyto důvody vedly Tecgraf k implementaci základních nástrojů, které potřeboval od nuly.

Luovými předchůdci byly jazyky popisu/konfigurace dat SOL (Simple Object Language) a DEL (jazyk pro zadávání dat). Byly nezávisle vyvinuty ve společnosti Tecgraf v letech 1992–1993, aby přidaly určitou flexibilitu do dvou různých projektů (oba byly interaktivní grafické programy pro inženýrské aplikace ve společnosti Petrobras ). V SOL a DEL chyběly jakékoli struktury řízení toku a Petrobras cítil rostoucí potřebu přidat jim plnou programovací sílu.

V knize The Evolution of Lua autoři jazyka napsali:

V roce 1993 byl jediným skutečným uchazečem Tcl , který byl výslovně navržen pro zabudování do aplikací. Tcl však měl neznámou syntaxi, nenabízel dobrou podporu pro popis dat a běžel pouze na unixových platformách. Neuvažovali jsme o LISP nebo Scheme kvůli jejich nepřátelské syntaxi. Python byl stále v plenkách. Ve svobodné, kutilské atmosféře, která tehdy vládla v Tecgrafu, bylo zcela přirozené, že bychom se měli pokusit vyvinout vlastní skriptovací jazyk ... Protože mnoho potenciálních uživatelů jazyka nebyli profesionální programátoři, jazyk by se měl vyvarovat záhadných syntaxe a sémantika. Implementace nového jazyka by měla být vysoce přenosná, protože klienti Tecgrafu měli velmi různorodou sbírku počítačových platforem. Nakonec, protože jsme očekávali, že další produkty Tecgraf budou také potřebovat vložit skriptovací jazyk, nový jazyk by měl následovat příkladu SOL a měl by být poskytován jako knihovna s C API.

Lua 1.0 byl navržen takovým způsobem, že jeho konstruktory objektů, které se tehdy mírně lišily od současného lehkého a flexibilního stylu, začlenily syntaxi popisu dat SOL (odtud název Lua: Sol znamená „slunce“ v portugalštině a Lua znamená "Měsíc"). Lua syntaxe řídicích struktur byl většinou půjčil si od Modula ( if, while, repeat/ until), ale také vzal vliv od CLU (více úkolů a více výnosy z volání funkcí, jako jednodušší alternativa k referenční parametry a explicitních ukazatele ), C ++ ( "úhledné myšlence umožnění deklarace lokální proměnné pouze tam, kde ji potřebujeme “), SNOBOL a AWK (asociativní pole). V článku publikovaném v časopise Dr. Dobba , Luovi tvůrci také uvádějí, že LISP a Scheme s jejich jediným, všudypřítomným mechanismem struktury dat ( seznam ) měly zásadní vliv na jejich rozhodnutí vyvinout tabulku jako primární datovou strukturu Lua.

Lua sémantika byla postupem času stále více ovlivňována schématem, zejména se zavedením anonymních funkcí a plným lexikálním rozsahem . V nových verzích Lua bylo přidáno několik funkcí.

Verze Lua před verzí 5.0 byly vydány na základě licence podobné licenci BSD . Od verze 5.0 a dále je Lua licencován pod licencí MIT . Obě jsou povolnými licencemi svobodného softwaru a jsou téměř totožné.

Funkce

Lua je běžně popisován jako jazyk „ více paradigmat “, který poskytuje malou sadu obecných funkcí, které lze rozšířit tak, aby vyhovovaly různým typům problémů. Lua neobsahuje explicitní podporu dědičnosti , ale umožňuje ji implementovat pomocí metatables . Podobně Lua umožňuje programátorům implementovat jmenné prostory , třídy a další související funkce pomocí implementace jedné tabulky; prvotřídní funkce umožňují využití mnoha technik z funkčního programování ; a plné lexikální rozsahy umožňují skrývání jemnozrnných informací za účelem prosazení zásady nejmenších oprávnění .

Lua se obecně snaží poskytovat jednoduché, flexibilní metafunkce, které lze podle potřeby rozšiřovat, místo aby dodával sadu funkcí specifickou pro jedno programovací paradigma. Výsledkem je, že základní jazyk je lehký - úplný tlumočník referencí je kompilován pouze asi 247  kB - a snadno se přizpůsobuje široké škále aplikací.

Dynamicky napsaný jazyk určena k použití jako jazyk rozšíření nebo skriptovacím jazykem , Lua je dostatečně kompaktní, aby se vešly na různých hostitelských platforem. Podporuje pouze malý počet atomových datových struktur, jako jsou booleovské hodnoty, čísla ( ve výchozím nastavení s plovoucí desetinnou čárkou s dvojitou přesností a 64bitová celá čísla ) a řetězce . Typické datové struktury, jako jsou pole , sady , seznamy a záznamy, lze reprezentovat pomocí jediné nativní datové struktury Lua, tabulky, což je v podstatě heterogenní asociativní pole .

Lua implementuje malou sadu pokročilých funkcí, jako jsou prvotřídní funkce , sběr odpadků , zavírání , správné volání ocasu , nátlak (automatický převod mezi hodnotami řetězců a čísel za běhu), coroutines (kooperativní multitasking) a dynamické načítání modulů .

Syntax

Klasické „Hello, World!“ program lze napsat následovně:

print("Hello, World!")

nebo jako:

print 'Hello, World!'

Komentář v Lua začíná s dvojitou pomlčkou a běží až do konce řádku, podobně jako Ada , Eiffel , Haskell , SQL a VHDL . Víceřádkové řetězce a komentáře jsou ozdobeny dvojitými hranatými závorkami.

Faktorial funkce je implementována jako funkce v tomto příkladu:

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

Řídicí tok

Lua má čtyři typy smyček : whilesmyčku , repeatsmyčku (podobnou do whilesmyčce ), numerickou forsmyčku a obecnou forsmyčku.

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

Obecná forsmyčka:

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

bude iterovat po tabulce _Gpomocí standardní funkce iterátoru pairs, dokud se nevrátí nil.

Smyčky lze také vnořit (vložit do jiné smyčky).

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

Funkce

Luaovo zacházení s funkcemi jako hodnotami první třídy ukazuje následující příklad, kde je upraveno chování tiskové funkce:

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

Jakákoli budoucí volání na printbudou nyní směrována přes novou funkci a kvůli Luovu lexikálnímu rozsahu bude stará funkce tisku přístupná pouze novým, upraveným tiskem.

Lua také podporuje uzavírání , jak je ukázáno níže:

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

Při xkaždém addtovolání se vytvoří nové uzavření proměnné , takže každá nová vrácená anonymní funkce bude mít vždy přístup ke svému vlastnímu xparametru. Uzavření je řízeno Luiným popelářem, jako každý jiný objekt.

Tabulky

Tabulky jsou nejdůležitější datové struktury (a podle návrhu jediný vestavěný složený datový typ ) v Lua a jsou základem všech typů vytvořených uživatelem. Jsou to asociativní pole s přidáním automatického numerického klíče a speciální syntaxe.

Tabulka je kolekce párů klíčů a dat, kde na data odkazují klíče; jinými slovy, je to hašované heterogenní asociativní pole.

Tabulky jsou vytvářeny pomocí {}syntaxe konstruktoru.

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

Tabulky se vždy předávají podle odkazu (viz Volání sdílením ).

Klíčem (indexem) může být libovolná hodnota kromě nila NaN , včetně funkcí.

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.

Tabulka se často používá jako struktura (nebo záznam ) pomocí řetězců jako klíčů. Protože je takové použití velmi běžné, Lua nabízí speciální syntaxi pro přístup k takovým polím.

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.

Pomocí tabulky k ukládání souvisejících funkcí může fungovat jako obor názvů.

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

Tabulkám je automaticky přiřazen číselný klíč, což umožňuje jejich použití jako datového typu pole . První automatický index je 1 místo 0, jak je tomu v mnoha jiných programovacích jazycích (ačkoli je povolen explicitní index 0).

Číselný klíč 1se liší od klíče řetězce "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.

Délka tabulky tje definována jako libovolný celočíselný index n, který t[n]není nila t[n+1]je nil; navíc, pokud t[1]je nil, nmůže být nula. Pro běžné pole s nenulovými hodnotami od 1 do daného nje jeho délka přesně to n, index jeho poslední hodnoty. Pokud má pole „díry“ (tj. Nulové hodnoty mezi jinými hodnotami, které nemají nenulové hodnoty), pak #tmůže být kterýkoli z indexů, které přímo předcházejí nilhodnotě (to znamená, že může považovat jakoukoli takovou nulovou hodnotu za konec pole ).

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

Tabulka může být řada objektů.

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

Použití hash mapy k emulaci pole je obvykle pomalejší než použití skutečného pole; tabulky Lua jsou však optimalizovány pro použití jako pole, aby se tomuto problému předešlo.

Metatables

Rozšiřitelná sémantika je klíčovou vlastností Lua a metatabilní koncept umožňuje výkonné přizpůsobení tabulek. Následující příklad ukazuje "nekonečnou" tabulku. Pro všechny n, fibs[n]n-tý počet Fibonacci pomocí dynamického programování a 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
})

Objektově orientované programování

Přestože Lua nemá integrovaný koncept tříd , objektově orientované programování lze emulovat pomocí funkcí a tabulek. Objekt je vytvořen vložením metod a polí do tabulky. Dědičnost (jednoduchou i vícenásobnou) lze implementovat pomocí metatables , přičemž neexistující metody a pole lze delegovat na nadřazený objekt.

Neexistuje žádný takový koncept jako „třída“ s těmito technikami; spíše se používají prototypy , podobné Self nebo JavaScript . Nové objekty se vytvářejí buď tovární metodou (která vytváří nové objekty od nuly), nebo klonováním existujícího objektu.

Vytvoření základního vektorového objektu:

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)

Zde setmetatableříká Lua, aby hledal prvek v Vectortabulce, pokud v tabulce není přítomen vec. , což je ekvivalent , nejprve hledá v tabulce prvek. Tabulka nemá prvek, ale jeho metatable deleguje na stole za prvek, když není nalezen v tabulce. vec.magnitudevec["magnitude"]vecmagnitudevecmagnitudeVectormagnitudevec

Lua poskytuje nějaký syntaktický cukr, který usnadňuje orientaci objektu. K deklaraci členských funkcí uvnitř prototypové tabulky lze použít , což je ekvivalentní . Volání metod třídy také využívá dvojtečku: je ekvivalentní . function table:func(args)function table.func(self, args)object:func(args)object.func(object, args)

Na mysli je zde odpovídající třída se :syntaktickým cukrem:

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)

Dědictví

Lua podporuje použití metatables k získání dědičnosti třídy Lua. V tomto případě povolujeme vektory vynásobit jejich hodnoty konstantou v odvozené třídě.

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 také podporuje vícenásobnou dědičnost ; __indexmůže to být funkce nebo tabulka. Lze také provést přetížení operátora ; Metata Lua mohou mít prvky jako __add, __subatd.

Implementace

Programy Lua nejsou interpretovány přímo z textového souboru Lua, ale jsou kompilovány do bytecode, který je poté spuštěn na virtuálním počítači Lua . Proces kompilace je pro uživatele obvykle neviditelný a je prováděn za běhu , zvláště když je použit kompilátor JIT , ale lze jej provést offline, aby se zvýšil výkon načítání nebo zmenšila paměťová stopa hostitelského prostředí vynecháním kompilátor. Lua bytecode lze také vytvořit a spustit z Lua pomocí dumpfunkce z knihovny řetězců a load/loadstring/loadfilefunkcí. Lua verze 5.3.4 je implementována v přibližně 24 000 řádcích kódu C.

Jako většina CPU a na rozdíl od většiny virtuálních strojů (které jsou založeny na stacku ), Lua VM je založený na registrech , a proto se více podobá skutečnému hardwarovému designu. Architektura registru zabraňuje nadměrnému kopírování hodnot a snižuje celkový počet instrukcí na funkci. Virtuální stroj Lua 5 je jedním z prvních čistých virtuálních počítačů založených na registrech, které mají široké využití. Parrot a Android je Dalvik jsou dva další známý registr založený na VM. Virtuální počítač PCScheme byl také založený na registrech.

Tento příklad je výpis bytecode výše definované faktoriální funkce (jak ukazuje luackompilátor 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

C API

Lua je zamýšleno pro vložení do jiných aplikací a poskytuje k tomu C API . API je rozděleno na dvě části: jádro Lua a pomocnou knihovnu Lua. Lua API design eliminuje potřebu manuální správy referencí v C kódu, na rozdíl od API Pythonu . API, stejně jako jazyk, je minimalistické. Pokročilé funkce poskytuje pomocná knihovna, která se skládá převážně z maker preprocesoru, které pomáhají se složitými operacemi s tabulkami.

Lua C API je založeno na zásobníku . Lua poskytuje funkce pro tlačení a vysouvání nejjednodušších datových typů C (celá čísla, plováky atd.) Do a ze zásobníku, stejně jako funkce pro manipulaci s tabulkami přes zásobník. Lua stack se poněkud liší od tradičního stacku; zásobník lze například přímo indexovat. Záporné indexy označují posuny od horní části zásobníku. Například −1 je nejvyšší (naposledy vložená hodnota), zatímco kladné indexy označují odsazení zespodu (nejstarší hodnota). Seskupování dat mezi funkcemi C a Lua se také provádí pomocí zásobníku. Chcete -li zavolat funkci Lua, argumenty se vloží do zásobníku a poté lua_callse použije k volání skutečné funkce. Při psaní funkce C, která má být volána přímo z Lua, se argumenty čtou ze zásobníku.

Zde je příklad volání funkce Lua z 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;
}

Spuštěním tohoto příkladu získáte:

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

C API také poskytuje několik speciálních tabulek, umístěných na různých „pseudoindexech“ v zásobníku Lua. At LUA_GLOBALSINDEXpřed Lua 5.2 je tabulka globals, _Gzevnitř Lua, což je hlavní namespace . Existuje také registr, do LUA_REGISTRYINDEXkterého mohou programy C ukládat hodnoty Lua pro pozdější načtení.

Pomocí Lua API je možné zapisovat rozšiřující moduly. Rozšiřující moduly jsou sdílené objekty, které lze použít k rozšíření funkcí překladače poskytováním nativních zařízení skriptům Lua. Ze strany Lua se takový modul jeví jako tabulka jmenného prostoru, která obsahuje své funkce a proměnné. Skripty Lua mohou načítat rozšiřující moduly pomocí require, stejně jako moduly napsané v samotném Lua. Rostoucí sbírka modulů známých jako skály je k dispozici prostřednictvím systému pro správu balíčků s názvem LuaRocks , v duchu vajec CPAN , RubyGems a Python . Předepsané vazby Lua existují pro většinu populárních programovacích jazyků, včetně jiných skriptovacích jazyků. Pro C ++ existuje řada přístupů založených na šablonách a některé generátory automatických vazeb.

Aplikace

V Video vývoj her , Lua je široce používán jako skriptovací jazyk u programátorů , a to především díky své jednoduchosti vnímané vložit, rychlé provedení, a krátkou zaučení . Jednou z pozoruhodných herních platforem je Roblox, ve kterém se pro skriptování rychlého vývoje her používá jejich vlastní dialekt Luau. Dalším je World of Warcraft, který také používá zmenšenou verzi Lua.

V roce 2003 průzkum veřejného mínění provedený GameDev.net ukázal, že Lua je nejpopulárnějším skriptovacím jazykem pro programování her. Dne 12. ledna 2012 byl Lua vyhlášen vítězem Front Line Award 2011 z časopisu Game Developer v kategorii Programming Tools.

Velký počet non-herních aplikací použít také Lua pro rozšiřitelnost, jako LuaTEX , implementací TeXu typu nastavení jazyka, REDIS , v databázi klíč-hodnota , Neovim , textového editoru a Nginx , s webovým serverem .

Díky rozšíření Scribunto je Lua k dispozici jako skriptovací jazyk na straně serveru v softwaru MediaWiki, který pohání Wikipedii a další wiki. Mezi jeho použití patří umožnění integrace dat z Wikidata do článků a napájení automatizovaného systému taxoboxu .

Odvozené jazyky

Jazyky, které se kompilují do Lua

  • MoonScript je dynamický , mezery -sensitive skriptovací jazyk inspirovaný CoffeeScript , který je sestaven na Lua. To znamená, že místo použití doa end(nebo {a }) k oddělení částí kódu používá konce řádků a styl odsazení . Pozoruhodný použití MoonScript je videohra rozdělení webové stránky Itch.io .
  • Haxe podporuje kompilaci na cíl Lua, podporuje Lua 5.1-5.3 a LuaJIT 2.0 a 2.1.
  • Fenykl, dialekt Lisp, který cílí na Lua.
  • Urn, dialekt Lispu, který je postaven na Lua.
  • Amulet, funkční jazyk podobný ML , jehož překladač produkuje soubory Lua.

Nářečí

  • LuaJIT (viz níže), jazyk Lua 5.1 s podporou JIT s goto(od Lua 5.2) a C FFI .
  • Luau od Roblox , jazyk Lua 5.1 s postupným zadáváním a ergonomickými doplňky.
  • Ravi, jazyk Lua 5.3 s podporou JIT s volitelným statickým zadáváním. JIT se řídí informacemi o typu.
  • Shine, vidlice LuaJIT s mnoha rozšířeními, včetně modulového systému a makrosystému.

Komunita uživatelů Lua navíc poskytuje několik výkonových záplat nad implementací referenčního C.

LuaJIT

LuaJIT
Vývojáři Mike Pall
Stabilní uvolnění
2.0.5 / 1. května 2017 ; Před 4 lety ( 01.05.2017 )
Úložiště repo. nebo .cz /w /luajit-2 .0 .git
Napsáno C , Lua
Operační systém viz seznam
Typ Právě včas kompilátor
Licence Licence MIT
webová stránka luajit .org

LuaJIT je kompilátor Lua právě včas . Byl použit pro vkládání nebo pro obecné účely. Ve verzi 2.0 LuaJIT byl projekt přepsán za účelem lepší optimalizace výkonu.

Dějiny

Projekt LuaJIT zahájil v roce 2005 vývojář Mike Pall, vydaný pod licencí MIT open source. Nejnovější verze 2.0.5 vychází v roce 2017. Od té doby projekt aktuálně neudržují jiní vývojáři než přispěvatelé.

Instalace

LuaJIT je open source a projekt musí být zkompilován, aby mohl být použit. Úložiště bude nutné stáhnout pomocí Gitu nebo jinými způsoby stahování úložišť. Poté je kompilován s jakýmkoli kompilátorem C, obvykle s GNU make , ale jsou k dispozici další možnosti. Aby byl kompilátor LuaJIT použit, musí být spustitelný soubor LuaJIT a Lua 5.1 DLL ve stejném adresáři.

Existuje průvodce používáním kompilátoru LuaJIT, který obsahuje možnosti příkazového řádku.

Výkon

Ve srovnání s jinými běhovými časy Lua je LuaJIT často nejrychlejším kompilátorem Lua.

Platformy

LuaJIT lze použít v:

Lze jej kompilovat pomocí GCC , Clang nebo MSVC .

Příklady

Knihovnu FFi lze použít k volání funkcí C a použití datových struktur C z kódu Lua. Od LuaJIT je k dispozici průvodce o používání této knihovny. Jako takové existuje několik vazeb LuaJIT na knihovny C, které používají knihovnu FFI. Tento příklad by zavolal funkci C, printf z čistého kódu Lua a vydá Hello world! .

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

Kompilátor LuaJIT také přidal některá rozšíření do Lua's C API. Tento příklad napsaný v jazyce C ++ by byl použit pro účely ladění .

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

Viz také

Poznámky

Reference

Další čtení

externí odkazy