3.3 - 堆栈操作
Lua提供了如下的基础堆栈操作API:
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_settop用于把堆栈的栈顶索引设置为指定的数值,它可以接受所有可接受索引。如果新的栈顶索引比原来的大,则新的位置用nil填充。如果index为0,则将删除堆栈中的所有元素。在lua.h中定义了如下一个宏:
#define lua_pop(L,n) lua_settop(L,-(n)-1)
用以把堆栈上部的n个元素删除。
lua_pushvalue压入一个元素的值拷贝到指定的索引处,相反地,lua_remove删除给定索引的元素,并将之一索引之上的元素来填补空缺。同样地,lua_insert在上移给定索引之上的所有元素后再在指定位置插入新元素。Lua_replace将栈顶元素压入指定位置而不移动任何元素(因此指定位置的元素的值被替换)。这些函数都仅接受有效索引(你不应当使用假索引调用lua_remove或lua_insert,因为它不能解析为一个堆栈位置)。下面是一个例子,栈的初始状态为10 20 30 40 50 *(从栈底到栈顶,“*”标识为栈顶,有:
lua_pushvalue(L, 3) --> 10 20 30 40 50 30*
lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30*
lua_remove(L, -3) --> 10 20 30 40 30 30*
lua_remove(L, 6) --> 10 20 30 40 30*
lua_insert(L, 1) --> 30 10 20 30 40*
lua_insert(L, -1) --> 30 10 20 30 40* (没影响)
lua_replace(L, 2) --> 30 40 20 30*
lua_settop(L, -3) --> 30 40*
lua_settop(L, 6) --> 30 40 nil nil nil nil*
3.4 - 堆栈查询
检测堆栈元素的数据类型可以使用如下函数:
int lua_type (lua_State *L, int index);
int lua_isnil (lua_State *L, int index);
int lua_isboolean (lua_State *L, int index);
int lua_isnumber (lua_State *L, int index);
int lua_isstring (lua_State *L, int index);
int lua_istable (lua_State *L, int index);
int lua_isfunction (lua_State *L, int index);
int lua_iscfunction (lua_State *L, int index);
int lua_isuserdata (lua_State *L, int index);
int lua_islightuserdata (lua_State *L, int index);
这些函数可用任意可打接受索引为参数。
lua_type返回堆栈元素的值类型,当使用无效索引时返回LUA_TNONE(如当堆栈为空的时候)。lua_type返回的类型代码为如下在lua.h中定义的常量:LUA_TNIL,LUA_TNUMBER,LUA_TBOOLEAN,LUA_TSTRING,LUA_TTABLE,LUA_TFUNCTION,LUA_USERDATA,LUA_TTHEARD,LUA_TLIGHTUSERDATA。下面的函数可以将这些常量转换为字符串:
const char* lua_typename (lua_State* L, int type);
带lua_is*前辍的函数在当堆栈元素对象与给定的类型兼容时返回1,否则返回0。Lua_isboolean是个例外,它仅在元素类型为布尔型时成功(否则没有意思,因为任何值都可看作布尔型)。当使用无效索引时,它们总返回0。Lua_isnumber接受数字或者全部为数字的字符串;lua_isstring打接受字符串和数值,lua_isfunction接受lua函数和C函数;lua_isuserdata也可接受完全和轻量级两种userdata。如果想区分C函数和lua函数,可以使用lua_iscfunction函数;同样地,想区分完全和轻量级userdata可以使用lua_islightuserdata;区分数字和数字组成的字符串可以使用lua_type。
API函数中还有比较堆栈中的两个值 的大小的函数:
int lua_equal (lua_State *L, int index1, int index2);
int lua_rawequal (lua_State *L, int index1, int index2);
int lua_lessthan (lua_State *L, int index1, int index2);
lua_equal和lua_lessthan与相对应的lua操作符等价(参考2.5.2)。lua_rawequal直接判断两个值的原始值,而非通过调用元方法来比较。以上的函数当索引无效时返回0。