5. 简单:基于原型的面向对象
metatable
String = {}
function String:new(s)
return setmetatable({value = s or ''}, {__index = String})
end
function String:print() print(self.value) end
function String:print2() print(self.value) end
String:new(‘hello ’):print() --hello
-- inheritance
Child=String:new(‘inheritance’)
function Child:print() print(‘child of string: ’ .. self.value) end
c = setmetatable({}, {__index = Child}}
c:print() -- child of string: inheritance
c:print2() -- inheritance
6. 简单: Coroutines 非抢占式多任务
下载文件从指定地址 test
threads = {} -- list of all live threads host = "www.w3.org"
function get (host, file) -- create coroutine
co = coroutine.create(function() get(host, "/…/html40.txt")
… get(host, "/…/xhtml1.pdf")
if status == "timeout" then get(host, "/../html.html")
coroutine.yield(connection)
end dispatch() -- main loop
end)
table.insert(threads, co)
end
function dispatch ()
while true do
if threads[i] == nil then -- no more threads? 将底层细节和多状态模式
… 屏蔽,使得逻辑流畅易懂
local status, res = coroutine.resume(threads[i])
提高了工业强度
if not res then table.remove(threads, i) end
end
调度可控,显式优于隐式
end
7. 高效:基于寄存器 VM , LuaJIT
基于寄存器 4 条指令 基于栈 11 条指令
local a,t,i 1: LOADNIL 0 2 0 local a,t,i 1: PUSHNIL 3
a=a+i 2: ADD 0 0 2 a=a+i 2: GETLOCAL 0 ; a
3: GETLOCAL 2 ; i
4: ADD
5: SETLOCAL 0 ; a
a=a+1 3: ADD 0 0 250 a=a+1 6: GETLOCAL 0 ; a
7: ADDI 1
8: SETLOCAL 0 ; a
a=t[i] 4: GETTABLE 0 1 2 a=t[i] 9: GETLOCAL 1 ; t
10: GETINDEXED 2 ; i
11: SETLOCAL 0 ; a
LuaJIT
解释器使用自定义字节码格式
直接派发,替代了以前的 switch
用汇编重写
11. 嵌入示例 在栈上交互调用
C 宿主程序 test.c Lua 嵌入脚本 test.lua
#include <lua.h> function lua_func(x)
static int c_func (lua_State *L) { if x<= 1 then
double d = lua_tonumber(L, 1); /* get argument */ return 1
lua_pushnumber(L, sqrt(d)); /* push result */ end
return 1; /* number of results */ return ((lua_func(x-2))+
} lua_func((x-1)))
static int register_c_func (lua_State *L, const char *func_name) { end
lua_pushcfunction(l, c_func);
lua_setglobal(l, func_name); function lua_call_c(x)
} return c_func(x)
static int call_lua_func (lua_State *L, const char *func_name) { end
lua_getglobal(L, func_name);/*get lua function by name*/
lua_pushnumber(L, 1); /*push argument in local stack*/ --test
lua_pcall(L, 1, 1, 0); /*call function*/ local fibonacci = lua_func
return lua_tointeger(L, 1); /*get result from local stack*/ for i = 0, 10 do
} print(fibonacci (i))
int main(int argc, char* argv[]) { end
lua_State *L = luaL_newstate(); /*1.create interpreter*/
luaL_openlibs(L); /*2.register standard libs*/ local sqrt= lua_call_c
register_c_func (L, “c_func“); /*3.register callback function*/ for i = 0, 10 do
luaL_dofile(L, “test.lua”); /*4.load script file*/ print(sqrt(i))
call_lua_func (L, “lua_func”); /*5. call lua function*/ end
lua_close(L); /*6. bye Lua*/
}