Lua (programozási nyelv)
A Lua (portugálul: hold) egy nyílt forráskódú, beágyazható szkriptnyelv, amelyet 1993-ban fejlesztettek ki a brazíliai Katolikus Teológiai Egyetemen. Készítői fontosnak tartották az együttműködést a C nyelvű programokkal, programkönyvtárakkal. Platformfüggetlen; a programok futás előtt bájtkódra fordulnak. Bár önállóan is használható, de inkább beágyazott nyelvként tartják számon, ahogy a Tcl nyelvet is. Más script nyelvekhez képest nagy sebessége, bővíthetősége és 120 kB-os mérete népszerűvé tette a fejlesztők között. Az értelmező egy C könyvtárból érhető el, ami API-ként szolgál, ha C programból hívják. Ez lehetővé teszi a két nyelv kevert használatát: a Lua is hívhat C függvényeket, és fordítva, a C is meghívhat Lua függvényeket. ANSI C-ben készült, és az imperatív és a funkcionális paradigmákat támogatja; az objektumorientáltsághoz nem nyújt nyelvi eszközöket, mégis lehet objektumokat készíteni a tábla adattípus felhasználásával. SzintaxisaNyelvi elemekAz azonosítók betűkből, számokból, aláhúzásjelekből építkezhetnek, ahol az első jel nem lehet szám. A betűkészlet a helyi beállításoktól függ. Egy jel betű volta ellenőrizhető az A számok tartalmazhatnak törtrészt és decimális exponenst. A tizenhatos számrendszert a A Lua forráskódban a kis- és nagybetűk nem minősülnek azonosnak. TípusokA Lua beépített típusai:
Egy nil típusú változónak egyetlen lehetséges értéke van, a Egy logikai változónak két lehetséges értéke van: A számok alapértelmezetten dupla pontosságú lebegőpontos számok. Nincs külön egész típus. A számokon végezhető műveletek operátorai: A függvények tárolhatók változókban, és átadhatók paraméterként. A C-ben írt programkönyvtárak felhasználásának elősegítésére a C függvények is kezelhetők így. Függvényhíváskor akkor is ki kell tenni a zárójelet, ha nem adunk meg paramétereket. A Javaban megszokott objektum.metódus(objektum, paraméterek)
de létezik egy szintaktikus cukor ennek a lerövidítésére: objektum:metódus(paraméterek)
A thread a többszálú programozás programszálainak típusa. A rövid stringek megadhatók egyszeres vagy kétszeres idézőjelek között. Hosszabb stringek megadhatók Az escape sorozatok ugyanazok, mint C-ben. A userdata C-ben megvalósított adattípusokat tárol. Módosítani, rajta műveleteket végrehajtani csak C függvényekkel lehet, a Lua csak értékadást és egyenlőségvizsgálatot biztosít hozzá. TáblákA table a Lua egyetlen összetett típusa, asszociatív tömb. A kulcsok lehetnek számok (ajánlottan csak egészek), stringek, másik táblák vagy függvények. A táblák automatikus indexelése a modernebb nyelvekhez hasonlóan 1-től kezdődik, mivel a 0 index hiánya nem igényel kihasználatlan helyfoglalást. Bejárásuk kétféle módon lehetséges: csak az egész típusú kulcsokat (és a hozzájuk tartozó értékeket) nézzük végig 1-től az első nem létező kulcsig ( Táblák létrehozhatók így: x = {3.14, "ez egy string"}
Ilyenkor az egyes értékeket sorban az 1, 2, 3, ... kulcsokhoz rendeli. String kulcsokat így lehet használni: x =
{
nev = "Kovács János",
kor = 46,
fizetes = {ertek = 10000, penznem = "Ft"}
}
A táblák referencia szerint adódnak át: a_table = {x = 10} -- Új tábla, egy kulcs-érték pár: "x" kulcs a 10-es számhoz.
print(a_table["x"]) -- A string kulcshoz tartozó érték kiíratása; itt 10.
b_table = a_table
b_table["x"] = 20 -- Az "x"-hez tartozó érték megváltoztatása 20-ra.
print(b_table["x"]) -- Az új érték kiíratása: 20.
print(a_table["x"]) -- ez is 20-at ír, mert az a_table és a b_table ugyanarra a táblára hivatkozik.
Kulcsok, értékek beszúrása, eltávolítása: myTable = {"a", "b"}
table.insert(myTable, "c")
print(unpack(myTable)) -- eredménye: a b c
table.remove(myTable, 2)
print(unpack(myTable)) -- eredménye: a c
MegjegyzésekEgysoros megjegyzés: -- Megjegyzés
Többsoros megjegyzés: --[[Ide egy
többsoros
megjegyzés
került]]
VáltozókA változók nevükkel hivatkozhatók. A táblában levő értékek hivatkozhatók a tömböknél megszokott módon, pl. A változók láthatóság szempontjából háromfélék lehetnek: globális, lokális, és táblamezők. A változók deklarációjuktól kezdve egészen a legkisebb befoglaló blokk végéig láthatók. Egy változó lokálissá tehető, ha ElágazásA Lua csak a kétirányú elágazást ismeri, a többágú elágazás valójában csak szintaktikus cukor: if kifejezes then
blokk
else
blokk
end
if kifejezes then
blokk
elseif kifejezes then
blokk
elseif kifejezes then
blokk
...
else
blokk
end
CiklusokElöltesztelő ciklusAddig hajtja végre a ciklusmagot, amíg a feltétel igaz. while feltétel do
-- Utasítások
end
Hátultesztelő ciklusrepeat
-- Utasítások
until feltétel
A ciklusmagot egyszer mindenképpen végrehajtja, majd utána addig hajtja végre a ciklust, amíg a feltétel hamis (igazzá nem válik). Az until ciklus valójában csak szintaktikus cukor, nem hoz létre új láthatósági tartományt. Számláló ciklusfor index = start, finish, delta do
-- Utasítások
end
Az Ha for index = start, finish do
-- Utasítások
end
Iteráló ciklusA Luában kétféle iteráló ciklus van. Az for _, value in ipairs(lista) do
-- Utasítások
end
A for key, value in pairs(lista) do
-- Utasítások
end
FüggvényekA Luában a függvények átadhatók paraméterként, sőt, visszatérési értékek is lehetnek, ahogy a következő példa mutatja: do
local oldprint = print -- a jelenlegi print függvény eltárolása oldprint néven
function print(s) -- a print függvény újradefiniálása, itt lehet a szokásos print függvényt használni
if s == "foo" then
oldprint("bar")
else
oldprint(s)
end
end
end
A régi print függvény csak az új print függvényen keresztül érhető el. A Lua a lezártakat is támogatja: function hozzaad (x)
-- visszatér egy új funkcióval, ami hozzáadja x-et a paraméterhez
return function(y)
--[[Amikor az x változóra hivatkozunk, ami kívül van az aktuális láthatósági tartományon
és az élettartama hosszabb, mint ennek a névtelen függvénynek,
akkor a Lua egy lezártat (closure) hoz létre]]
return x + y
end
end
negyplusz = hozzaad(4)
print(negyplusz(3)) --> kiirja a 7-et
Valahányszor meghívódik a MetatáblákA metatáblák új lehetőségeket nyújtanak a táblák felhasználására. A következő példa egy végtelen táblát mutat be. Minden n-re fibs = { 1, 1 } -- fibs[1] fibs[2] kezdőértékei.
setmetatable(fibs, {
__index = function(name, n) -- Ezt hívja, ha még nincs fibs[n].
name[n] = name[n - 1] + name[n - 2] -- Kiszámolja és megjegyzi fibs[n]-et.
return name[n]
end
})
Egy másik példa: a __call metametódus az objektumorientáltság érzetét adja: newPerson = {} -- Új tábla 'newPerson' néven.
setmetatable(newPerson, {
__call = function(table,name,age) -- A newPerson táblát functable-lé teszi.
local person = {Name = name, Age = age} -- Lokális változó a később létrehozandó person attributumaival
return person -- A person tábla visszaadása, a person tábla változóinak beállítása
end
})
Bill = newPerson("Bill Raizer", 21) -- Új Person-t hoz létre
print(Bill.Name, Bill.Age) -- A name és az age attributumok kiíratása.
StruktúrákBár a Luában nincs adatszerkezet rekordok létrehozására, mint például C-ben a pont = { x = 10, y = 20 } -- Új tábla
print(pont["x"]) -- Az "x" koordináta kiíratása, itt 10
print(pont.x) -- Ugyanaz, mint az előző sorban, csak másként.
NévterekA táblák összetartozó függvényeket is tárolhatnak, ezzel átvehetik a névterek szerepét, objektumorientáltság érzetét adva: Point = {} -- Új névtér létrehozása
Point.new = function (x, y) -- Konstruktor
return {x = x, y = y}
end
Point.set_x = function (self, x)
self.x = x
end
Point.get_x = function (self)
return self.x
end
TömbökA Lua táblák tömbökként is használhatók: array = { "a", "b", "c", "d" } -- Az indexek automatikusan számozódnak.
print(array[2]) -- A "b"-t írja ki. A Lua 1-től kezdi a tömbelemek indexelését.
print(#array) -- 4, a tábla hossza. A # operátor adja meg a táblák és a stringek hosszát.
array[0] = "z" -- A 0 index használata.
print(#array) -- Most is 4, a nulladik index nem számítódik bele a hosszba.
Objektumok tömbjeként: function newPoint(x, y) -- A "Point" objektum konstruktora
return { x = x, y = y } -- Új objektum létrehozása és visszaadása
end
array = { newPoint(10, 20), newPoint(30, 40), newPoint(50, 60) } -- Pontok tömbje
print(array[2].y) -- 40-et ír ki
A Lua táblák tömbrésszel és assziociatív tömbrésszel vannak implementálva. Korábban az egészet asszociatív tömbbel valósították meg, de ez az ábrázolás gyorsabb.[2] Felhasználói modulokA Lua lehetővé teszi új modulok létrehozását. A modulok kezelésére rendelkezésre áll a Luarocks modulkezelő. Néhány modul a leggyakoribbak közül:
Hello, World!A klasszikus Hello World! program Lua nyelven: print("Hello World!")
A program futtatásaA virtuális gép nem közvetlenül a Lua szkriptet hajtja végre, hanem futás közben bájtkódra fordítja, és ez fut. A szkriptek futtatás nélkül is fordíthatók. Maga a fordítás átlátható. A Lua virtuális gép regiszteres, ezért a legtöbb virtuális gépnél jobban hasonlít a hardver felépítéséhez. Ez csökkenti az értékek átmásolásának és a függvényenkénti utasítások számát. A Lua 5 az egyik legrégibb regiszteres virtuális gép.[3] Az Android Dalvikja és a több nyelvre, köztük Perlre tervezett Parrot is ilyen. Így fordítja a luac 5.1 virtuális gép a faktoriális függvényt:[4] function <factorial.lua:1,6> (10 instructions, 40 bytes at 003D5818) 1 param, 3 slots, 0 upvalues, 1 local, 3 constants, 0 functions 1 [2] EQ 0 0 -1 ; – 0 2 [2] JMP 2 ; to 5 3 [3] LOADK 1 -2 ; 1 4 [3] RETURN 1 2 5 [5] GETGLOBAL 1 -3 ; factorial 6 [5] SUB 2 0 -2 ; – 1 7 [5] CALL 1 2 2 8 [5] MUL 1 0 1 9 [5] RETURN 1 2 10 [6] RETURN 0 1 C APIA Luát alkalmazásokba ágyazott nyelvnek fejlesztették, ezért könnyen használható, robusztus C API-val látták el. Az API két részből áll: ezek a Lua core és a Lua auxiliary library.[5] Kiküszöböli a C kézi hivatkozáskezelését. Az API a nyelvhez hasonlóan minimalisztikus; a funkcionalitás bővítéséért az auxiliary library felelős, ami preprocesszor makrókkal egyszerűsíti a táblakezelést. VeremA Lua C API verem alapú. A veremműveleteket Lua függvények valósítják meg, továbbá léteznek táblakezelő függvények is, amik a veremből is hívhatók. Ez a verem indexelhető is. A Python tömbökhöz hasonlóan negatív indexek is használhatók; ezek a verem tetejétől (-1 a legfelső elem), a pozitív indexek a verem aljától számítódnak. A C és a Lua közötti kommunikációt szintén a verem valósítja meg. A Lua függvénynek átadott argumentumok a verembe kerülnek, és az aktuális függvény PéldaLua függvény hívása C-ből: #include <stdio.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main()
{
lua_State *L = luaL_newstate();
if (luaL_dostring(L, "function foo (x,y) return x+y end")) exit(1);
lua_getglobal(L, "foo");
lua_pushinteger(L, 5);
lua_pushinteger(L, 3);
lua_call(L, 2, 1);
printf("Result: %d\n", lua_tointeger(L, -1));
return 0;
}
Fordítás és futtatás: $ gcc -o hello -llua hello.c $ ./hello Result: 8 Speciális táblákA C API speciális táblákat is elérhetővé tesz, amik pszeudoindexekkel hivatkozhatók a Lua veremből. A Kiterjesztés és kötésKiterjesztő modulok is készíthetők a Lua API használatával. Ezek a könyvtárak kiterjesztik az értelmező funkcionalitását. A Lua szempontjából ezek névterek, vagyis táblák a maguk változóival és függvényeivel. Ezek a modulok a A LuaRocks csomagkezelő rendszerből egyre több modul érhető el,[6] a CPANhoz, a RubyGemshez és a Python Eggshez hasonlóan. További források a LuaForge és a lua-users.org wiki Lua Addonsa.[7] Vannak csomagok a grafikus felülethez, a Perl/POSIX szabályos kifejezésekhez, a titkosításhoz, a fájltömörítéshez és még sok máshoz. A legtöbb népszerű nyelvhez vannak Lua kötések, például más szkript nyelvekhez.[8] A C++ megközelítés sablon alapú, és automatikus generátorokat használ. AlkalmazásaiManapság a videójátékok nagy része rendelkezik Lua scriptelési lehetőséggel, ezen kívüli alkalmazások:
Jegyzetek
Irodalom
További információk |
Portal di Ensiklopedia Dunia