この第 1 版は、Lua 5.0 用に執筆されました。後続のバージョンにも大部分が関係していますが、いくつかの違いがあります。
第 4 版は、Lua 5.3 をターゲットに執筆され、Amazon や他の書店で購入できます。
この本を購入することで、Lua プロジェクトを支援することにもなります。


24.2.3 – その他のスタック操作

C とスタックとの間で値を交換する上記の関数に加えて、API はジェネリックなスタック操作のための以下の操作も提供します

    int   lua_gettop (lua_State *L);
    void  lua_settop (lua_State *L, int index);
    void  lua_pushvalue (lua_State *L, int index);
    void  lua_remove (lua_State *L, int index);
    void  lua_insert (lua_State *L, int index);
    void  lua_replace (lua_State *L, int index);
lua_gettop 関数は、スタック内のエレメントの数を返します。これはトップエレメントのインデックスでもあります。負のインデックス -x は、正のインデックス gettop - x + 1 と同等であることに注意してください。

lua_settop は、トップ (つまりスタック内のエレメントの数) を特定の値に設定します。以前のトップが新しいトップよりも高かった場合、トップの値は破棄されます。そうでない場合、この関数は、スタック上の nil のプッシュを行い、指定されたサイズを得ます。特定の場合、lua_settop(L, 0) はスタックを空にします。負のインデックスを lua_settop と共に使用することもできます。これにより、トップエレメントが指定されたインデックスに設定されます。この機能を使用すると、API は、スタックから n 個のエレメントをポップする次のマクロを提供します

    #define lua_pop(L,n)  lua_settop(L, -(n)-1)

lua_pushvalue 関数は、指定されたインデックスのエレメントのコピーをスタックのトップにプッシュします。lua_remove は、指定されたインデックスのエレメントを削除し、その位置より上のすべてのエレメントを下にずらしてギャップを埋めます。lua_insert は、トップエレメントを指定された位置に移動し、その位置より上のすべてのエレメントを上にずらしてスペースを作成します。最後に、lua_replace は、トップから値をポップし、何も移動せずに、それを指定されたインデックスの値として設定します。次の操作は、スタックに対して効果がないことに注意してください

    lua_settop(L, -1);  /* set top to its current value */
    lua_insert(L, -1);  /* move top element to the top */

これらの関数の使用を説明するために、スタックのすべてのコンテンツをダンプする便利なヘルパー関数を次に示します

    static void stackDump (lua_State *L) {
      int i;
      int top = lua_gettop(L);
      for (i = 1; i <= top; i++) {  /* repeat for each level */
        int t = lua_type(L, i);
        switch (t) {
    
          case LUA_TSTRING:  /* strings */
            printf("`%s'", lua_tostring(L, i));
            break;
    
          case LUA_TBOOLEAN:  /* booleans */
            printf(lua_toboolean(L, i) ? "true" : "false");
            break;
    
          case LUA_TNUMBER:  /* numbers */
            printf("%g", lua_tonumber(L, i));
            break;
    
          default:  /* other values */
            printf("%s", lua_typename(L, t));
            break;
    
        }
        printf("  ");  /* put a separator */
      }
      printf("\n");  /* end the listing */
    }
この関数は、スタックを下から上に走査し、各エレメントをタイプに応じて出力します。文字列は引用符で囲んで出力し、数値には `%g´ 形式を使用します。他の値 (テーブル、関数など) には、そのタイプのみが出力されます (lua_typename は、タイプコードをタイプ名に変換します)。

次のプログラムは、API スタックの操作をさらに説明するために stackDump を使用します

    #include <stdio.h>
    #include <lua.h>
    
    static void stackDump (lua_State *L) {
      ...
    }
    
    int main (void) {
      lua_State *L = lua_open();
      lua_pushboolean(L, 1); lua_pushnumber(L, 10);
      lua_pushnil(L); lua_pushstring(L, "hello");
      stackDump(L);
                       /* true  10  nil  `hello'  */
    
      lua_pushvalue(L, -4); stackDump(L);
                       /* true  10  nil  `hello'  true  */
    
      lua_replace(L, 3); stackDump(L);
                       /* true  10  true  `hello'  */
    
      lua_settop(L, 6); stackDump(L);
                       /* true  10  true  `hello'  nil  nil  */
    
      lua_remove(L, -3); stackDump(L);
                       /* true  10  true  nil  nil  */
    
      lua_settop(L, -5); stackDump(L);
                       /* true  */
    
      lua_close(L);
      return 0;
    }