2009-06-25 6 views
2

Ich muss Operationen auf Lua-Tabellen von C ausführen, wo die Tabellen als Listen oder Warteschlangen behandelt werden. Insbesondere muss ich ein Element am Kopf einfügen und das Kopfelement entfernen und die anderen Elemente verschieben, um das neue Element aufzunehmen.Wie lua Tabelle Operationen von C zu tun?

Dies wäre einfach in gerade lua, würde ich table.insert und table.remove verwenden. Aber in C?

Es sind Funktionen in der Lua C api wie lua_settable, aber keine Mittel für table.insert und table.remove die taucht sind. Es sieht so aus, als ob interne C Funktionen innerhalb des Interpreters tinsert und tremove sind, aber sie sind nicht Teil der API.

Muss ich wirklich zu einer Lua-Funktion rufen, die das für mich tut?

Antwort

4

Ich glaube, Sie die Funktionen wiederverwenden können

static int tinsert (lua_State *L) 
static int tremove (lua_State *L) 

und das Makro

#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) 

, die in der ltablib.c sind. Sie hängen nur von Lua's API ab.

+0

danke. Aber wenn ich aus meinem Code tinsert versuchte, scheitert es, weil der Rückgabewert von lua_gettop nicht das ist, was er erwartet. Es gibt bereits einige Werte auf dem Stapel, also gibt lua_gettop etwa 24 zurück, und diese Funktion erwartet, dass es die Anzahl der übergebenen Argumente ist, wie 2 oder 3. –

+0

Schieben Sie zum Beispiel Position und Wert im Stapel vor rufst du tinsert an? –

+0

yeah, die Funktion kann aus verschiedenen Kontexten aufgerufen werden, in denen der Stapel bereits verschiedene Mengen an Material enthält. Also fügte ich meiner Version von tinsert eine zusätzliche Variable für den Stapeloffset hinzu und machte die Interna meines Tiltserts mit diesem Offset. Jetzt funktioniert es. Vielen Dank. –

1

Code nicht getestet, aber hier ist eine Skizze. Sie übergeben den Index der Tabelle und für die Einfügefunktion auch den Index des Werts, den Sie einfügen möchten. Zum Entfernen wird der Wert auf den Lua-Stack geschoben.

#define getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) 

void insert_at_head (lua_State *L, int tbl_idx, int val_idx) { 
    int e; 
    /* shift elements right to make room */ 
    for (e = getn(L, tbl_idx) + 1; e > 1; e--) { 
    lua_rawgeti(L, tbl_idx, e-1); 
    lua_rawseti(L, tbl_idx, e); 
    } 
    lua_pushvalue(L, val_idx); 
    lua_rawseti(L, tbl_idx, 1); 
} 

void remove_from_head_and_push (lua_State *L, int tbl_idx) { 
    int e; 
    int n = getn(L, tbl_idx); 
    if (n == 0) 
    return luaL_error("removed from head of empty list"); 
    lua_rawgeti(L, tbl_idx, 1); /* push first element */ 
    /* shift elements left */ 
    for (e = 2; e < n; e++) 
    lua_rawgeti(L, tbl_idx, e); 
    lua_rawseti(L, tbl_idx, e-1); 
    } 
    lua_pushnil(L, val_idx); 
    lua_rawseti(L, tbl_idx, n); 
} 
+0

das ist ein schöner sauberer Code :) –