この初版はLua 5.0向けに書かれています。後のバージョンにも概ね該当しますが、いくつかの違いがあります。
第4版はLua 5.3を対象としており、Amazonや他の書店で入手できます。
本書を購入することで、Luaプロジェクトの支援にもなります。


24.1 – 最初の例

この概要は、アプリケーションプログラムの簡単な例であるスタンドアロンのLuaインタプリタから始めます。原始的なスタンドアロンインタプリタは、次のように記述できます。

警告: このコードはLua 5.0用です。Lua 5.1で実行するには、5つのluaopen_*(L)呼び出しを1つのluaL_openlibs(L)呼び出しに変更する必要があります。

    #include <stdio.h>
    #include <string.h>
    #include <lua.h>
    #include <lauxlib.h>
    #include <lualib.h>
    
    int main (void) {
      char buff[256];
      int error;
      lua_State *L = lua_open();   /* opens Lua */
      luaopen_base(L);             /* opens the basic library */
      luaopen_table(L);            /* opens the table library */
      luaopen_io(L);               /* opens the I/O library */
      luaopen_string(L);           /* opens the string lib. */
      luaopen_math(L);             /* opens the math lib. */
    
      while (fgets(buff, sizeof(buff), stdin) != NULL) {
        error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
                lua_pcall(L, 0, 0, 0);
        if (error) {
          fprintf(stderr, "%s", lua_tostring(L, -1));
          lua_pop(L, 1);  /* pop error message from the stack */
        }
      }
    
      lua_close(L);
      return 0;
    }
ヘッダーファイルlua.hは、Luaによって提供される基本的な関数を定義します。これには、新しいLua環境を作成する関数(lua_openなど)、Lua関数を実行する関数(lua_pcallなど)、Lua環境のグローバル変数を読み書きする関数、Luaから呼び出される新しい関数を登録する関数などが含まれます。 lua.hで定義されているすべてのものには、lua_プレフィックスが付いています。

ヘッダーファイルlauxlib.hは、*補助ライブラリ*(auxlib)によって提供される関数を定義します。すべての定義はluaL_で始まります(例:luaL_loadbuffer)。補助ライブラリは、lua.hによって提供される基本APIを使用して、より高い抽象化レベルを提供します。すべてのLua標準ライブラリはauxlibを使用します。基本APIは経済性と直交性を重視するのに対し、auxlibは一般的なタスクの実用性を重視します。もちろん、プログラムが必要とする他の抽象化を作成することも非常に簡単です。 auxlibはLuaの内部にアクセスできないことに注意してください。すべての作業は公式の基本APIを介して行われます。

Luaライブラリは、グローバル変数をまったく定義していません。すべての状態は動的構造体lua_Stateに保持され、この構造体へのポインタはLua内のすべての関数に引数として渡されます。この実装により、Luaはリエントラントになり、マルチスレッドコードで使用できるようになります。

lua_open関数は、新しい環境(または*状態*)を作成します。 lua_openが新しい環境を作成すると、この環境には定義済みの関数が含まれていません。 printも含まれていません。 Luaを小さく保つために、すべての標準ライブラリは個別の

状態を作成し、標準ライブラリで設定した後、ユーザー入力を解釈します。ユーザーが入力する各行について、プログラムは最初にluaL_loadbufferを呼び出してコードをコンパイルします。エラーがない場合、呼び出しはゼロを返し、結果のチャンクをスタックにプッシュします。(この「魔法の」スタックについては、次のセクションで詳しく説明します。)次に、プログラムはlua_pcallを呼び出します。これは、スタックからチャンクをポップし、保護モードで実行します。 luaL_loadbufferと同様に、lua_pcallはエラーがない場合にゼロを返します。エラーが発生した場合、両方の関数はスタックにエラーメッセージをプッシュします。このメッセージはlua_tostringで取得し、出力後にlua_popでスタックから削除します。

エラーが発生した場合、このプログラムは単に標準エラーストリームにエラーメッセージを出力することに注意してください。実際のエラー処理はCでは非常に複雑になる可能性があり、その方法はアプリケーションの性質によって異なります。 Luaコアは、出力ストリームに何も直接書き込みません。エラーコードとエラーメッセージを返すことでエラーを通知します。各アプリケーションは、ニーズに最も適した方法でこれらのシグナルを処理できます。説明を簡単にするために、ここでは、エラーメッセージを出力し、Luaの状態を閉じ、アプリケーション全体を終了する、次のような単純なエラーハンドラを想定します。

    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    void error (lua_State *L, const char *fmt, ...) {
      va_list argp;
      va_start(argp, fmt);
      vfprintf(stderr, argp);
      va_end(argp);
      lua_close(L);
      exit(EXIT_FAILURE);
    }
後で、アプリケーションコードでのエラー処理について詳しく説明します。

LuaはCコードとC++コードの両方としてコンパイルできるため、lua.hには、他のいくつかのCライブラリに存在するこの典型的な調整コードは含まれていません。

    #ifdef __cplusplus
    extern "C" {
    #endif
       ...
    #ifdef __cplusplus
    }
    #endif
したがって、LuaをCコード(最も一般的なケース)としてコンパイルし、C++で使用している場合は、次のようにlua.hを含める必要があります。
    extern "C" {
    #include <lua.h>
    }
一般的な方法は、上記のコードを含むヘッダーファイルlua.hppを作成し、この新しいファイルをC++プログラムに含めることです。