Lua
Template:NoteTA 腳本錯誤:沒有「about」這個模塊。 Template:Selfref 腳本錯誤:沒有「Infobox」這個模塊。腳本錯誤:沒有「Check for unknown parameters」這個模塊。
Lua(腳本錯誤:沒有「IPAc-en」這個模塊。,詞源葡萄牙語「月亮」)是一個簡潔、輕量、可擴展的腳本語言。Lua有著相對簡單的C語言API而很容易嵌入應用中[1]。很多應用程式使用Lua作為自己的嵌入式腳本語言,以此來實現可配置性、可擴展性[2]。
歷史[編輯]
Template:CSS image crop Lua是在1993年由羅伯托·耶魯薩林斯希、Luiz Henrique de Figueiredo和Waldemar Celes創建的,他們當時是巴西的里約熱內盧天主教大學的計算機圖形技術組(Tecgraf)成員。Lua的先驅是數據描述/配置語言「SOL」(簡單對象語言)和「DEL」(數據錄入語言)[3]。他們於1992年–1993年在Tecgraf獨立開發了需要增加靈活性的兩個不同項目(都是用於工程應用的交互式圖形程序)。在SOL和DEL中缺乏很多控制流結構,需要向它們增加完全的編程能力。
在《The Evolution of Lua》中,這門語言的作者寫道[4]:
頁面Template:Quote/blockquote.css沒有內容。
在1993年,唯一真正的競爭者是Tcl,它已經明確的設計用於嵌入到應用之中。但是,Tcl有著不熟知的語法,未對數據描述提供良好的支持,並且只在Unix平台上運行。我們不考慮LISP或Scheme,因為它們有著不友好的語法。Python仍處在幼年期。在Tecgraf的自由的自力更生氛圍下,我們非常自然的嘗試開發自己的腳本語言 ... 由於這門語言的很多潛在用戶不是專業編程者,語言應當避免神秘的語法和語義。新語言的實現應當是高度可移植的,因為Tecgraf的客戶有著非常多樣的各種計算機平台。最後,由於我們預期Tecgraf的其他產品也需要嵌入腳本語言,新語言應當追隨SOL的例子並提供為帶有C API的庫。
Lua主要受到了下列前輩語言的影響:
- Modula-2:從中引入了大部份控制結構Template:Le,
if、while、repeat/until。 - CLU:多賦值和從函數調用的多個返回值,這是對引用參數或顯式指針的更簡單的替代。
- C++:「允許局部變量只在需要的地方聲明的靈巧想法」[4]。
- SNOBOL和AWK:關聯數組。
- LISP和Scheme:在發表於《Template:Le》的文章中,Lua的創立者還聲稱,有著單一且無所不在的數據結構機制(列表)的LISP和Scheme,對他們決定將表格開發為Lua的主要數據結構起到了主要影響[5]。Lua的語義久而久之日趨受到Scheme的影響[4],特別是介入了匿名函數和完全的詞法作用域。
Lua在版本5.0之前在類似BSD許可證之下發行。自從版本5.0以來,Lua採用了MIT許可證。
特性[編輯]
Lua是一種輕量語言,它的官方版本只包括一個精簡的核心和最基本的庫。這使得Lua體積小、啟動速度快。它用ANSI C語言編寫[6],並以原始碼形式開放,編譯後的完整參考解釋器只有大約247kB[6],到5.4.3版本,該體積變成283kB(Linux,amd64),依然非常小巧,可以很方便的嵌入別的程式裡。和許多「大而全」的語言不一樣,網路通訊、圖形界面等都沒有預設提供。但是Lua可以很容易地被擴展:由宿主語言(通常是C或C++)提供這些功能,Lua可以使用它們,就像是本來就內置的功能一樣。事實上,現在已經有很多成熟的擴展模塊可供選用。
Lua是一個動態類型語言,支援增量式垃圾收集策略。有內建的,與作業系統無關的協作式多線程支援。Lua原生支援的數據類型很少,只提供了數值(默認是雙精度浮點數,可配置)、布爾量、字符串、表格、函數、線程以及用戶自定義數據這幾種。但是其處理表和字符串的效率非常之高,加上元表的支援,開發者可以高效的模擬出需要的複雜數據類型(比如集合、數組等)。
語法和語義[編輯]
Lua是一種多重編程范型的程式設計語言:它只提供了很小的一個特性集合來滿足不同編程范型的需要,而不是為某種特定的編程范型提供繁雜的特性支援。例如,Lua並不提供繼承這個特性,但是你可以用元表格來模擬它。諸如命名空間、類這些概念都沒有在語言基本特性中實現,但是我們可以用表格結構(Lua唯一提供的複雜數據結構)輕易模擬。正是提供了這些基本的元特性,我們可以任意的對語言進行自需的改造。
Lua實現了少量的高級特徵比如頭等函數、垃圾回收、閉包、正當尾調用、類型轉換(於運行時間在字符串和數值之間自動轉換)、協程(協作多任務)和動態模塊裝載。
詞法[編輯]
經典的Hello World!程序可以寫為如下[7]:
print("Hello World!")
或者如下:
print 'Hello World'
print [[Hello World]]
在Lua中注釋可以於雙連字符並行至此行的結束,類似於Ada、Eiffel、Haskell、SQL和VHDL。多行字符串和注釋用雙方括號來裝飾。
下例中實現了一個階乘函數:
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))
120
控制流[編輯]
Lua有一種類型的條件測試:if then end,它具有可選的else和elseif then執行控制構造。
通用的if then end語句需要三個關鍵字:
if condition then
--当 condition 为 true 时执行的语句体
end
可以增加else關鍵字來控制執行,它隨同著在if條件求值為false之時執行的語句塊:
if condition then
--当 condition 为 true 时执行的语句体
else
--当上述条件都为 false 时执行的可选默认语句体
end
還可以使用elseif then關鍵字依據多個條件來控制執行:
if condition1 then
-- 当 condition1 为 true 时执行的语句体
elseif condition2 then
-- 当 condition1 为 false 且 condition2 为 true 时执行的语句体
else -- 可选
-- 当上述条件都为 false 时执行的可选默认语句体
end
Lua有四種類型的循環:while循環、repeat循環(類似於do while循環)、數值for循環和通用for循環。
- while
condition = true -- 进入 while 循环的条件
while condition do
-- 在这里修改 condition 为 false,以避免无限循环
end
--[[注意:如果循环无响应,请关闭模块:Example 或关闭浏览器]]-- local idx = 1 -- 初始计数器值 -- 将 condition 变量设为 false 的语句以避免无限循环 while idx <= 5 do -- 当 idx 小于或等于 5 时循环(为避免无限循环) print(idx) -- 在调试控制台输出当前计数器值 idx = idx + 1 -- 在每次迭代中增加计数器,以确保循环结束 end -- 循环结束时 idx 的值将为 6。 print("while 循环之外、idx = " .. idx)
1 2 3 4 5 while 循环之外、idx = 6
- repeat
condition = false -- 在 repeat 循环中至少循环一次的条件
repeat
-- 在这里将 condition 修改为 true,以避免无限循环
until condition
local idx = 1 -- 初始计数器值 repeat print(idx) -- 在调试控制台输出当前计数器值 idx = idx + 1 -- 在每次迭代中增加计数器,以确保循环结束 -- 将 condition 变量设为 true 的语句以避免无限循环 until idx > 5 -- 循环结束时 idx 的值将为 6。 print("repeat 循环之外、idx = " .. idx)
1 2 3 4 5 repeat 循环之外、idx = 6
- for
for idx = first, last, delta do --delta可以是负数,允许计数增加或减少的循环
-- 使用 idx 的语句
-- 例如:print(idx)
end
for idx = 1, 5 do -- for idx = 从, 到 print(idx) end -- 变量 idx 在 for 循环外不可见
1 2 3 4 5
通用for循環:
for key, value in pairs(_G) do print("键: " .. key .. "、值: " .. tostring(value)) end
键: 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。
可以有嵌套的循環,就是在其他循環中的循環。
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
行: 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函數的表現可以修改來展示:
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還支持閉包,展示如下:
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的垃圾收集器來管理,如同任何其他對象一樣。
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)。
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中最重要的數據結構(並且是設計中唯一內建的複合數據類型),並且是所有用戶創建類型的基礎。它們是增加了自動數值鍵和特殊語法的關聯數組。
表格是鍵和數據的有序對的搜集,其中的數據用鍵來引用;換句話說,它是散列異構關聯數組。
表格使用{}構造器語法來創建。
a_table = {} -- 建立一个新的空表格
表格總是用引用來傳遞的(參見傳共享調用)。
鍵(索引)可以是除了nil和NaN的任何值,包括函數。
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都引用相同的表格。
通過使用字符串作為鍵,表格經常用作Template:Le(或記錄)。由於這種用法太常見,Lua為訪問這種欄位提供了特殊語法[8]。
point = { x = 10, y = 20 } -- 建立一个新表格
print(point["x"]) -- 打印10
print(point.x) -- 同上一行完全相同含义。易读的点只是语法糖。
通過使用表格來存儲有關函數,它可以充當名字空間。
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
表格被自動的賦予了數值鍵,使得它們可以被用作Template:Le。第一個自動索引是1而非0,因為很多其他程式語言都這樣(儘管顯式的索引0是允許的)。
數值鍵1不同於字符串鍵"1"。
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值當作數組的結束[9])。
ExampleTable =
{
{1, 2, 3, 4},
{5, 6, 7, 8}
}
print(ExampleTable[1][3]) -- 打印"3"
print(ExampleTable[2][4]) -- 打印"8"
表格可以是對象的數組。
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表格為用作數組而做了優化來避免這個問題[10]。
元表格[編輯]
可擴展的語義是Lua的關鍵特徵,而「元表格」概念允許以強力方式來定製Lua的表格。下列例子展示了一個「無限」表格。對於任何n,fibs[n]會給出第n個斐波那契數,使用了動態規劃和記憶化。
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)
斐波那契数: 1、 1、 2、 3、 5、 8、 13、 21、 34、 55、 89、 144、 233、 377、 610、 987、 1597、 2584、
面向對象編程[編輯]
儘管Lua沒有內建的類的概念,可以用過兩個語言特徵實現面向對象編程:頭等函數和表格。通過放置函數和有關數據入表格,形成一個對象。繼承(單繼承和多重繼承二者)可以通過使用元表格機制來實現,告訴這個對象在哪些父對象中查找不存在的方法。
對於這些技術不採用「類」的概念,而是採用原型,類似於Self或JavaScript。建立新對象要麼通過工廠方法(從頭構造一個新對象),要麼通過複製現存的對象。
建立一個基本的向量對象:
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)。
下面是使用:語法糖的對應的類:
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具有類繼承[11]。在這個例子中,我們允許向量在派生的類中將它們的值乘以一個常量:
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可以要麼是一個函數要麼是一個表格[12]。也支持運算符重載,Lua元表格通過設置元素比如__add、__sub等來重寫表的操作符操作行為[13]。
實現[編輯]
Lua程序不是從文本式的Lua文件直接解釋的,而是編譯成字節碼,接著把它運行在Lua虛擬機上。編譯過程典型的對於用戶是不可見並且是在運行時間進行的,但是它可以離線完成用來增加裝載性能或通過排除編譯器來減少對宿主環境的內存占用。Lua字節碼還可以在Lua之內產生和執行,使用來自字符串庫的dump函數和load/loadstring/loadfile函數。Lua版本5.3.4是用大約24,000行C代碼實現的[2][6]。
像大多數CPU,而不像多數虛擬機(它們是基於堆棧的),Lua VM是基於寄存器的,因此更加類似真實的硬體設計。寄存器架構既避免了過多的值複製又減少了每函數的指令的總數。Lua 5的虛擬機是第一個廣泛使用的基於寄存器的純VM[14]。Parrot和Android的Dalvik是另外兩個周知的基於寄存器的VM。PCScheme的VM也是基於寄存器的[15]。
下面的例子列出上面定義的階乘函數的字節碼(通過luac 5.1編譯器來展示)[16]:
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核心庫和輔助庫[17]。Lua API的設計消除了對用C代碼的手動引用管理的需要,不同於Python的API。API就像語言本身一樣是極簡主義的。高級功能通過輔助庫來提供,它們很大程度上構成自預處理器宏,用以幫助做複雜的表格操作。
Lua C API是基於堆棧的。Lua提供壓入和彈出最簡單C數據類型(整數、浮點數等)進入和離開堆棧的函數,還有通過堆棧操作表格的函數。Lua堆棧稍微不同於傳統堆棧,例如堆棧可以直接的被索引。負數索引指示從棧頂開始往下的偏移量。例如−1是在頂部的(最新進壓入的值),而整數索引指示從底部(最舊的值)往上的偏移量。在C和Lua函數之間集結數據也使用堆棧完成。要調用一個Lua函數,把實際參數壓入堆棧,並接著使用lua_call來調用實際的函數。在寫從Lua直接調用的C函數的時候,實際參數讀取自堆棧。
下面是從C調用Lua函數的例子:
#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;
}
如下這樣運行這個例子:
$ cc -o example example.c -llua
$ ./example
Result: 8
C API還提供一些特殊表格,位於各種Lua堆棧中的「偽索引」之上。Lua 5.2之前[18],在LUA_GLOBALSINDEX之上是全局表格;_G來自Lua內部,它是主名字空間。還有一個註冊表位於LUA_REGISTRYINDEX,在這裡C程序可以存儲Lua值用於以後檢索。
還可以使用Lua API寫擴展模塊。擴展模塊是通過向Lua腳本提供本地設施,用來擴展解釋器的功能的共享對象。從Lua方面看來,這種模塊出現為一個名字空間表格,它持有自己的函數和變量。Lua腳本可以使用require裝載擴展模塊[17],就像用Lua自身寫的模塊一樣。一組仍在增長中的叫做「rock」的模塊可以通過叫做Template:Le的軟體包管理器獲取到[19],類似於CPAN、RubyGems和Template:Le。對大多數流行的程式語言包括其他腳本語言,都存在預先寫好的Lua綁定[20]。對於C++,有許多基於模板的方式和一些自動綁定生成器。
應用[編輯]
腳本錯誤:沒有「main」這個模塊。
在視頻遊戲開發中,Lua被程式設計師廣泛的用作腳本語言,主要由於它的可感知到的易於嵌入、快速執行,和短學習曲線[21]。
在2003年,GameDev.net組織的一次投票,說明了Lua是遊戲編程的最流行腳本語言[22]。在2012年1月12日,Lua被《Template:Le》宣布為編程工具範疇的Front Line獎2011年度獲獎者[23]。
大量非遊戲應用也出於可擴展性而使用Lua,比如TeX排版設置語言實現LuaTeX、鍵-值資料庫Redis、文本編輯器Neovim和web伺服器Nginx。
通過Scribunto擴展,Lua可獲得為MediaWiki軟體中的伺服器端腳本語言,Wikipedia和其他wiki都基於了它[24][25]。它的應用包括允許從Wikidata集成數據到文章中[26],和助力於Template:Le。
Lua可以用於嵌入式硬體,不僅可以嵌入其他編程語言,而且可以嵌入微處理器中,例如NodeMCU開源硬體項目將Lua嵌入到Wi-Fi SoC中[27],另外,遊戲平台Roblox所有遊戲都是利用Lua進行編程的。另外, 還有中國大陸發起的開源LuatOS項目[28],也是將Lua應用到嵌入式領域,但不僅限於Wifi,它包含2G/4G/NBIOT等通信模塊,也包含stm32/w800等嵌入式mcu,同時也支持在windows/linux平台上執行的模擬器。
派生語言[編輯]
編譯成Lua的語言[編輯]
- Moonscript,是動態、空白敏感的腳本語言,它受到CoffeeScript的啟發,編譯成Lua[30][31][32]。
- Haxe,支持編譯成Lua目標,支持Lua 5.1-5.3還有LuaJIT 2.0和2.1。
- Fennel,目標為Lua的Lisp方言[33]。
- Urn,建造在Lua之上的Lisp方言[34]。
- Amulet,類ML的函數式語言,其編譯器輸出Lua文件[35]。
- LunarML,產生Lua/JavaScript代碼的Standard ML編譯器[36]。
方言[編輯]
- Template:Le,Lua 5.1的即時編譯器[37][38]。
- Template:Le,由Roblox公司開發,派生自Lua 5.1,具有Template:Le,補充特徵並關注於性能[39]。
- Ravi,啟用了JIT的Lua 5.3語言並具有可選的靜態類型。JIT由類型信息來指導[40]。
- Shine,既有很多擴展的LuaJIT分叉,包括了模塊系統和宏系統[41]。
- Glua,嵌入到遊戲蓋瑞模組中作為其腳本語言的一個Lua修改版本[42]。
- Teal,用Lua編寫的靜態類型的Lua方言。
此外,Lua用戶社區在參考C語言實現之上提供了一些「能力補丁」[43]。
引用[編輯]
- ↑ Template:Cite web
- ↑ 2.0 2.1 Template:Cite journal
- ↑ Template:Cite web。
- ↑ 4.0 4.1 4.2 Template:Cite book
- ↑ 腳本錯誤:沒有「Citation/CS1」這個模塊。
- ↑ 6.0 6.1 6.2 Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite book
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite journal
- ↑ Template:Cite book
- ↑ Template:Cite web
- ↑ 17.0 17.1 Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ 腳本錯誤:沒有「citation/CS1」這個模塊。
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
- ↑ Template:Cite web
延伸閱讀[編輯]
頁面Template:ReflistH/styles.css沒有內容。
- Template:Cite book (The 1st ed. is available online (頁面存檔備份,存於網際網路檔案館).)
- Template:Cite book
- Template:Cite book
- Template:Cite book
- Template:Cite book
- Template:Cite book Chapters 6 and 7 are dedicated to Lua, while others look at software in Brazil more broadly.
- Template:Cite book
- Template:Cite web
- Template:Cite web
- Template:Cite web
- Template:Cite journal
- Template:Cite news Interview with Roberto Ierusalimschy.
- Template:Cite journal How the embeddability of Lua impacted its design.
- Template:Cite journal
- Lua papers and theses (頁面存檔備份,存於網際網路檔案館)
外部連結[編輯]
腳本錯誤:沒有「Sister project links」這個模塊。
- Template:Official website
- Lua Users (頁面存檔備份,存於網際網路檔案館), 用戶社區
- Awesome Lua (頁面存檔備份,存於網際網路檔案館)
腳本錯誤:沒有「Navbox」這個模塊。