Lua

Uses your system voice; voice and rate in settings.

Q3264588Snapshot

≈ 12 min read

Names in other languages

  • astRíu Lua
  • cebLua
  • DeutschLua
  • EnglishLua
  • FrançaisLua
  • NederlandsLua
  • SvenskaLua

Article bodies are English and are not machine-translated. A name in another language is not a translation of the article.

Lua is a lightweight, high-level, multi-paradigm programming language designed mainly for embedded use in applications. Lua is cross-platform software, since the interpreter of compiled bytecode is written in ANSI C, and Lua has a relatively simple C application programming interface (API) to embed it into applications. Lua originated in 1993 as a language for extending software applications to meet the increasing demand for customization at the time. It provided the basic facilities of most procedural programming languages, but more complicated or domain-specific features were not included; rather, it included mechanisms for extending the language, allowing programmers to implement such features. As Lua was intended to be a general embeddable extension language, the designers of Lua focused on improving its speed, portability, extensibility and ease-of-use in development.

Lua is a lightweight, high-level, multi-paradigm programming language designed mainly for embedded use in applications. Lua is cross-platform software, since the interpreter of compiled bytecode is written in ANSI C, and Lua has a relatively simple C application programming interface (API) to embed it into applications. Lua originated in 1993 as a language for extending software applications to meet the increasing demand for customization at the time. It provided the basic facilities of most procedural programming languages, but more complicated or domain-specific features were not included; rather, it included mechanisms for extending the language, allowing programmers to implement such features. As Lua was intended to be a general embeddable extension language, the designers of Lua focused on improving its speed, portability, extensibility and ease-of-use in development. print("Hello, World!") print "Hello, World!" The declaration of a variable, without a value. local variable The declaration of a variable with a value of 1000 (one thousand) local students = 1000 A comment in Lua starts with a double-hyphen and runs to the end of the line, similar to Ada, Eiffel, Haskell, SQL and VHDL. Multi-line strings and comments are marked with double square brackets. -- Single line comment -- Multi-line comment The factorial function is implemented in this example: function factorial(n) local x = 1 for i = 2, n do x = x * i end return x end if condition then --statement body end An example of an if statement if x ~= 10 then print(x) end The else keyword may be added with an accompanying statement block to control execution when the if condition evaluates to false : if condition then --statement body else --statement body end An example of an if else statement if x == 10 then print(10) else print(x) end Execution may also be controlled according to multiple conditions using the elseif then keywords: if condition then --statement body elseif condition then --statement body else -- optional --optional default statement body end An example of an if elseif else statement if x == y then print("x = y") elseif x == z then print("x = z") else -- optional print("x does not equal any other variable") end Lua has four types of conditional loops: the while loop, the repeat loop (similar to a do while loop), the numeric for loop and the generic for loop. --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 This generic for loop would iterate over the table _G using the standard iterator function pairs , until it returns nil : for key, value in pairs(_G) do print(key, value) end Loops can also be nested (put inside of other loops). local grid = { { 11, 12, 13 }, { 21, 22, 23 }, { 31, 32, 33 } } for y, row in pairs(grid) do for x, value in pairs(row) do print(x, y, value) end end 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 Any future calls to print will now be routed through the new function, and because of Lua's lexical scoping, the old print function will only be accessible by the new, modified print. Lua also supports closures, as demonstrated below: 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. A new closure for the variable x is created every time addto is called, so that each new anonymous function returned will always access its own x parameter. The closure is managed by Lua's garbage collector, just like any other object. a_table = {} -- Creates a new, empty table Tables are always passed by reference (see Call by sharing). A key (index) can be any value except nil and NaN, including functions. 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. A table is often used as structure (or record) by using strings as keys. Because such use is very common, Lua features a special syntax for accessing such fields. 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. By using a table to store related functions, it can act as a 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 Tables are automatically assigned a numerical key, enabling them to be used as an array data type. The first automatic index is 1 rather than 0 as it is for many other programming languages (though an explicit index of 0 is allowed). A numeric key 1 is distinct from a string key "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. The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil ; moreover, if t[1] is nil , n can be zero. For a regular array, with non-nil values from 1 to a given n , its length is exactly that n , the index of its last value. If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array). ExampleTable = { {1, 2, 3, 4}, {5, 6, 7, 8} } print(ExampleTable[1][3]) -- Prints "3" print(ExampleTable[2][4]) -- Prints "8" A table can be an array of objects. 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 Using a hash map to emulate an array is normally slower than using an actual array; however, Lua tables are optimized for use as arrays to help avoid this issue. 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 memoize fibs[n]. return values[n] end }) 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) Here, tells Lua to look for an element in the table if it is not present in the table. , which is equivalent to , first looks in the table for the element. The table does not have a element, but its metatable delegates to the table for the element when it's not found in the table. Lua provides some syntactic sugar to facilitate object orientation. To declare member functions inside a prototype table, one can use , which is equivalent to . Calling class methods also makes use of the colon: is equivalent to . That in mind, here is a corresponding class with syntactic sugar: 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) 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 pseudo 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) It is also possible to implement multiple inheritance; can either be a function or a table. Operator overloading can also be done; Lua metatables can have elements such as , and so on. include include // Lua main library (lua_*) include // 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; } Running this example gives: $ cc -o example example.c -llua $ ./example Result: 8 The C API also provides some special tables, located at various "pseudo-indices" in the Lua stack. At LUA_GLOBALSINDEX prior to Lua 5.2 is the globals table, _G from within Lua, which is the main namespace. There is also a registry located at LUA_REGISTRYINDEX where C programs can store Lua values for later retrieval. ===Languages that compile to Lua=== MoonScript is a dynamic, whitespace-sensitive scripting language inspired by CoffeeScript, which is compiled into Lua. This means that instead of using do and end (or { and } ) to delimit sections of code it uses line breaks and indentation style. A notable use of MoonScript is the video game distribution website Itch.io. Haxe supports compiling to some Lua targets, including Lua 5.1–5.3 and LuaJIT 2.0 and 2.1. Fennel, a Lisp dialect that targets Lua. Urn, a Lisp dialect built on Lua. Amulet, an ML-like functional programming language, which compiler emits Lua files. LunarML, Standard ML compiler that produces Lua/JavaScript

Text derived from https://en.wikipedia.org/w/index.php?oldid=1374477766 under CC BY-SA 4.0; modifications have been made.