ルア

ルア
MediaWiki Scribunto拡張機能を使用したWikipedia LuaモジュールのLuaコードのスクリーンショット
パラダイムマルチパラダイム:スクリプト命令型手続き型プロトタイプベースオブジェクト指向)、関数型メタリフレクティブ
デザイン:ロベルト・イエルサリムシ・ワルデマール・セレス・ルイス・エンリケ・デ・フィゲイレド
初登場1993 (1993年
安定版リリース
5.5 [ 1 ] ウィキデータで編集する / 2025年12月22日 (2025年12月22日
タイピングの規律ダイナミック力強いアヒル
実装言語ANSI C
OSクロスプラットフォーム
ライセンスマサチューセッツ工科大学
ファイル名拡張子.lua
Webサイトwww.lua.org
主要な実装
LuaLuaJITLuaVelaMoonSharp
方言
GSL シェルLua u
影響を受けた
C++CLUModulaSchemeSNOBOL
影響を受けた
GameMonkeyIoJavaScriptJuliaRedRing[ 2 ] 、 RubySquirrelC--Luau

Lua / ˈ l ə / LOO ;ポルトガル語:lua [ˈlu(w)ɐ](月の意味)は、主にアプリケーションへの組み込み向けに設計された軽量高水準のマルチパラダイムプログラミング言語です。[ 3 ] Luaはクロスプラットフォームソフトウェアであり、コンパイルされたバイトコードインタープリタはANSI Cで書かれています。[ 4 ]また、Luaにはアプリケーションに組み込むための比較的シンプルなCアプリケーションプログラミングインターフェイス(API)があります。[ 5 ]

Luaは1993年、当時高まるカスタマイズ需要に応えるため、ソフトウェアアプリケーションを拡張するための言語として誕生しました。Luaはほとんどの手続き型プログラミング言語の基本的な機能を備えていましたが、より複雑な機能やドメイン固有の機能は含まれていませんでした。その代わりに、言語を拡張するためのメカニズムを備えており、プログラマーがそのような機能を実装できるようにしていました。Luaは汎用的な組み込み拡張言語となることを目指していたため、設計者は開発における速度移植性、拡張性、そして使いやすさの向上に重点を置きました。

歴史

Lua は、1993 年にブラジルリオデジャネイロ・ポンティフィカル・カトリック大学のコンピュータ グラフィックス テクノロジー グループ ( Tecgraf )のメンバーであるRoberto Ierusalimschy 、Luiz Henrique de Figueiredo、Waldemar Celesによって作成されました。

1977年から1992年まで、ブラジルはコンピュータのハードウェアソフトウェアに対して強力な貿易障壁(市場留保政策)を敷いていました。これは、ブラジルが自国でハードウェアとソフトウェアを生産できる、そして生産すべきだと信じていたためです。このような状況下では、Tecgrafの顧客は政治的にも財政的にも、海外からカスタマイズされたソフトウェアを購入する余裕がありませんでした。市場留保政策の下では、顧客はブラジル企業ではニーズを満たせないことを証明するために、複雑な官僚的な手続きを経なければなりませんでした。こうした理由から、Tecgrafは必要な基本ツールをゼロから実装することにしました。[ 6 ]

Luaの前身は、データ記述言語と設定言語であるシンプルオブジェクト言語(SOL)とデータエントリ言語(DEL)でした。[ 7 ]これらは、1992年から1993年にかけてTecgrafで独立して開発され、2つの異なるプロジェクト(どちらもペトロブラス社のエンジニアリングアプリケーション用のインタラクティブグラフィカルプログラム)に柔軟性を追加するものでした。SOLとDELにはフロー制御構造が欠如しており、ペトロブラスはこれらに完全なプログラミング機能を追加する必要性が高まっていると感じていました。

Luaの進化の中で、この言語の作者は次のように書いている: [ 6 ]

1993 年、唯一の真の競合相手は、アプリケーションに組み込むことを明確に目的として設計された Tcl でしたしかし、Tcl は構文がわかりにくく、データ記述のサポートが不十分で、Unix プラットフォームでしか実行できませんでした。LISP や Scheme は構文が使いにくいため、検討対象とはしませんでした。Pythonまだ初期段階でした。当時 Tecgraf には自由で DIY の雰囲気が広がっていたため、独自のスクリプト言語を開発しようとするのはごく自然なことでした... この言語の潜在的なユーザーの多くはプロのプログラマーではなかったので、この言語では難解な構文やセマンティクスを避ける必要がありました。Tecgraf のクライアントは多種多様なコンピューター プラットフォームを使用していたため、新しい言語の実装は移植性が高くなければなりませんでした。最後に、他の Tecgraf 製品にもスクリプト言語を組み込む必要があると予想されたため、新しい言語は SOL の例に倣い、C API 付きのライブラリとして提供される必要がありました。

Lua 1.0は、オブジェクトコンストラクタが当時の軽量で柔軟なスタイルとは若干異なっており、SOLのデータ記述構文を取り入れた設計でした(Luaという名前は、ポルトガル語でSolが「太陽」、Luaが「月」を意味することに由来しています)。制御構造のLua構文は、主にModulaif、、while/ )から借用しましたが、CLU(関数呼び出しからの多重代入と多重戻り。参照パラメータや明示的なポインタのよりシンプルな代替手段)、C++(「必要な場所にのみローカル変数を宣言できるという優れたアイデア」 [ 6 ])、SNOBOLAWK連想配列)の影響も受けています。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は、特定のプログラミングパラダイムに特化した機能セットを提供するのではなく、必要に応じて拡張可能なシンプルで柔軟なメタ機能を提供することを目指しています。その結果、ベース言語は軽量化され、完全なリファレンスインタプリタはコンパイル後わずか約247KB [4] で 幅広いアプリケーション容易に適応できます。

拡張言語またはスクリプト言語としての使用を目的とした動的型付け言語であるLuaは、様々なホストプラットフォームに適合するほどコンパクトです。ブール値、数値(デフォルトでは倍精度浮動小数点数64ビット整数)、文字列といった、ごく少数のアトミックデータ構造のみをサポートしています。配列セットリスト、レコードといった一般的なデータ構造は、Luaの単一のネイティブデータ構造であるテーブルで表現できます。テーブルは、本質的には異種連想配列です。

Lua は、ファーストクラス関数ガベージコレクションクロージャ、適切な末尾呼び出し強制変換 (実行時に文字列と数値を自動的に変換する)、コルーチン(協調型マルチタスク)、動的モジュール読み込みなどの高度な機能の小さなセットを実装しています。

構文

古典的な「Hello, World!」プログラムは、括弧の有無にかかわらず次のように記述できます。[ 9 ] [ a ]

印刷( "Hello, World!" )
「Hello, World!」と印刷します。

値のない変数の宣言。

ローカル変数

値が 10 である変数の宣言。

地元の学生= 10

Lua のコメントは、 AdaEiffelHaskellSQLVHDLと同様に、二重ハイフンで始まり、行末まで続きます。複数行の文字列とコメントは、二重角括弧で囲まれます。

-- 単一行コメント--[[複数行コメント--]]

この例では階乗関数が実装されてい ます

関数階乗( n )ローカルx = 1 i = 2 , n の場合x = x * iを実行end return x end

制御フロー

Lua には、オプションと実行制御構造 を持つ1 種類の条件テストがあります。if then endelseelseif then

汎用if then endステートメントには、次の 3 つのキーワードすべてが必要です。

if条件then --文本体終了

if声明 の例

x ~= 10の場合print ( x )を出力します。

条件が次のように評価された場合に実行を制御するために、キーワードelseに付随するステートメント ブロックを追加することができます。 iffalse

if条件then --文本体else --文本体end

if else声明 の例

x == 10場合print ( 10 )、そうでない場合はprint ( x )、終了

次のキーワードを使用して、複数の条件に応じて実行を制御することもできますelseif then

if条件then --文本体elseif条件then --文本体else --オプション--オプション デフォルト文本体end

if elseif else声明 の例

x == yの場合print ( "x = y" ) elseif x == zの場合print ( "x = z" ) else -- オプションprint ( "x は他のどの変数とも等しくありません" ) 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 } }for y , row in pairs ( grid ) do for 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を通して引き続き使用できる。新しいprint関数は引数を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 = {} -- 新しい空のテーブルを作成します

テーブルは常に参照によって渡されます (共有による呼び出しを参照)。

キー (インデックス) には、関数を含め、 NaN をnil除く任意の値を指定できます。

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 } endPoint .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" -- 0 は有効なインデックスです。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にはクラスの概念が組み込まれていませんが、関数とテーブルを用いることでオブジェクト指向プログラミングをエミュレートできます。オブジェクトは、メソッドとフィールドをテーブルに格納することで形成されます。継承(単一継承と多重継承の両方)はメタテーブルを用いて実装でき、存在しないメソッドとフィールドを親オブジェクトに委譲することができます。

これらの手法には「クラス」という概念はなく、SelfJavaScriptと同様にプロトタイプが使用されます。新しいオブジェクトは、ファクトリーメソッド(新しいオブジェクトをゼロから構築するメソッド)または既存のオブジェクトのクローンによって作成されます。

基本的なベクターオブジェクトの作成:

ローカルVector = {}ローカルVectorMeta = { __index = Vector }function Vector.new ( x , y , z ) -- コンストラクタreturn setmetatable ( { x = x , y = y , z = z } , VectorMeta ) endfunction Vector.magnitude ( self ) --方法return math.sqrt ( self.x ^ 2 + self.y ^ 2 + self.z ^ 2 ) endlocal vec = Vector . new ( 0 , 1 , 0 ) -- ベクトルを作成するprint ( vec . magnification ( vec )) -- メソッドを呼び出す (出力: 1) print ( vec . x ) -- メンバー変数にアクセスする (出力: 0)

ここで、 は、 Lua に、要素がテーブルに存在しない場合にテーブルsetmetatable内を検索するように指示します。は と同等であり、まずテーブル内で要素を検索します。テーブルには要素がありませんが、そのメタテーブルは、要素がテーブルに見つからない場合、テーブルに要素の検索を委譲します。 Vectorvecvec.magnitudevec["magnitude"]vecmagnitudevecmagnitudeVectormagnitudevec

Luaはオブジェクト指向を容易にするための糖衣構文を提供しています。プロトタイプテーブル内でメンバー関数を宣言するには、 を使用します。これは と同等です。クラスメソッドの呼び出しにもコロンを使用します。は と同等です。 functiontable:func(args)functiontable.func(self,args)object:func(args)object.func(object,args)

:それを念頭に置いて、構文糖衣 を含む対応するクラスを次に示します。

ローカルベクトル= {}ベクトル. __index =ベクトルfunction Vector : new ( x , y , z ) -- コンストラクタ-- 関数定義ではコロンが使用されているため、-- 最初の引数は "self" で、これは"Vector" を参照します。 return setmetatable ({ x = x , y = y , z = z }, self ) endfunction Vector : magnitude () -- 別の方法-- self を使用して暗黙のオブジェクトを参照するreturn math.sqrt ( self . x ^ 2 + self . y ^ 2 + self . z ^ 2 ) endlocal vec = Vector : new ( 0 , 1 , 0 ) -- ベクトルを作成するprint ( vec : magnitude ()) -- メソッドを呼び出す (出力: 1) print ( vec . x ) -- メンバー変数にアクセスする (出力: 0)

継承

メタテーブルを使うとLuaのクラス継承の動作を模倣することができます。[ 14 ]この例では、派生クラスでベクトルの値を定数で乗算できるようにします。

ローカルベクトル= {}ベクトル. __index =ベクトルfunction Vector : new ( x , y , z ) -- コンストラクタ-- ここで、self は呼び出されるクラスの "new" メソッドを指します。派生クラスでは、self は派生クラスになります。Vector クラスでは、selfは Vector になります。 return setmetatable ({ x = x , y = y , z = z }, self ) endfunction 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 の子にする関数VectorMult : multiply ( value ) self.x = self.x * value self.y = self.y * value self.z = self.z * value return self endlocal vec = VectorMult : new ( 0 , 1 , 0 ) -- ベクトルを作成します。print ( vec : magnitude ()) -- メソッドを呼び出します (出力: 1) print ( vec . y ) -- メンバー変数にアクセスします (出力: 1) vec : multiply ( 2 ) -- ベクトルのすべての要素を 2 で乗算します。print ( vec . y ) -- メンバーに再度アクセスします (出力: 2)

多重継承を実装することも可能です。__index関数またはテーブルのいずれかになります。[ 15 ]演算子のオーバーロードも可能です。Luaのメタテーブルには__add、、などの要素を含めることができます__sub[ 16 ]

実装

Luaプログラムはテキスト形式のLuaファイルから直接解釈されるのではなく、バイトコードにコンパイルされ、Lua仮想マシン(VM)上で実行されます。このコンパイルプロセスは通常、ユーザーには見えず、実行時に実行されます。特にJIT( Just-In-Time Compilation)コンパイラを使用する場合は顕著ですが、オフラインで実行することで読み込みパフォーマンスを向上させたり、コンパイラを介さずにホスト環境のメモリ使用量を削減したりすることも可能です。Luaバイトコードは、dump文字列ライブラリの関数とload/loadstring/loadfile関数を使用して、Lua内部から生成・実行することもできます。Luaバージョン5.3.4は、約24,000行のCコードで実装されています。[ 3 ] [ 4 ]

ほとんどのCPUと同様に、またスタックベースの仮想マシンとは異なり、Lua VMはレジスタベースであるため、ほとんどのハードウェア設計に近いものとなっています。レジスタアーキテクチャは、値の過剰なコピーを回避し、関数あたりの命令の総数を削減します。Lua 5の仮想マシンは、広く普及した最初のレジスタベースの純粋なVMの1つです。[ 17 ] ParrotAndroidDalvikは、他によく知られているレジスタベースのVMです。PCSchemeのVM​​もレジスタベースでした。[ 18 ]

この例は、上で定義した階乗関数のバイトコードリストです(5.1コンパイラによって表示されますluac)。[ 19 ]

関数 <factorial.lua:1,7> (9命令、0x8063c60の36バイト) 1 個のパラメータ、6 個のスロット、0 個のアップ値、6 個のローカル変数、2 個の定数、0 個の関数 1 [2] ロード 1 -1 ; 1 2 [3] ロードK 2 -2 ; 2 3 [3] 移動 3 0 4 [3] ロードク 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 

C API

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 LUA_GLOBALSINDEX5.2 [ 21 ]より前のバージョンでは、Lua内部のグローバルテーブルが_Gメインの名前空間として存在していました。また、Cプログラムが後で取得するためにLuaの値を保存できるレジストリも存在しますLUA_REGISTRYINDEX

モジュール

標準ライブラリ (コア) モジュールの他に、Lua API を使用して拡張機能を記述することも可能です。拡張モジュールは共有オブジェクトであり、Lua スクリプトにネイティブ機能を提供することでインタープリタの機能を拡張するために使用できます。Lua スクリプトは、Lua 自身で記述されたモジュールと同様に、 [ 20 ] を使用して拡張モジュールをロードすることもrequire[ 22 ]使用て拡張モジュールをロードすることもできますpackage.loadlib。Cライブラリが 経由でロードされると、Luaは 関数を探して呼び出します。この関数は、Lua から呼び出し可能な任意の C 関数として動作し、通常はメソッドが入ったテーブルを返します。rocks と呼ばれるモジュールのセットは増え続けており、CPANRubyGemsPython eggsの精神にのっとり、 LuaRocksというパッケージ管理システムを通じて利用できます[ 23 ]他のスクリプト言語含む、ほとんどの一般的なプログラミング言語用に、事前に記述された Luaバインディングが存在します。 require('foo')luaopen_foo

アプリケーション

ビデオゲーム開発において、Luaはスクリプト言語として広く使用されている。これは主に、組み込みの容易さ、実行の高速さ、学習曲線の短さなどが理由である。[ 25 ] Luaを使用している有名なゲームには、Roblox[ 26 ] Garry's ModWorld of WarcraftPayday 2Project ZomboidPhantasy Star Online 2Dota 2Crysis[ 27 ]などがある。Luaプログラミングやスクリプトをネイティブでサポートしていないゲームでは、ComputerCraftがMinecraftに対して行っているように、modによってこの機能が追加されている。同様に、DiscordiaなどのLua APIライブラリは、Luaをネイティブでサポートしていないプラットフォームで使用されている。[ 28 ] Luaはオープンソースの2次元ゲームエンジンLÖVEで使用されている。[ 29 ]また、LuaはAdobe LightroomMohoiCloneAerospikeなどのビデオゲーム以外のソフトウェアや、FreeBSDNetBSDの一部のシステムソフトウェアでも使用されており、Scribunto拡張機能を使用してMediaWikiのテンプレートスクリプト言語としても使用されています。[ 30 ]

2003年にGameDev.netが実施した世論調査では、Luaがゲームプログラミングで最も人気のあるスクリプト言語であることが示されました。[ 31 ] 2012年1月12日、Luaは雑誌Game Developerのプログラミングツール部門でFront Line Award 2011を受賞したことが発表されました。[ 32 ]

ゲーム以外の多くのアプリケーションでも、拡張性のために Lua が使用されています。たとえば、 TeX型設定言語の実装であるLuaTeX 、キー値データベースRedisワイドカラムストアのScyllaDB テキストエディタのNeovimWeb サーバのNginx、ネットワーク パケット アナライザのWireshark 、 Discord API ライブラリのDiscordia 、ビジュアル オーディオ プログラミング言語のPure Data (pdlua 拡張機能経由) などです。

派生言語

Luaにコンパイルされる言語

方言

  • LuaJIT、Lua 5.1のジャストインタイムコンパイラ。[ 39 ] [ 40 ]
  • Roblox Corporationによって開発されたLuauは、段階的な型付け、追加機能、パフォーマンスに重点を置いた、Lua 5.1 の派生であり、下位互換性があります。 [ 41 ] Luau ではサンドボックスが改良され、組み込みアプリケーションで信頼できないコードを実行できるようになりました。[ 42 ]
  • Raviは、オプションの静的型付けを備えたJIT対応のLua 5.3言語です。JITは型情報によって制御されます。[ 43 ]
  • Shineは、モジュールシステムやマクロシステムなど、多くの拡張機能を備えたLuaJITのフォークです。 [ 44 ]
  • Gluaは、ゲームGarry's Modのスクリプト言語として組み込まれた改良版である。[ 45 ]
  • TealはLuaで書かれた静的型付けLua方言である。 [ 46 ]
  • 「ファンタジー ビデオ ゲーム コンソール」であるPICO-8は、PICO-8 Lua と呼ばれる Lua のサブセットを使用します。
  • PlutoはLua 5.4のスーパーセットであり、強化された構文、ライブラリ、優れた開発者エクスペリエンスを提供しながら、通常のLuaとの互換性を維持しています。[ 47 ]

さらに、Luaユーザーコミュニティは、リファレンスC実装の上にいくつかの強力なパッチを提供しています。 [ 48 ]

参照

注記

  1. ^構文糖衣、識別子に続くテーブル構造またはリテラル文字列は有効な関数呼び出しです。 [ 10 ]

参考文献

  1. ^ https://lua.org/versions.html#5.5{{cite web}}:欠落または空|title=(ヘルプ)
  2. ^ Ring Team (2017年12月5日). 「Ringプログラミング言語とその他の言語」 . ring-lang.net . 2018年12月25日時点のオリジナルよりアーカイブ2017年12月5日閲覧。
  3. ^ a bイエルサリムシイ、ロベルト;デ・フィゲイレード、ルイス・エンリケ。フィーリョ、ワルデマール・セレス(1996 年 6 月)。「Lua—拡張可能な拡張言語」ソフトウェア: 実践と経験26 (6): 635–652 .土井: 10.1002/(SICI)1097-024X(199606)26:6<635::AID-SPE26>3.0.CO;2-PS2CID 61066194 2015 年10 月 24 日に取得 
  4. ^ a b c「Luaについて」 . Lua.org . 2011年8月11日閲覧
  5. ^タクチェエフ、ユーリ (2013 年 4 月 21 日)。「ブラジルからウィキペディアへ」外交問題2013 年4 月 25 日に取得
  6. ^ a b c d 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 .
  7. ^ 「拡張言語の進化:Luaの歴史」 2001年。 2008年12月18日閲覧
  8. ^フィゲイレード、LH;エルサリムシイ、R.セレス、W. (1996 年 12 月)。「Lua: 拡張可能な組み込み言語。いくつかのメタメカニズムが多数の機能を置き換えます。 」ドブ博士の日記。 Vol. 21、いいえ。 12.  26 ~ 33 ページ。
  9. ^ 「Luaでのプログラミング:1」
  10. ^ 「Lua 5.0リファレンスマニュアル、2.5.7、関数呼び出し」
  11. ^ 「Lua 5.1 リファレンスマニュアル」 . 2014年. 2014年2月27日閲覧
  12. ^ 「Lua 5.1 リファレンスマニュアル」 . 2012年. 2012年10月16日閲覧
  13. ^ 「Lua 5.1 ソースコード」 2006年. 2011年3月24日閲覧
  14. ^ロベルト・イエルサリムシィ。Lua でのプログラミング、第 4 版。 p. 165.
  15. ^ 「Luaでのプログラミング:16.3」。Lua 2021年9月16日閲覧
  16. ^ 「メタメソッドチュートリアル」 . lua-users wiki . 2021年9月16日時点のオリジナルよりアーカイブ。 2021年9月16日閲覧
  17. ^ 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 .
  18. ^ Texas Instruments (1990). PC Scheme: ユーザーズガイドおよび言語リファレンスマニュアル、トレード版. MIP Press. ISBN 0-262-70040-9
  19. ^ Man, Kein-Hong (2006). 「Lua 5.1 VM命令のシンプルな入門」(PDF) .
  20. ^ a b「Lua 5.2リファレンスマニュアル」 . Lua.org . 2012年10月23日閲覧
  21. ^イエルサリムシイ、ロベルト;デ・フィゲイレード、ルイス・エンリケ。セレス、ワルデマール (2011–2013)。API の変更。 Lua.org 2014 年5 月 9 日に取得{{cite book}}:|work=無視されました (ヘルプ)
  22. ^エルサリムシイ、ロベルト;デ・フィゲイレード、ルイス・エンリケ。セレス、ワルデマール。「Lua 5.4 リファレンスマニュアル」ルア2022 年6 月 1 日に取得
  23. ^ "LuaRocks" . luarocks.org . 2009年5月24日閲覧
  24. ^ 「Binding Code To Lua」 . Lua-users wiki. 2009年7月27日時点のオリジナルよりアーカイブ。 2009年5月24日閲覧
  25. ^ 「なぜLuaはゲーム言語と見なされているのか?」Stack Overflow2013年8月20日時点のオリジナルよりアーカイブ。 2017年4月22日閲覧
  26. ^ 「なぜルアウのか?」ルアウ2022年3月23日閲覧
  27. ^ 「Crysis サーバーサイドモッディング入門」2022年3月23日閲覧。
  28. ^ 「Discordia API」 . GitHub . 2025年7月2日閲覧
  29. ^ “LOVE2Dゲームエンジン” . 2025年3月5日時点のオリジナルよりアーカイブ2025年7月2日閲覧。
  30. ^ 「Lua関数」 . wow.gamepedia.com . 2021年3月1日閲覧
  31. ^ “Poll Results” . 2003年12月7日時点のオリジナルよりアーカイブ2017年4月22日閲覧。{{cite web}}: CS1 maint: bot: 元のURLステータス不明(リンク
  32. ^ “Front Line Award Winners Announced” . 2013年6月15日時点のオリジナルよりアーカイブ2017年4月22日閲覧。
  33. ^ 「言語ガイド - MoonScript 0.5.0」 . moonscript.org . 2020年9月25日閲覧
  34. ^ leaf (2020年9月23日). 「leafo/moonscript」 . GitHub . 2020年9月25日閲覧
  35. ^ a bガルツィア、アンドレ・アウベス。「Lua にコンパイルされる言語」アンドレガルツィア.com 2020 年9 月 25 日に取得
  36. ^ 「Urn: LuaのLisp実装 | Urn」urn-lang.com . 2021年1月12日閲覧
  37. ^ 「Amulet ML」 . amulet.works . 2021年1月12日閲覧
  38. ^ 「LunarML、Lua/JavaScriptを生成する標準MLコンパイラ」。GitHub
  39. ^ "LuaJIT" . LuaJIT .
  40. ^ 「拡張機能」 . LuaJIT .
  41. ^ 「なぜLuauなのか?」 . Luau . 2024年8月3日閲覧これらすべてが、私たちがLua 5.1をベースに、Luauと呼ぶ新しい派生言語へと作り直すきっかけとなりました。私たちは、言語のパフォーマンスと機能を向上させ、リンティングと漸進的型システムを用いた型チェックを組み合わせることで、堅牢なコードを容易に記述できるようにすることに重点を置いています。
  42. ^ 「サンドボックス化」 . Luau . 2025年3月27日閲覧
  43. ^Raviプログラミング言語」。GitHub
  44. ^リチャード・フント (2021 年 4 月 22 日)。「リチャードフント/シャイン」 . GitHub
  45. ^ 「Garry's Mod Wiki」 . wiki.facepunch.com .
  46. ^ "teal-language/tl" . Teal language . 2024年12月23日. 2024年12月23日閲覧
  47. ^ 「冥王星とは何か?」冥王星. 2025年6月27日閲覧
  48. ^ “Lua Power Patches” . lua-users.org . 2021年5月18日時点のオリジナルよりアーカイブ2021年5月18日閲覧。

さらに読む