Lua

Lua（icon，詞源葡萄牙語「月亮」）是一個簡潔、輕量、可擴展的腳本語言。Lua有著相對簡單的C語言API而很容易嵌入應用中。很多應用程式使用Lua作為自己的嵌入式腳本語言，以此來實現可配置性、可擴展性。

## 歷史

Lua是在1993年由羅伯托·耶魯薩林斯希、Luiz Henrique de Figueiredo和Waldemar Celes創建的，他們當時是巴西的里約熱內盧天主教大學的電腦圖形技術組（Tecgraf）成員。Lua的先驅是數據描述/配置語言「SOL」（簡單對象語言）和「DEL」（數據錄入語言）。他們於1992年–1993年在Tecgraf獨立開發了需要增加靈活性的兩個不同項目（都是用於工程應用的交互式圖形程序）。在SOL和DEL中缺乏很多控制流結構，需要向它們增加完全的編程能力。

在《The Evolution of Lua》中，這門語言的作者寫道：

Lua主要受到了下列前輩語言的影響：

- Modula-2：從中引入了大部份控制結構語法 (程式語言)，`if`、`while`、`repeat`/`until`。
- CLU：多賦值和從函數調用的多個返回值，這是對引用參數或顯式指針的更簡單的替代。
- C++：「允許局部變量只在需要的地方聲明的靈巧想法」。
- SNOBOL和AWK：關聯數組。
- LISP和Scheme：在發表於《Dr. Dobb's Journal》的文章中，Lua的創立者還聲稱，有著單一且無所不在的數據結構機制（列表）的LISP和Scheme，對他們決定將表格開發為Lua的主要數據結構起到了主要影響。Lua的語義久而久之日趨受到Scheme的影響，特別是介入了匿名函數和完全的詞法作用域。

Lua在版本5.0之前在類似BSD許可證之下發行。自從版本5.0以來，Lua採用了MIT許可證。

## 特性

Lua是一種輕量語言，它的官方版本只包括一個精簡的核心和最基本的庫。這使得Lua體積小、啟動速度快。它用ANSI C語言編寫，並以原始碼形式開放，編譯後的完整參考解釋器只有大約247kB，到5.4.3版本，該體積變成283kB（Linux,amd64），依然非常小巧，可以很方便的嵌入別的程式裡。和許多「大而全」的語言不一樣，網路通訊、圖形界面等都沒有預設提供。但是Lua可以很容易地被擴展：由宿主語言（通常是C或C++）提供這些功能，Lua可以使用它們，就像是本來就內置的功能一樣。事實上，現在已經有很多成熟的擴展模塊可供選用。

Lua是一個動態類型語言，支援增量式垃圾收集策略。有內建的，與作業系統無關的協作式多線程支援。Lua原生支援的數據類型很少，只提供了數值（默認是雙精度浮點數，可配置）、布爾量、字串、表格、函數、線程以及使用者自定義數據這幾種。但是其處理表和字串的效率非常之高，加上元表的支援，開發者可以高效的模擬出需要的複雜數據類型（比如集合、陣列等）。

## 語法和語義

Lua是一種多重編程范型的程式設計語言：它只提供了很小的一個特性集合來滿足不同編程范型的需要，而不是為某種特定的編程范型提供繁雜的特性支援。例如，Lua並不提供繼承這個特性，但是你可以用元表格來模擬它。諸如命名空間、類這些概念都沒有在語言基本特性中實現，但是我們可以用表格結構（Lua唯一提供的複雜數據結構）輕易模擬。正是提供了這些基本的元特性，我們可以任意的對語言進行自需的改造。

Lua實現了少量的高級特徵比如頭等函數、垃圾回收、閉包、正當尾調用、類型轉換（於運行時間在字串和數值之間自動轉換）、協程（協作多任務）和動態模塊裝載。

### 詞法

經典的Hello World!程序可以寫為如下：

```lua
print("Hello World!")
```

或者如下：

```lua
print 'Hello World' 
print [[Hello World]]
```

在Lua中注釋可以於雙連字符並行至此行的結束，類似於Ada、Eiffel、Haskell、SQL和VHDL。多行字串和注釋用雙方括號來裝飾。

下例中實現了一個階乘函數：

```lua
local function factorial(nbr) -- 输入参数 nbr 为整数
    local res = 1 -- 将局部结果初始化为 1
    for idx = 2, nbr do -- 从 2 到 nbr 的循环
        res = res * idx
    end
    return res -- 返回 nbr 的阶乘
end
print(factorial(5))
```

```lua
120
```

### 控制流

Lua有一種類型的條件測試：

```lua
if then end
```

它具有可選的

```lua
else
```

和

```lua
elseif then
```

執行控制構造。

通用的

```lua
if then end
```

語句需要三個關鍵字:

```lua
if condition then
	--当 condition 为 true 时执行的语句体
end
```

可以增加

```lua
else
```

關鍵字來控制執行，它隨同著在

```lua
if
```

條件求值為

```lua
false
```

之時執行的語句塊：

```lua
if condition then
	--当 condition 为 true 时执行的语句体
else
	--当上述条件都为 false 时执行的可选默认语句体
end
```

還可以使用

```lua
elseif then
```

關鍵字依據多個條件來控制執行：

```lua
if condition1 then
	-- 当 condition1 为 true 时执行的语句体
elseif condition2 then
	-- 当 condition1 为 false 且 condition2 为 true 时执行的语句体
else -- 可选
	-- 当上述条件都为 false 时执行的可选默认语句体
end
```

Lua有四種類型的循環：

```lua
while
```

循環。

```lua
repeat
```

循環（類似於

```lua
do while
```

循環）、數值

```lua
for
```

循環和通用

```lua
for
```

循環。

while

```lua
condition = true -- 进入 while 循环的条件

while condition do
  -- 在这里修改 condition 为 false，以避免无限循环
end
```

```lua
--[[注意：如果循环无响应，请关闭模块：Example 或关闭浏览器]]--
local idx = 1     -- 初始计数器值
-- 将 condition 变量设为 false 的语句以避免无限循环
while idx <= 5 do -- 当 idx 小于或等于 5 时循环（为避免无限循环）
  print(idx)      -- 在调试控制台输出当前计数器值
  idx = idx + 1   -- 在每次迭代中增加计数器，以确保循环结束
end               -- 循环结束时 idx 的值将为 6。
print("while 循环之外、idx = " .. idx)
```

```lua
1
2
3
4
5
while 循环之外、idx = 6
```

repeat

```lua
condition = false -- 在 repeat 循环中至少循环一次的条件
repeat
  -- 在这里将 condition 修改为 true，以避免无限循环
until condition
```

```lua
local idx = 1     -- 初始计数器值
repeat
  print(idx)      -- 在调试控制台输出当前计数器值
  idx = idx + 1   -- 在每次迭代中增加计数器，以确保循环结束
  -- 将 condition 变量设为 true 的语句以避免无限循环
until idx > 5     -- 循环结束时 idx 的值将为 6。
print("repeat 循环之外、idx = " .. idx)
```

```lua
1
2
3
4
5
repeat 循环之外、idx = 6
```

for

```lua
for idx = first, last, delta do  --delta可以是负数，允许计数增加或减少的循环
  -- 使用 idx 的语句
  -- 例如：print(idx)
end
```

```lua
for idx = 1, 5 do -- for idx = 从, 到
    print(idx)
end
-- 变量 idx 在 for 循环外不可见
```

```lua
1
2
3
4
5
```

通用

```lua
for
```

循環：

```lua
for key, value in pairs(_G) do
  print("键: " .. key .. "、值: " .. tostring(value))
end
```

```lua
键: string、值: table
键: xpcall、值: function
键: package、值: table
键: rawset、值: function
键: _VERSION、值: Lua 5.1
键: error、值: function
键: pcall、值: function
键: os、值: table
键: unpack、值: function
键: math、值: table
键: ipairs、值: function
键: require、值: function
键: rawget、值: function
键: type、值: function
键: setmetatable、值: function
键: next、值: function
键: select、值: function
键: assert、值: function
键: pairs、值: function
键: tonumber、值: function
键: _G、值: table
键: table、值: table
键: rawequal、值: function
键: debug、值: table
键: mw、值: table
键: getmetatable、值: function
键: tostring、值: function
```

將在表格`_G`上使用標準迭代器函數`pairs`進行迭代，直到它返回`nil`。

可以有嵌套的循環，就是在其他循環中的循環。

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

for indRow, row in ipairs(grid) do
  for indCol, value in ipairs(row) do
    print(" 行: " .. indRow .. "、列: " .. indCol .. " 值: " .. grid[indRow][indCol])
  end
end
```

```lua
行: 1、列: 1 值: 11
行: 1、列: 2 值: 12
行: 1、列: 3 值: 13
行: 2、列: 1 值: 21
行: 2、列: 2 值: 22
行: 2、列: 3 值: 23
行: 3、列: 1 值: 31
行: 3、列: 2 值: 32
行: 3、列: 3 值: 33
```

### 函數

Lua將函數處理為頭等值，在下例子中用`print`函數的表現可以修改來展示：

```lua
do
  local oldprint = print
  -- 存储当前的print函数为oldprint
  function print(s)
    --[[重新定义print函数。新函数只有一个实际参数。
    平常的print函数仍可以通过oldprint使用。]]
    oldprint(s == "foo" and "bar" or s)
  end
end
```

任何對`print`的進一步調用都要經由新函數，並且由於Lua的詞法作用域，這個舊的`print`函數將只能被這個新的修改了的`print`訪問到。

Lua還支持閉包，展示如下：

```lua
function addto(x)
  -- 返回一个把实际参数加到x上
  return function(y)
    --[=[ 在我们引用变量x的时候，它在当前作用域的外部。
    它的生命期会比这个匿名函数短，Lua建立一个闭包。]=]
    return x + y
  end
end
fourplus = addto(4)
print(fourplus(3))  -- 打印7

print(addto(4)(3))
--[[这是因为这直接用视件参数3调用了从addto(4)返回的函数。
    如果经常这么调用的话会减少数据消耗并提升性能。]]
```

每次調用的時候為變量`x`建立新的閉包，所以返回的每個新匿名函數都訪問它自己的`x`參數。閉包由Lua的垃圾收集器來管理，如同任何其他對象一樣。

```Lua
function create_a_counter()
  local count = 0
  return function()
    count = count + 1
    return count
  end
end
```

`create_a_counter()`會返回一個匿名函數，這個匿名函數會把`count`加`1`後再回傳。在匿名函數中的變數`count`的值會一直被保存在匿名函數中。因此調用`create_a_counter()`時產生一個記數器函數，每次調用記數器函數，都會得到一個比上次大`1`的值。

### 變量類型

Lua是一種動態類型語言，因此語言中沒有類型的定義，不需要聲明變量類型，每個變量自己保存了類型。

有8種基本類型：nil、布爾值（boolean）、數字型（number）、字串型（string）、使用者自定義類型（userdata）、函數（function）、線程（thread）和表（table）。

```Lua
print(type(nil))                    -- 输出 nil
print(type(99.7+12*9))              -- 输出 number
print(type(true))                   -- 输出 boolean
print(type("Hello Wikipedia"))      -- 输出 string
print(type(print))                  -- 输出 function
print(type({1, 2, test = "test"}))  -- 输出 table
```

### 表格

表格（table）是Lua中最重要的數據結構（並且是設計中唯一內建的複合數據類型），並且是所有使用者創建類型的基礎。它們是增加了自動數值鍵和特殊語法的關聯數組。

表格是鍵和數據的有序對的搜集，其中的數據用鍵來引用；換句話說，它是散列異構關聯數組。

表格使用`{}`構造器語法來創建。

```lua
a_table = {} -- 建立一个新的空表格
```

表格總是用引用來傳遞的（參見傳共享調用）。

鍵（索引）可以是除了`nil`和NaN的任何值，包括函數。

```lua
a_table = {x = 10}  -- 建立一个新表格，具有映射"x"到数10的一个表项。
print(a_table["x"]) -- 打印于这个字符串关联的值，这里是10。
b_table = a_table
b_table["x"] = 20   -- 在表格中的值变更为20。
print(b_table["x"]) -- 打印20。
print(a_table["x"]) -- 还是打印20，因为a_table和b_table都引用相同的表格。
```

通過使用字串作為鍵，表格經常用作對象複合（或記錄）。由於這種用法太常見，Lua為訪問這種欄位提供了特殊語法。

```lua
point = { x = 10, y = 20 }   -- 建立一个新表格
print(point["x"])            -- 打印10
print(point.x)               -- 同上一行完全相同含义。易读的点只是语法糖。
```

通過使用表格來存儲有關函數，它可以充當名字空間。

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

表格被自動的賦予了數值鍵，使得它們可以被用作陣列數據類型。第一個自動索引是`1`而非`0`，因為很多其他程式語言都這樣（儘管顯式的索引`0`是允許的）。

數值鍵`1`不同於字串鍵`"1"`。

```lua
array = { "a", "b", "c", "d" }   -- 索引被自动赋予。
print(array[2])                  -- 打印"b"。在Lua中自动索引开始于1。
print(#array)                    -- 打印4。#是表格和字符串的长度算符。
array[0] = "z"                   -- 0是合法索引。
print(#array)                    -- 仍打印4，因为Lua数组是基于1的。
```

表格`t`的長度被定義為任何整數索引`n`，使得`t[n]`不是`nil`而`t[n+1]`是`nil`；而且如果`t[1]`是`nil`， `n`可以是`0`。對於一個正規表格，具有非`nil`值從`1`到給定`n`，它的長度就精確的是`n`，它的最後的值的索引。如果這個陣列有「洞」（就是說在其他非`nil`值之間的`nil`值），則`#t`可以是直接前導於`nil`值的任何一個索引（就是說可以把任何這種`nil`值當作陣列的結束）。

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

表格可以是對象的陣列。

```lua
function Point(x, y)        -- "Point"对象构造器
  return { x = x, y = y }   -- 建立并返回新对象（表格）
end
array = { Point(10, 20), Point(30, 40), Point(50, 60) }   -- 建立point的数组
                        -- array = { { x = 10, y = 20 }, { x = 30, y = 40 }, { x = 50, y = 60 } };
print(array[2].y)                                         -- 打印40
```

使用散列映射來模擬陣列通常比使用真正數組要慢；但Lua表格為用作陣列而做了優化來避免這個問題。

### 元表格

可擴展的語義是Lua的關鍵特徵，而「元表格」概念允許以強力方式來定製Lua的表格。下列例子展示了一個「無限」表格。對於任何`n`，`fibs[n]`會給出第`n`個斐波那契數，使用了動態規劃和記憶化。

```lua
fibs = { 1, 1 }                                -- 给fibs[1]和fibs[2]初始值。
setmetatable(fibs, {
  __index = function(values, n)                --[[__index是Lua预定义的函数， 
                                                   如果"n"不存在则调用它。]]
    values[n] = values[n - 1] + values[n - 2]  -- 计算并记忆化fibs[n]。
    return values[n]
  end
})
local res = '斐波那契数: '; for idx = 1, 18 do res = res .. fibs[idx] .. '、 ' end; print(res)
```

```lua
斐波那契数: 1、 1、 2、 3、 5、 8、 13、 21、 34、 55、 89、 144、 233、 377、 610、 987、 1597、 2584、 
```

## 面向對象編程

儘管Lua沒有內建的類的概念，可以用過兩個語言特徵實現面向對象編程：頭等函數和表格。通過放置函數和有關數據入表格，形成一個對象。繼承（單繼承和多重繼承二者）可以通過使用元表格機制來實現，告訴這個對象在哪些父對象中查找不存在的方法。

對於這些技術不採用「類」的概念，而是採用原型，類似於Self或JavaScript。建立新對象要麼通過工廠方法（從頭構造一個新對象），要麼通過複製現存的對象。

建立一個基本的向量對象：

```lua
local Vector = {}
Vector.__index = Vector

function Vector:new(x, y, z)    -- 构造器
  return setmetatable({x = x, y = y, z = z}, Vector)
end

function Vector:magnitude()     -- 另一个方法
  -- 使用self引用隐蔽的对象
  return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end

local vec = Vector:new(0, 1, 0) -- 建立一个向量
print(vec:magnitude())          -- 调用一个方法 (输出: 1)
print(vec.x)                    -- 访问一个成员变量 (输出: 0)
```

Lua為便利對象定向提供了一些語法糖。要聲明在原型表格內的成員函數，可以使用function table:func(args)，它等價於function table.func(self, args)。調用類方法也使用冒號，object:func(args)等價於object.func(object, args)。

下面是使用語法糖的對應的類：

```lua
local Vector = {}
Vector.__index = Vector

function Vector:new(x, y, z)    -- 构造子
  -- 因为函数定义使用冒号， 
  -- 其第一个实际参数是"self"
  -- 它引用到"Vector"
  return setmetatable({x = x, y = y, z = z}, self)
end

function Vector:magnitude()     -- 另一个方法
  -- 使用self引用隐含的对象
  return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end

local vec = Vector:new(0, 1, 0) -- 建立一个向量
print(vec:magnitude())          -- 调用方法（输出：1）
print(vec.x)                    -- 访问成员变量（输出：0）
```

### 繼承

Lua支持使用元表格來使得Lua具有類繼承。在這個例子中，我們允許向量在派生的類中將它們的值乘以一個常量：

```lua
local Vector = {}
Vector.__index = Vector

function Vector:new(x, y, z)    -- 构造子
  -- 这里的self引用到我们调用"new"方法的任何类
  -- 在派生的类中，self将是派生的类。
  -- 在Vector类中，self将是Vector。
  return setmetatable({x = x, y = y, z = z}, self)
end

function Vector:magnitude()     -- 另一个方法
  -- 使用self引用隐含的对象
  return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end

-- 类继承的例子
local VectorMult = {}
VectorMult.__index = VectorMult
setmetatable(VectorMult, Vector) -- 使得VectorMult成为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) -- 建立一个向量
print(vec:magnitude())          -- 调用一个方法（输出：1）
print(vec.y)                    -- 访问一个成员变量（输出：1）
vec:multiply(2)                 -- 将向量的所有分量乘以2
print(vec.y)                    -- 再次访问成员变量（输出：2）
```

Lua還支持多重繼承，__index可以要麼是一個函數要麼是一個表格。也支持運算符重載，Lua元表格通過設置元素比如__add、__sub等來重寫表的操作符操作行為。

## 實現

Lua程序不是從文本式的Lua文件直接解釋的，而是編譯成字節碼，接著把它運行在Lua虛擬機上。編譯過程典型的對於使用者是不可見並且是在運行時間進行的，但是它可以離線完成用來增加裝載性能或通過排除編譯器來減少對宿主環境的記憶體占用。Lua字節碼還可以在Lua之內產生和執行，使用來自字串庫的`dump`函數和`load/loadstring/loadfile`函數。Lua版本5.3.4是用大約24,000行C代碼實現的。

像大多數CPU，而不像多數虛擬機（它們是基於堆棧的），Lua VM是基於寄存器的，因此更加類似真實的硬體設計。寄存器架構既避免了過多的值複製又減少了每函數的指令的總數。Lua 5的虛擬機是第一個廣泛使用的基於寄存器的純VM。Parrot和Android的Dalvik是另外兩個周知的基於寄存器的VM。PCScheme的VM也是基於寄存器的。

下面的例子列出上面定義的階乘函數的字節碼（通過`luac` 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意圖被嵌入到其他應用之中，為了這個目的而提供了C API。API被分成兩部份：Lua核心庫和輔助庫。Lua API的設計消除了對用C代碼的手動引用管理的需要，不同於Python的API。API就像語言本身一樣是極簡主義的。高級功能通過輔助庫來提供，它們很大程度上構成自預處理器宏，用以幫助做複雜的表格操作。

Lua C API是基於堆棧的。Lua提供壓入和彈出最簡單C數據類型（整數、浮點數等）進入和離開堆棧的函數，還有通過堆棧操作表格的函數。Lua堆棧稍微不同於傳統堆棧，例如堆棧可以直接的被索引。負數索引指示從棧頂開始往下的偏移量。例如−1是在頂部的（最新進壓入的值），而整數索引指示從底部（最舊的值）往上的偏移量。在C和Lua函數之間集結數據也使用堆棧完成。要調用一個Lua函數，把實際參數壓入堆棧，並接著使用`lua_call`來調用實際的函數。在寫從Lua直接調用的C函數的時候，實際參數讀取自堆棧。

下面是從C調用Lua函數的例子:

```c
#include <stdio.h>
#include <lua.h> // Lua主要库 (lua_*)
#include <lauxlib.h> // Lua辅助库 (luaL_*)

int main(void)
{
    // 建立一个Lua状态
    lua_State *L = luaL_newstate();

    // 装载并执行一个字符串
    if (luaL_dostring(L, "function foo (x,y) return x+y end")) {
        lua_close(L);
        return -1;
    }

    // 压入全局"foo"（上面定义的函数）的值
    // 到堆栈，跟随着整数5和3
    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)); // 打印在栈顶的项目的整数值
    lua_pop(L, 1); // 返回堆栈至最初状态
    lua_close(L); // 关闭Lua状态
    return 0;
}
```

如下這樣運行這個例子：

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

C API還提供一些特殊表格，位於各種Lua堆棧中的「偽索引」之上。Lua 5.2之前，在`LUA_GLOBALSINDEX`之上是全局表格；`_G`來自Lua內部，它是主名字空間。還有一個註冊表位於`LUA_REGISTRYINDEX`，在這裡C程序可以存儲Lua值用於以後檢索。

還可以使用Lua API寫擴展模塊。擴展模塊是通過向Lua腳本提供本地設施，用來擴展解釋器的功能的共享對象。從Lua方面看來，這種模塊出現為一個名字空間表格，它持有自己的函數和變量。Lua腳本可以使用`require`裝載擴展模塊，就像用Lua自身寫的模塊一樣。一組仍在增長中的叫做「rock」的模塊可以通過叫做LuaRocks的軟體包管理器獲取到，類似於CPAN、RubyGems和Setuptools。對大多數流行的程式語言包括其他腳本語言，都存在預先寫好的Lua綁定。對於C++，有許多基於模板的方式和一些自動綁定生成器。

## 應用

在影片遊戲開發中，Lua被程式設計師廣泛的用作腳本語言，主要由於它的可感知到的易於嵌入、快速執行，和短學習曲線。

在2003年，GameDev.net組織的一次投票，說明了Lua是遊戲編程的最流行腳本語言。在2012年1月12日，Lua被《遊戲開發者 (期刊)》宣布為編程工具範疇的Front Line獎2011年度獲獎者。

大量非遊戲應用也出於可擴展性而使用Lua，比如TeX排版設置語言實現LuaTeX、鍵-值資料庫Redis、文本編輯器Neovim和web伺服器Nginx。

通過Scribunto擴展，Lua可獲得為MediaWiki軟體中的伺服器端腳本語言，Wikipedia和其他wiki都基於了它。它的應用包括允許從Wikidata集成數據到文章中，和助力於自動生物分類框系統。

Lua可以用於嵌入式硬體，不僅可以嵌入其他編程語言，而且可以嵌入微處理器中，例如NodeMCU開源硬體項目將Lua嵌入到Wi-Fi SoC中，另外，遊戲平台Roblox所有遊戲都是利用Lua進行編程的。另外, 還有中國大陸發起的開源LuatOS項目，也是將Lua應用到嵌入式領域，但不僅限於Wifi，它包含2G/4G/NBIOT等通信模塊，也包含stm32/w800等嵌入式mcu，同時也支持在windows/linux平台上執行的模擬器。

## 派生語言

### 編譯成Lua的語言

以Lua作為編譯目標輸出的程式語言：

- Moonscript，是動態、空白敏感的腳本語言，它受到CoffeeScript的啟發，編譯成Lua。
- Haxe，支持編譯成Lua目標，支持Lua 5.1-5.3還有LuaJIT 2.0和2.1。
- Fennel，目標為Lua的Lisp方言。
- Urn，建造在Lua之上的Lisp方言。
- Amulet，類ML的函數式語言，其編譯器輸出Lua文件。
- LunarML，產生Lua/JavaScript代碼的Standard ML編譯器。

### 方言

- LuaJIT，Lua 5.1的即時編譯器。
- Luau (程式語言)，由Roblox Corporation開發，並運用於Roblox平台，派生自Lua 5.1，具有漸進類型，補充特徵並關注於性能。
- Ravi，啟用了JIT的Lua 5.3語言並具有可選的靜態類型。JIT由類型資訊來指導。
- Shine，既有很多擴展的LuaJIT分叉，包括了模塊系統和宏系統。
- Glua，嵌入到遊戲蓋瑞模組中作為其腳本語言的一個Lua修改版本。
- Teal，用Lua編寫的靜態類型的Lua方言。

此外，Lua使用者社區在參考C語言實現之上提供了一些「能力補丁」。

## 延伸閱讀

- (The 1st ed. is available online .)
- Chapters 6 and 7 are dedicated to Lua, while others look at software in Brazil more broadly.
- Interview with Roberto Ierusalimschy.
- How the embeddability of Lua impacted its design.
- Lua papers and theses

## 基本資料

- 編程范型：多范型：腳本，指令式（過程式，基於原型，面向對象），函數式
- 發行時間：1993年
- 設計者：Roberto Ierusalimschy、Waldemar Celes、Luiz Henrique de Figueiredo
- 軟體版本週期：Q207316
- 類型系統：動態、強類型、鴨子
- 軟體實現：//www.lua.org/download.html Lua, LuaJIT, //eliasdaler.github.io/luavela/ LuaVela, MoonSharp, //luvit.io Luvit, //www.luart.org LuaRT
- 實作語言：ANSI C
- dialects： Metalua, Idle, GSL Shell, Luau
- 受影響於：Scheme、SNOBOL、Modula-2、CLU、C++
- 施影響於：GameMonkey Script, Io, JavaScript, Julia, MiniD, Red (程式語言), Ring, Ruby, Squirrel (程式語言), MoonScript, C--
- 作業系統：跨平台
- 許可證：MIT許可證
- 文件擴展名：.lua