MediaWiki Scribunto 拡張機能を使用したWikipedia Lua モジュールの Lua コードのスクリーンショット | |
| パラダイム | マルチパラダイム:スクリプト、命令型(手続き型、プロトタイプベース、オブジェクト指向)、関数型、メタ、リフレクティブ |
|---|---|
| デザイン: | ロベルト・イエルサリムシ ・ワルデマール・セレス・ルイス ・エンリケ・デ・フィゲイレド |
| 初登場 | 1993年 |
| 安定リリース | 5.4.7 [1]
/ 2024年6月25日 |
| タイピングの規律 | ダイナミック、強い、アヒル |
| 実装言語 | ANSI C |
| OS | クロスプラットフォーム |
| ライセンス | マサチューセッツ工科大学 |
| ファイル名拡張子 | .lua |
| Webサイト | 詳しくはこちら |
| 主な実装 | |
| Lua、LuaJIT、LuaVela、MoonSharp、Luvit、LuaRT、Lauu | |
| 方言 | |
| メタルア、アイドル、GSL シェル | |
| 影響を受けた | |
| C++、CLU、Modula、Scheme、SNOBOL | |
| 影響を受けた | |
| GameMonkey、Io、JavaScript [要出典]、Julia、MiniD、Red、Ring、[2] Ruby、[要出典] Squirrel、MoonScript、C-- | |
Lua (/ ˈ l uː ə / LOO -ə ;ポルトガル語:lua [ˈlu(w)ɐ]は月を意味する)は、主にアプリケーションへの組み込み用に設計された軽量で高水準なマルチパラダイム プログラミング言語です。 [3] Luaはクロスプラットフォームソフトウェアであり、コンパイルされたバイトコードのインタープリタはANSI Cで記述されており、[4] Luaにはアプリケーションに組み込むための比較的単純なCアプリケーションプログラミングインターフェイス(API)があります。[5]
Lua は、当時高まるカスタマイズの需要に応えるためにソフトウェア アプリケーションを拡張するための言語として 1993 年に誕生しました。ほとんどの手続き型プログラミング言語の基本的な機能を提供していましたが、より複雑な機能やドメイン固有の機能は含まれていませんでした。代わりに、言語を拡張するためのメカニズムが含まれており、プログラマがそのような機能を実装できるようにしていました。Lua は汎用の埋め込み可能な拡張言語となることを意図していたため、Lua の設計者は開発時の速度、移植性、拡張性、使いやすさの向上に重点を置きました。
歴史
Lua は、ブラジルのリオデジャネイロ・ポンティフィカル・カトリック大学のコンピュータグラフィックス技術グループ (Tecgraf) のメンバーであるRoberto Ierusalimschy 、 Luiz Henrique de Figueiredo 、 Waldemar Celesによって 1993 年に作成されました。
1977年から1992年まで、ブラジルはコンピュータハードウェアとソフトウェアに対して強力な貿易障壁(市場留保と呼ばれる)政策をとっており、ブラジルは独自のハードウェアとソフトウェアを生産できるし、生産すべきであると信じていた。その状況下では、Tecgrafの顧客は政治的にも経済的にも海外からカスタマイズされたソフトウェアを購入する余裕がなかった。市場留保の下では、顧客はブラジルの企業ではニーズを満たせないことを証明するために複雑な官僚的プロセスを経なければならなかった。これらの理由から、Tecgrafは必要な基本ツールをゼロから実装することになった。[6]
Lua の前身は、データ記述/構成言語であるSimple Object Language (SOL) とデータエントリ言語(DEL) でした。[7]これらは、1992 年から 1993 年にかけて Tecgraf で独立して開発され、2 つの異なるプロジェクト (どちらもPetrobras社のエンジニアリング アプリケーション用のインタラクティブ グラフィカル プログラム) に柔軟性を追加しました。SOL と DEL にはフロー制御構造がまったくなく、Petrobras はこれらに完全なプログラミング機能を追加する必要性が高まっていると感じていました。
Luaの進化の中で、この言語の作者は次のように書いている: [6]
1993 年、唯一の真の競争相手は、アプリケーションに組み込むように明示的に設計されたTclでした。しかし、Tcl は構文がわかりにくく、データ記述のサポートが不十分で、Unix プラットフォームでしか実行できませんでした。LISPやScheme は、使いにくい構文のため検討しませんでした。Pythonはまだ初期段階でした。当時 Tecgraf に浸透していた自由で DIY の雰囲気の中で、独自のスクリプト言語を開発しようとするのはごく自然なことでした... この言語の潜在的なユーザーの多くはプロのプログラマーではないため、この言語では難解な構文やセマンティクスを避ける必要がありました。Tecgraf のクライアントは多種多様なコンピュータ プラットフォームを持っていたため、新しい言語の実装は移植性が高くなければなりませんでした。最後に、他の Tecgraf 製品にもスクリプト言語を組み込む必要があると予想されたため、新しい言語は SOL の例に倣い、C API を備えたライブラリとして提供される必要がありました。
Lua 1.0 は、オブジェクト コンストラクタが当時の軽量で柔軟なスタイルとは少し異なっており、 SOLのデータ記述構文を組み込むように設計されていました (そのためLua という名前が付けられました。Sol はポルトガル語で「太陽」、Lua は「月」を意味します)。制御構造の Lua構文は主にModula ( if、、while/ ) から借用されましたが、CLU (関数呼び出しからの複数の代入と複数の戻り。参照パラメータや明示的なポインタのより簡単な代替手段)、C++ (「必要な場所でのみローカル変数を宣言できるようにする優れたアイデア」 [6] )、SNOBOL、AWK (連想配列) の影響も受けていました。Dr . Dobb's Journalに掲載された記事で、Lua の作成者は、LISP と Scheme の単一のユビキタスなデータ構造メカニズム (リスト) が、テーブルを Lua の主要データ構造として開発するという決定に大きな影響を与えたと述べています。 [8]repeatuntil
Luaのセマンティクスは時間の経過とともにSchemeの影響をますます受けてきており、[6]特に匿名関数と完全なレキシカルスコープの導入により影響を受けています。新しいLuaバージョンではいくつかの機能が追加されました。
Lua のバージョン 5.0 より前のバージョンは、BSD ライセンスに類似したライセンスの下でリリースされました。バージョン 5.0 以降、Lua はMIT ライセンスの下でライセンスされています。どちらも許容的なフリー ソフトウェア ライセンスであり、ほぼ同じです。
特徴
Lua は一般に「マルチパラダイム」言語と呼ばれ、さまざまな問題の種類に合わせて拡張できる一般的な機能の小さなセットを提供します。Lua には継承の明示的なサポートはありませんが、メタテーブルを使用して実装できます。同様に、Lua では、プログラマーが単一のテーブル実装を使用して名前空間、クラス、およびその他の関連機能を実装できます。ファーストクラス関数により、関数型プログラミングの多くのテクニックを活用でき、完全な語彙スコープにより、きめ細かい情報隠蔽が可能になり、最小権限の原則を強制できます。
一般的に、Luaは、1つのプログラミングパラダイムに固有の機能セットを提供するのではなく、必要に応じて拡張できるシンプルで柔軟なメタ機能を提供することを目指しています。その結果、ベース言語は軽量で、完全なリファレンスインタープリタはコンパイル後でも約247kBしかなく [ 4]、幅広いアプリケーションに簡単に適応できます。
拡張言語またはスクリプト言語として使用することを目的とした動的型付け言語であるLua は、さまざまなホスト プラットフォームに適合するほどコンパクトです。ブール値、数値 (デフォルトでは倍精度浮動小数点数と64 ビット整数)、文字列などの少数のアトミック データ構造のみをサポートしています。配列、セット、リスト、レコードなどの一般的なデータ構造は、Lua の単一のネイティブ データ構造であるテーブルを使用して表すことができます。テーブルは、本質的には異種連想配列です。
Lua は、ファーストクラス関数、ガベージコレクション、クロージャ、適切な末尾呼び出し、強制変換(実行時に文字列と数値を自動的に変換する)、コルーチン(協調型マルチタスク)、動的モジュール読み込みなどの高度な機能の小さなセットを実装しています。
構文
古典的な「Hello, World!」プログラムは、括弧の有無にかかわらず、次のように記述できます。[9] [a]
印刷( "Hello, World!" )
「Hello, World!」と印刷します。
Lua のコメントは、 Ada、Eiffel、Haskell、SQL、VHDLと同様に、二重ハイフンで始まり、行末まで続きます。複数行の文字列とコメントは、二重角括弧でマークされます。
-- 単一行コメント
--[[
複数行コメント
--]]
この例では階乗関数が実装されています。
関数 階乗( n )
ローカル x = 1
i = 2 、n の場合 x = x * iを実行する終了戻り値x終了
制御フロー
Lua には、オプションと実行制御構造を
持つ1 種類の条件テストがあります。if then endelseelseif then
汎用if then endステートメントには、次の 3 つのキーワードすべてが必要です。
if 条件 then
--文本体
終了
条件が次のように評価されたelse場合に実行を制御するために、付随するステートメント ブロックとともにキーワードを追加できます。
iffalse
if 条件 then
--文本体
else
--文本体
end
次のキーワードを使用して、複数の条件に従って実行を制御することもできますelseif then。
if 条件 then
--文本体
elseif 条件 then
--文本体
else -- オプション
--オプション デフォルト文本体
end
whileLua には、ループ、repeatループ (do whileループに似ています)、数値forループ、汎用ループの 4 種類の条件付きループがありますfor。
--条件 = 真
while 条件 do
--ステートメント
終了
条件が満たされるまでステートメント
を繰り返す
for i = first , last , delta do --delta は負の値でも構いません。for ループでカウントダウンまたはカウントアップできます
--statements
--example: print(i)
end
この汎用ループは、標準の反復関数を使用して、次の結果が返されるまでforテーブルを反復処理します。
_Gpairsnil
キーと 値 の ペア( _G ) に対して、 print (キー、値)を実行します
。
ループはネスト(別のループ内に入れる) することもできます。
ローカル グリッド = {
{ 11 , 12 , 13 },
{ 21 , 22 , 23 },
{ 31 , 32 , 33 }
}
y 、row in pairs ( grid ) do x 、value in pairs ( row ) do print ( x 、y 、value ) end end
機能
Lua が関数をファーストクラスの値として扱う方法は、次の例に示されています。この例では、print 関数の動作が変更されています。
do
local oldprint = print
-- 現在の print 関数を oldprint
関数として保存します print ( s )
--[[ print 関数を再定義します。通常の print 関数は
oldprint を通じて引き続き使用できます。新しい関数には引数が 1 つしかありません。]]
oldprint ( s == "foo" and "bar" or s )
end
end
今後の の呼び出しはすべて新しい関数を経由してルーティングされ、Lua のレキシカル スコープprintにより、古い 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 ))
--[[ これは、 'addto(4)' から返された関数を引数 '3' で直接呼び出しているためです。
これは、繰り返し呼び出される場合にデータ コストを削減し、パフォーマンスを向上させるのにも役立ちます。]]
xが呼び出されるたびに変数の新しいクロージャが作成されるaddtoため、返される新しい匿名関数は常に独自のxパラメータにアクセスします。クロージャは、他のオブジェクトと同様に、Lua のガベージ コレクターによって管理されます。
テーブル
テーブルは Lua で最も重要なデータ構造 (そして設計上、唯一の組み込み複合データ型) であり、すべてのユーザー作成型の基礎となります。テーブルは、自動数値キーと特殊な構文が追加された連想配列です。
テーブルはキーとデータのペアのセットであり、データはキーによって参照されます。つまり、ハッシュされた異種の連想配列です。
テーブルはコンストラクター構文を使用して作成されます{}。
a_table = {} -- 新しい空のテーブルを作成します
テーブルは常に参照によって渡されます (共有による呼び出しを参照)。
キー (インデックス) には、関数を含むnil、NaN を除く任意の値を指定できます。
a_table = { x = 10 } -- 1 つのエントリが "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" ]) -- a_table と b_table は両方とも同じテーブルを参照するため、20 も出力されます。
テーブルは、文字列をキーとして構造体(またはレコード)として使用されることが多い。このような使用法は非常に一般的であるため、Luaではそのようなフィールドにアクセスするための特別な構文が採用されている。[11]
point = { x = 10 , y = 20 } -- 新しいテーブルを作成します。
print ( point [ "x" ]) -- 10 を出力します。
print ( point . x ) -- 上記の行とまったく同じ意味になります。読みやすいドット表記は単なる構文上の糖衣です。
関連する関数を格納するテーブルを使用することで、名前空間として機能させることができます。
ポイント = {}
ポイント.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 ;終了
テーブルには自動的に数値キーが割り当てられ、配列データ型として使用できるようになります。最初の自動インデックスは、他の多くのプログラミング言語の場合のように 0 ではなく 1 です (ただし、明示的なインデックス 0 は許可されます)。
数値キーは1文字列キーとは異なります"1"。
array = { "a" , "b" , "c" , "d" } -- インデックスは自動的に割り当てられます。
print ( array [ 2 ]) -- "b" を出力します。Lua の自動インデックスは 1 から始まります。
print ( # array ) -- 4 を出力します。# はテーブルと文字列の長さ演算子です。
array [ 0 ] = "z" -- ゼロは有効なインデックスです。
print ( # array ) -- Lua 配列は 1 から始まるため、やはり 4 を出力します。
テーブルの長さは、が でなくであるようなt任意の整数インデックスとして定義されます。さらに、が である場合、 はゼロになることがあります。1 から指定された までの nil 以外の値を持つ通常の配列の場合、その長さは、最後の値のインデックス とまったく同じです。配列に「穴」がある場合 (つまり、他の nil 以外の値の間に nil 値がある場合)、 は値の直前のインデックスのいずれかになります(つまり、そのような nil 値を配列の末尾と見なすことができます)。[12]nt[n]nilt[n+1]nilt[1]nilnnn#tnil
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 ) } -- ポイントの配列を作成します
-- array = { { x = 10, y = 20 }, { x = 30, y = 40 }, { x = 50, y = 60 } };
print ( array [ 2 ]. y ) -- 40 を出力します
ハッシュマップを使用して配列をエミュレートすると、実際の配列を使用するよりも遅くなるのが普通です。しかし、Luaテーブルはこの問題を回避するために配列として使用できるように最適化されています。[13]
メタテーブル
拡張可能なセマンティクスは 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 })
オブジェクト指向プログラミング
Lua にはクラスの概念が組み込まれていませんが、関数とテーブルを使用してオブジェクト指向プログラミングをエミュレートできます。オブジェクトは、メソッドとフィールドをテーブルに配置することで形成されます。継承(単一および複数) はメタテーブルを使用して実装でき、存在しないメソッドとフィールドを親オブジェクトに委任します。
これらの手法には「クラス」という概念はありません。代わりに、SelfやJavaScriptに似たプロトタイプが使用されます。新しいオブジェクトは、ファクトリ メソッド(新しいオブジェクトを最初から構築する) を使用するか、既存のオブジェクトを複製することによって 作成されます。
基本的なベクターオブジェクトの作成:
ローカル Vector = {}
ローカル VectorMeta = { __index = Vector }
function Vector.new ( x , y , z ) -- コンストラクタreturn setmetatable ( { x = x , y = y , z = z } , VectorMeta ) end
関数 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 . magnification ( vec )) -- メソッドを呼び出す (出力: 1)
print ( vec . x ) -- メンバー変数にアクセスする (出力: 0)
ここで、 は、テーブルに要素が存在しない場合にテーブルsetmetatable内で要素を探すように Lua に指示します。は と同等で、最初にテーブル内で要素を探します。テーブルには要素はありませんが、そのメタテーブルは、テーブル内に要素が見つからない場合に、テーブルに要素の検索を委任します。
Vectorvecvec.magnitudevec["magnitude"]vecmagnitudevecmagnitudeVectormagnitudevec
Lua は、オブジェクト指向を容易にするための構文糖を提供します。プロトタイプ テーブル内でメンバー関数を宣言するには、 を使用します。これは と同等です。クラス メソッドの呼び出しにもコロンが使用されます。はと同等です。
function table:func(args)function table.func(self, args)object:func(args)object.func(object, args)
それを念頭に置いて、構文糖衣を含む対応するクラスを次に示します:。
ローカル Vector = {}
Vector . __index = Vector
function Vector : new ( x , y , z ) -- コンストラクタ
-- 関数定義ではコロンが使用されているため、
-- 最初の引数は "self" であり、これは
"Vector" を参照します
return setmetatable ({ x = x , y = y , z = z }, self )
end
function Vector : magnification () -- 別の方法
-- self を使用して暗黙のオブジェクトを参照する
return math.sqrt ( self . x ^ 2 + self . y ^ 2 + self . z ^ 2 )
end
local vec = Vector : new ( 0 , 1 , 0 ) -- ベクトルを作成する
print ( vec : magnification ()) -- メソッドを呼び出す (出力: 1)
print ( vec . x ) -- メンバー変数にアクセスする (出力: 0)
継承
Luaはメタテーブルを使用してLuaクラスを継承することをサポートしています。[14]この例では、ベクトルの値が派生クラスの定数で乗算されることを許可しています。
ローカル 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 : magnification () -- 別の方法
-- self を使用して暗黙のオブジェクトを参照する
return math.sqrt ( self . x ^ 2 + self . y ^ 2 + self . z ^ 2 )
end
-- クラス継承の例
local VectorMult = {}
VectorMult . __index = VectorMult
setmetatable ( VectorMult , Vector ) -- VectorMult を Vector の子にする
関数 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 : magnification ()) -- メソッドを呼び出します (出力: 1)。
print ( vec . y ) -- メンバー変数にアクセスします (出力: 1)。
vec : multiply ( 2 ) -- ベクトルのすべての要素を 2 で乗算します。
print ( vec . y ) -- メンバーに再度アクセスします (出力: 2)
Luaは多重継承もサポートしており、__index関数またはテーブルのいずれかになります。[15] 演算子のオーバーロードも可能です。Luaのメタテーブルには__add、__subなどの要素を含めることができます。[16]
実装
Lua プログラムはテキスト形式の Lua ファイルから直接解釈されるのではなく、バイトコードにコンパイルされ、その後 Lua仮想マシン(VM) 上で実行されます。コンパイル プロセスは、通常、ユーザーには見えず、実行時に実行されます。特にジャストインタイム コンパイル(JIT) コンパイラが使用されている場合はそうですが、オフラインで実行して読み込みパフォーマンスを向上させたり、コンパイラを省略してホスト環境のメモリ フットプリントを削減したりすることもできます。Lua バイトコードはdump、文字列ライブラリの関数とload/loadstring/loadfile関数を使用して、Lua 内から生成して実行することもできます。Lua バージョン 5.3.4 は、約 24,000 行の C コードで実装されています。[3] [4]
ほとんどのCPUと同様、またほとんどの仮想マシン(スタックベース)とは異なり、Lua VMはレジスタベースであるため、ほとんどのハードウェア設計に近いものとなっています。レジスタアーキテクチャは、値の過剰なコピーを回避し、関数あたりの命令の総数を削減します。Lua 5の仮想マシンは、広く使用されている最初のレジスタベースの純粋なVMの1つです。[17] ParrotとAndroidのDalvikは、他の2つのよく知られたレジスタベースのVMです。PCSchemeのVMもレジスタベースでした。[18]
この例は、上で定義した階乗関数のバイトコードリストです(luac5.1コンパイラによって表示されます):[19]
関数 <factorial.lua:1,7> (9 命令、0x8063c60 の 36 バイト) 1 パラメータ、6 スロット、0 上位値、6 ローカル、2 定数、0 関数 1 [2] ロードK 1 -1; 1 2 [3] ロードK 2 -2; 2 3 [3] 移動 3 0 4 [3] ロードK 4 -1; 1 5 [3] FORPREP 2 1 ; ~ 7 6 [4] マルチ 1 1 5 7 [3] FORLOOP 2 -2 ; 6まで 8 [6] 戻る 1 2 9 [7] リターン 0 1
CAPI について
Luaは他のアプリケーションに組み込むことを目的としており、この目的のためにC APIを提供しています。APIは、LuaコアとLua補助ライブラリの2つの部分に分かれています。[20] Lua APIの設計では、 PythonのAPIとは異なり、Cコードで手動で参照カウント(管理)する必要がありません。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 ); // 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
結果: 8
C API は、Lua スタック内のさまざまな「疑似インデックス」に配置されたいくつかの特別なテーブルも提供します。Lua 5.2 [21]LUA_GLOBALSINDEXより前のバージョンでは、メインの名前空間である Lua 内のグローバル テーブルが にあります。また、C プログラムが後で検索できるように Lua 値を保存できるレジストリも にあります。
_GLUA_REGISTRYINDEX
モジュール
標準ライブラリ (コア) モジュールの他に、Lua API を使用して拡張機能を記述することもできます。拡張モジュールは共有オブジェクトであり、Lua スクリプトにネイティブ機能を提供することで、インタープリタの機能を拡張するために使用できます。Lua スクリプトは、Lua 自体で記述されたモジュールと同様に、[20]requireを使用して拡張モジュールをロードするか、[22]を使用して拡張モジュールをロードできます。C ライブラリが 経由でロードされると、 Lua は 関数を探して呼び出します。これは、Lua から呼び出し可能な任意の C 関数として機能し、通常はメソッドが入ったテーブルを返します。rocksと呼ばれるモジュールのセットは増え続けており、 CPAN、RubyGems 、および Python eggの精神にのっとって、LuaRocks [23]というパッケージ管理システムから入手できます。他のスクリプト言語を含むほとんどの一般的なプログラミング言語用に、事前に記述された Luaバインディングが存在します。 [24] C++ の場合、テンプレートベースのアプローチがいくつかあり、自動バインディングジェネレーターもいくつかあります。
package.loadlibrequire('foo')luaopen_foo
アプリケーション
ビデオゲーム開発では、Luaはスクリプト言語として広く使用されています。これは主に、組み込みの容易さ、実行の高速化、学習曲線の短さが理由です。[25] Luaを使用している有名なゲームには、Roblox、[26] Garry's Mod、World of Warcraft、Payday 2、 Phantasy Star Online 2、Dota 2、Crysis、[27]などがあります。Luaプログラミングやスクリプトをネイティブでサポートしていないゲームの中には、ComputerCraftがMinecraftに対して行っているように、modによってこの機能が追加されているものもあります。また、Luaは、 Adobe Lightroom、Moho、iClone、Aerospike 、 FreeBSDとNetBSDの一部システムソフトウェアなど、ビデオゲーム以外のソフトウェアでも使用されており、 Scribunto拡張機能を使用してMediaWikiのテンプレートスクリプト言語として使用されています。 [28]
2003年にGameDev.netが実施した世論調査では、Luaがゲームプログラミングで最も人気のあるスクリプト言語であることが示されました。[29] 2012年1月12日、Luaは雑誌Game Developerのプログラミングツール部門でFront Line Award 2011を受賞したことが発表されました。 [30]
ゲーム以外の多くのアプリケーションでも、拡張性のために Lua が使用されています。たとえば、 TeX型設定言語の実装であるLuaTeX 、キー値データベースであるRedis 、ワイドカラムストアであるScyllaDB 、テキストエディタであるNeovim、Web サーバであるNginx、ネットワークパケットアナライザである Wireshark などです。
Scribunto拡張機能を通じて、LuaはWikipediaやその他のウィキを実行するMediaWikiソフトウェアのサーバー側スクリプト言語として利用できます。 [31] Luaの用途には、 Wikidataのデータを記事に統合することや、[32]自動化されたタクソボックスシステムの強化などがあります。
派生言語
Lua にコンパイルされる言語
- MoonScriptは、LuaにコンパイルされるCoffeeScriptに触発された、動的で空白文字を区別するスクリプト言語です。つまり、コードのセクションを区切るのにand (またはand )を使用する代わりに、改行とインデントスタイルを使用します。[33] [34] [35] MoonScriptの注目すべき使用例は、ビデオゲーム配信ウェブサイトItch.ioです。
doend{} - Haxe は、 Lua 5.1-5.3、 LuaJIT 2.0、2.1を含むいくつかの Lua ターゲットへのコンパイルをサポートしています。
- FennelはLuaを対象としたLisp方言である。[35]
- UrnはLua上に構築されたLisp方言である。 [36]
- AmuletはMLのような関数型プログラミング言語であり、コンパイラはLuaファイルを出力します。[37]
方言
- LuaJIT、Lua 5.1のジャストインタイムコンパイラ。[38] [39]
- LuauはRoblox Corporationによって開発され、段階的な型付け、追加機能、パフォーマンスに重点を置いたLua 5.1の派生です。 [40]
- Raviは、オプションの静的型付けを備えたJIT対応のLua 5.3言語です。JITは型情報によって制御されます。[41]
- Shineは、モジュールシステムやマクロシステムなど、多くの拡張機能を備えたLuaJITのフォークです。 [42]
- Gluaは、ゲームGarry's Modにスクリプト言語として組み込まれた修正版です。[43]
- Teal は、Lua で記述された静的に型付けされたLua 方言です。
さらに、Luaユーザーコミュニティは、リファレンスC実装の上にいくつかの強力なパッチを提供しています。 [44]
参照
注記
- ^ 構文上の糖衣構文では、識別子の後に続くテーブル構造またはリテラル文字列は有効な関数呼び出しです。[10]
参考文献
- ^ 「[ANN] Lua 5.4.7が利用可能になりました」。2024年6月25日。 2024年6月27日閲覧。
- ^ Ring Team (2017年12月5日). 「Ringプログラミング言語とその他の言語」. ring-lang.net . 2018年12月25日時点のオリジナルよりアーカイブ。2017年12月5日閲覧。
- ^ ab Ierusalimschy, Roberto; de Figueiredo, Luiz Henrique; Filho, Waldemar Celes (1996 年 6 月). 「Lua—拡張可能な拡張言語」.ソフトウェア: 実践と経験. 26 (6): 635–652. doi :10.1002/(SICI)1097-024X(199606)26:6<635::AID-SPE26>3.0.CO;2-P. S2CID 61066194. 2015 年10 月 24 日閲覧。
- ^ abc 「Luaについて」。Lua.org 。 2011年8月11日閲覧。
- ^ Takhteyev, Yuri (2013年4月21日). 「ブラジルからWikipediaへ」. Foreign Affairs . 2013年4月25日閲覧。
- ^ abcd Ierusalimschy, R. ; Figueiredo, LH; Celes, W. (2007). 「Lua の進化」(PDF)。プログラミング言語の歴史に関する第 3 回 ACM SIGPLAN 会議の議事録。pp. 2–1–2–26。doi : 10.1145 / 1238844.1238846。ISBN 978-1-59593-766-7. S2CID 475143。
- ^ 「拡張言語の進化: Lua の歴史」 2001 年. 2008 年12 月 18 日閲覧。
- ^ Figueiredo, LH; Ierusalimschy, R.; Celes, W. (1996 年 12 月)。「Lua: 拡張可能な埋め込み言語。いくつかのメタメカニズムが多数の機能を置き換えます」。Dr. Dobb's Journal。第 21 巻、第 12 号。26 ~ 33 ページ。
- ^ 「Luaでのプログラミング:1」。
- ^ 「Lua 5.0 リファレンスマニュアル、2.5.7、関数呼び出し」。
- ^ 「Lua 5.1 リファレンスマニュアル」 2014年2月27日閲覧。
- ^ 「Lua 5.1 リファレンスマニュアル」 2012年. 2012年10月16日閲覧。
- ^ 「Lua 5.1 ソースコード」 2006年. 2011年3月24日閲覧。
- ^ Roberto Ierusalimschy.プログラミング in Lua、第 4 版。p. 165。
- ^ 「Luaでのプログラミング:16.3」。Lua 。2021年9月16日閲覧。
- ^ 「Metamethods Tutorial」. lua-users wiki . 2021年9月16日時点のオリジナルよりアーカイブ。2021年9月16日閲覧。
- ^ Ierusalimschy, R.; Figueiredo, LH; Celes, W. (2005). 「Lua 5.0 の実装」. J. Of Universal Comp. Sci . 11 (7): 1159–1176. doi : 10.3217/jucs-011-07-1159 .
- ^ Texas Instruments (1990). PC Scheme: ユーザーズガイドおよび言語リファレンスマニュアル、貿易版。MIP Press。ISBN 0-262-70040-9。
- ^ Man, Kein-Hong (2006). 「Lua 5.1 VM 命令のシンプルな入門」(PDF)。
- ^ ab 「Lua 5.2 リファレンスマニュアル」。Lua.org 。 2012年10月23日閲覧。
- ^ エルサリムシイ、ロベルト;デ・フィゲイレード、ルイス・エンリケ。セレス、ワルデマール(2011–2013)。 API の変更。 Lua.org 。2014 年5 月 9 日に取得。
{{cite book}}:|work=無視されました (ヘルプ) - ^ イエルサリムシイ、ロベルト;デ・フィゲイレード、ルイス・エンリケ。セレス、ワルデマール。 「Lua 5.4 リファレンスマニュアル」。ルア。2022 年6 月 1 日に取得。
- ^ "LuaRocks". luarocks.org . 2009年5月24日閲覧。
- ^ 「Binding Code To Lua」。Lua-users wiki。2009年7月27日時点のオリジナルよりアーカイブ。2009年5月24日閲覧。
- ^ 「なぜ Lua はゲーム言語と見なされるのか?」Stack Overflow。 2013 年 8 月 20 日時点のオリジナルよりアーカイブ。2017 年4 月 22 日閲覧。
- ^ 「なぜルアウなのか?」ルアウ。 2022年3月23日閲覧。
- ^ 「Crysis サーバーサイド モッディング入門」 。2022年3 月 23 日閲覧。
- ^ 「Lua 関数」. wow.gamepedia.com . 2021 年3 月 1 日閲覧。
- ^ “世論調査結果”. 2003年12月7日時点のオリジナルよりアーカイブ。2017年4月22日閲覧。
{{cite web}}: CS1 maint: bot: 元の URL ステータス不明 (リンク) - ^ “Front Line Award Winners Announced”. 2013年6月15日時点のオリジナルよりアーカイブ。2017年4月22日閲覧。
- ^ "拡張子:Scribunto - MediaWiki".メディアウィキ.org 。2019 年2 月 21 日に取得。
- ^ "ウィキデータ:情報ボックス チュートリアル - ウィキデータ". www.wikidata.org 。2018 年12 月 21 日に取得。
- ^ 「言語ガイド - MoonScript 0.5.0」。moonscript.org 。 2020年9月25日閲覧。
- ^ leaf (2020年9月23日). 「leafo/moonscript」. GitHub . 2020年9月25日閲覧。
- ^ ab Garzia、Andre Alves。「Lua にコンパイルされる言語」。AndreGarzia.com。2020年9月 25 日閲覧。
- ^ 「Urn: Lua の Lisp 実装 | Urn」urn-lang.com . 2021 年1 月 12 日閲覧。
- ^ “Amulet ML”. amulet.works . 2021年1月12日閲覧。
- ^ 「LuaJIT」。LuaJIT。
- ^ 「拡張機能」。LuaJIT。
- ^ 「なぜ Luau なのか?」Luau 。 2024 年8 月 3 日閲覧。
これらすべてが、私たちが Lua 5.1 から Luau と呼ばれる新しい派生言語を作り直すきっかけとなりました。私たちは、言語のパフォーマンスと機能を向上させ、段階的な型システムを使用したリンティングと型チェックの組み合わせを通じて堅牢なコードを簡単に記述できるようにすることに重点を置いています。
- ^ 「Raviプログラミング言語」。GitHub。
- ^ リチャード・フント (2021 年 4 月 22 日)。 「リチャードフント/シャイン」。GitHub。
- ^ 「Garry's Mod Wiki」. wiki.facepunch.com .
- ^ “Lua Power Patches”. lua-users.org . 2021年5月18日時点のオリジナルよりアーカイブ。2021年5月18日閲覧。
さらに読む
- エルサリムシイ、R. (2013)。 Lua でのプログラミング (第 3 版)。ルア.org。ISBN 978-85-903798-5-0。(第1版はオンラインで入手可能です。)
- Gutschmidt, T. (2003)。Python 、Lua、Ruby によるゲームプログラミング。コーステクノロジーPTR。ISBN 978-1-59200-077-7。
- シュイテマ、P.マニエン、M. (2005)。Lua を使用したゲーム開発。チャールズ・リバー・メディア。ISBN 978-1-58450-404-7。
- Jung, K.; Brown, A. (2007). Lua プログラミング入門. Wrox Press . ISBN 978-0-470-06917-2. 2018年7月8日時点のオリジナルよりアーカイブ。2018年7月7日閲覧。
- Figueiredo, LH; Celes , W.; Ierusalimschy, R. 編 (2008)。Lua プログラミングの宝石。Lua.org。ISBN 978-85-903798-4-3。
- Takhteyev, Yuri (2012)。Coding Places : 南米の都市におけるソフトウェア実践。MIT Press。ISBN 978-0-262-01807-42012年11月2日時点のオリジナルよりアーカイブ。第 6 章と第 7 章は Lua に焦点を当てており、その他の章ではブラジルのソフトウェアをより広く取り上げています。
- Varma, Jayant ( 2012)。iOS ゲーム開発のための Lua を学ぶ。Apress。ISBN 978-1-4302-4662-6。
- Matheson, Ash (2003 年 4 月 29 日). 「Lua 入門」. GameDev.net . 2012 年 12 月 18 日時点のオリジナルよりアーカイブ。2013 年1 月 3 日閲覧。
- Fieldhouse, Keith (2006 年 2 月 16 日)。「Lua の紹介」。ONLamp.com。O'Reilly Media。2006年 3 月 12 日時点のオリジナルよりアーカイブ。2006年2 月 28 日閲覧。
- Streicher, Martin (2006 年 4 月 28 日)。「Lua による埋め込み可能なスクリプト」。developerWorks。IBM。2009年 7 月 2 日時点のオリジナルよりアーカイブ。2018年7月 7日閲覧。
- Quigley, Joseph (2007 年 6 月 1 日)。「Lua の概要」。Linux Journal。
- Hamilton, Naomi (2008年9月11日). 「プログラミング言語AZ: Lua」. Computerworld . IDG . 2018年7月8日時点のオリジナルよりアーカイブ。2018年7月7日閲覧。ロベルト・イェルサリムシー氏へのインタビュー。
- Ierusalimschy, Roberto; de Figueiredo, Luiz Henrique; Celes, Waldemar (2011 年 5 月 12 日)。「言語を針の穴に通す」。ACM Queue . 9 (5): 20–29. doi : 10.1145/1978862.1983083 . S2CID 19484689。Lua の埋め込み可能性が設計にどのような影響を与えたか。
- Ierusalimschy, Roberto; de Figueiredo , Luiz Henrique; Celes , Waldemar (2018 年 11 月)。「Lua の設計の概要」。Communications of the ACM。61 ( 11): 114–123。doi : 10.1145/3186277。S2CID 53114923。[永久リンク切れ]
- Lua の論文と論文
外部リンク
- 公式サイト
- Lua ユーザー 2010 年 12 月 16 日、 Wayback Machineにアーカイブ、コミュニティ
- Lua フォーラムは 2021 年 9 月 28 日にWayback Machineにアーカイブされました
- ルアディス
- Lua Rocks - パッケージ マネージャー
- Lua のプロジェクト
