《programming in lua 》的第24章讲C语言的API函数。
那么什么叫做lua解释器?
书中的意思lua解释器就是除了lua脚本和lua库之外的C语言程序。
lua脚本(由用户输入的字符串或文件组成) <-----> lua解释器 <-------->lua库(比如V5.1.4版本的库)
=======================================================================================
这章的第一节就写了个lua解释器的例子,由于例子中有头文件,所以就是介绍了头文件:
lua.h:所有在 lua.h 中被定义的都有一个 lua_前缀.
lauxlib.h 定义了辅助库(auxlib)提供的函数都以 luaL_打头( .lauxlib.h通过调用lua.H形成更高的抽象),比如:
LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
const char *name) {
LoadS ls;
ls.s = buff;
ls.size = size;
return lua_load(L, getS, &ls, name);
}
======================================================================================================================
对于下面的一般解释器都有的东东:
/*下面这句等价于L = luaL_newstate();*/
L = lua_open();
luaopen_base(L);
/* 下面这句等价于luaL_loadstring(L, LUA_SCRIPT) || lua_pcall(L, 0, LUA_MULTRET, 0);*/
error = luaL_dostring(L, LUA_SCRIPT);</span>
书中给出了具体解释:
函数 lua_open 创建一个新环境(或 state)。lua_open 创建一个新的环境时,这个环
境并不包括预定义的函数,甚至是 print。为了保持 Lua 的苗条,所有的标准库以单独的
包提供,所以如果你不需要就不会强求你使用它们。头文件 lualib.h 定义了打开这些库
的函数。例如,调用 luaopen_io,以创建 io table并注册 I/O函数(io.read,io.write等等)
到 Lua 环境中。
创建一个 state 并将标准库载入之后,就可以着手解释用户的输入了。对于用户输入
的每一行,C 程序首先调用 luaL_loadbuffer 编译这些 Lua 代码。如果没有错误,这个调
用返回零并把编译之后的 chunk 压入栈。(记住,我们将在下一节中讨论魔法般的栈)之
后,C 程序调用 lua_pcall,它将会把 chunk 从栈中弹出并在保护模式下运行它。和
luaL_laodbuffer 一样,lua_pcall 在没有错误的情况下返回零。在有错误的情况下,这两
个函数都将一条错误消息压入栈;我们可以用 lua_tostring 来得到这条信息、输出它,用
lua_pop 将它从栈中删除
========================================
第二节讲了堆栈。
操作堆栈用到了一下api函数:
压栈 lua_push*
查询 lua_is*
获取lua_to*
lua_gettop 获取堆栈元素个数
lua_settop 设置堆栈元素个数
lua_pop
这时候疑问来了,理解这些函数的最好方法就是弄个简单例子试一试,那么如何得知堆栈里面的内容都是啥呢?
于是作者给了一个函数stackDump,让所有的堆栈元素一览无余。
甚至还给出了具体的例子,真是太贴心了。
#include <stdio.h>
#include <lua.h>
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 */
}
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;
}