SlideShare a Scribd company logo
Lua 语言介绍

                   罗进
       luojinlj@gmail.com
简单、高效、易移植、易嵌入

                             C/C++


      Objective-C



                                                     .Net

                                                                     Awesome
   Java
                                                            Fortan



                                                     LuaPerl

          Erlang

                                     RubyLuaBridge

                    Lunatic Python
                                      Numeric Lua
了解从比较开始
                Lua5.1              Python2.6         Ruby1.9
生日              1993                1989              1995
籍贯              巴西                  荷兰                日本
安装 http         luarocks            easyinstall       gem
交互 console      ilua                ipython           irb
注释              --                  #                 #
程序库             少                   多多                多
类型数量            8                   37                >50
虚拟机 VM          基于寄存器               基于栈               基于栈
体积 win dll      120k, 可裁剪           2.155M            1.983M
速度 mandelbrot   GCC(0.41ms)         Java(4.96ms)      PHP(9.19ms)
( 分形图形 )        1.94ms              11.85ms           29.71ms
JIT 即时编译        LuaJIT     ~ x150   Pypy      ~ x20   Rubinius   ~ x20
简单: 8 种类型
•   string :” abcdfeg” , 0 结尾
•   nil : null
•   boolean : true , false
•   number :统一 short,integer,float 到 double
•   function :带有逻辑的变量
    local f = function (x) return x*x, x*x*x end
    f(2) --4, 8
• userdata : C 指针,用户自定义类型
• thread :非抢占式协程 coroutine
• table : hash 表,统一了序列式和关联式容器,索引从 1 开始
    t1 = {1,2,3}   t2= {s=“abs”,n=1.2,f=function(x) return x end}
    t1[2] --2      t2.s --abs t2.n --1.2 t2.f(2) –2
只有 string, table, function, thread4 中类型分配在堆上,需要 GC 回收,其他类型分配在栈上
简单:基于原型的面向对象
                                   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
简单: 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
高效:基于寄存器 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
用汇编重写
易移植 易嵌入: Lua 虚拟机快
       照
lua_State    lua_State
  stack        stack
  callinfo     callinfo




                          global_State MM GC
易移植 易嵌入: Lua 虚拟机结
       构
      C Library
易嵌入: Lua 虚拟机的栈                                                 与宿主程序交互



 struct lua_State {
                                      C API           正 逆             栈 lua_State
  global_State *l_G;                                  索 索               statck
                                                      引 引
   StkId stack;               lua_pushlightuserdata   6   -1   <…>
   StkId top;
                              lua_getglobal           5   -2   (cfunction)
   StkId base;
 …                            lua_pushcfunction                0x20120729
 };                           lua_newtable            4   -3   (table)
                              lua_rawseti                      {‘lua,’ ’pyton’,’ruby’}
/*Function Prototypes*/       lua_pushstring          3   -4   (string)
struct Proto {                lua_tostring                     “script language”
  TValue *k; /*constants */   lua_pushboolean         2   -5   true
  Instruction *code;
                              lua_pushnumber          1   -6   123
 Tstring **upvalues;          lua_tonumber
 /*inside funcs*/
                                                               function(Lua)
 struct Proto **p;
…
};
嵌入示例 在栈上交互调用
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*/
}
嵌入示例 Lua and C array 共享同一内
                                                     存
struct CArray {                                            CArray * new_CArray (lua_State *L, …){
   size_t size;                                              …
   size_t elemsize;//1:char,2;short,4:int,8:double           CArray *a = (CArray*) lua_newuserdata(L, nbytes);
   float values[1];                                          …
};                                                           luaL_newmetatable(L, "CArray");
static int getarray (lua_State *L) {                         luaL_register(L, NULL, arraylib_m);
   CArray *a = (CArray*)luaL_checkudata(L, 1, “CArray");     lua_setmetatable(L, -2);
   size_t idx= luaL_checkint(L, 2) - 1;                      lua_setglobal(L, array_name);
   luaL_argcheck(L, 0 <= idx …, 2, “error …");               return a;
   …                                                       }
   lua_pushinteger(L, (int*)(a->values)[index]);           CArray *a1 = new_CArray(L, “a1", 200, “int”);
   return 1;                                               CArray *a2 = new_CArray(L, “a2", 100, “double”);
}
                                                           --------------------------------------------------
static const struct luaL_Reg arraylib_m [] = {             Test.lua
   {"__newindex", setarray},                               for i = 1, 10 do
   {"__index", getarray},                                     print(a1(i), a2[i])
   {"__call", array_call},                                    a1[i] , a2[i] = i, i
   {NULL, NULL}                                               print(a1(i), a2[i])
};                                                         end

 将新建的 userdata 附上 metatable(struct luaL_Reg) ,
 就可以在 Lua 中基于对象编程了,实际使用的是宿主函数
Lua 咋个像?


  谢谢

More Related Content

PPTX
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王
 
PPT
Introduction to C++ over CLI
建興 王
 
PPT
Scala function-and-closures
wang hongjiang
 
PDF
functional-scala
wang hongjiang
 
PDF
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
Justin Lin
 
PDF
Pl 06 p10.prn
jokertest
 
PPTX
Introduction to Basic Haskell Components (In Chinese)
ChengHui Weng
 
PDF
OOP in C - Virtual Function (Chinese Version)
Kai-Feng Chou
 
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王
 
Introduction to C++ over CLI
建興 王
 
Scala function-and-closures
wang hongjiang
 
functional-scala
wang hongjiang
 
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
Justin Lin
 
Pl 06 p10.prn
jokertest
 
Introduction to Basic Haskell Components (In Chinese)
ChengHui Weng
 
OOP in C - Virtual Function (Chinese Version)
Kai-Feng Chou
 

What's hot (20)

PDF
程式設計師的自我修養 Chapter 10 記憶體
Shu-Yu Fu
 
PDF
Java 開發者的函數式程式設計
Justin Lin
 
PPT
10 檔案說明與處理
shademoon
 
PDF
深入淺出 Web 容器 - Tomcat 原始碼分析
Justin Lin
 
DOC
深入剖析Concurrent hashmap中的同步机制(上)
wang hongjiang
 
PPT
线程与并发
Tony Deng
 
PDF
系統程式 - 附錄
鍾誠 陳鍾誠
 
PDF
千呼萬喚始出來的 Java SE 7
Justin Lin
 
PDF
竞赛中C++语言拾遗
乐群 陈
 
PPTX
Linux c++ 编程之链接与装载 -提高篇--v0.3--20120509
tidesq
 
PPT
C語言 第4章 基本輸出與輸入功能
shademoon
 
PPTX
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509
tidesq
 
PPT
MPI use c language
ZongYing Lyu
 
PPT
第六章 函數與巨集
shademoon
 
PDF
Node.js开发体验
QLeelulu
 
DOC
Lua gc代码
Wei Sun
 
PPT
JAVA内存泄漏及诊断
ivannotes
 
PPT
Ch02
jashliao
 
PPT
第9章文件
summerfeng
 
PDF
Lua/LuaJIT 字节码浅析
Xiaozhe Wang
 
程式設計師的自我修養 Chapter 10 記憶體
Shu-Yu Fu
 
Java 開發者的函數式程式設計
Justin Lin
 
10 檔案說明與處理
shademoon
 
深入淺出 Web 容器 - Tomcat 原始碼分析
Justin Lin
 
深入剖析Concurrent hashmap中的同步机制(上)
wang hongjiang
 
线程与并发
Tony Deng
 
系統程式 - 附錄
鍾誠 陳鍾誠
 
千呼萬喚始出來的 Java SE 7
Justin Lin
 
竞赛中C++语言拾遗
乐群 陈
 
Linux c++ 编程之链接与装载 -提高篇--v0.3--20120509
tidesq
 
C語言 第4章 基本輸出與輸入功能
shademoon
 
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509
tidesq
 
MPI use c language
ZongYing Lyu
 
第六章 函數與巨集
shademoon
 
Node.js开发体验
QLeelulu
 
Lua gc代码
Wei Sun
 
JAVA内存泄漏及诊断
ivannotes
 
Ch02
jashliao
 
第9章文件
summerfeng
 
Lua/LuaJIT 字节码浅析
Xiaozhe Wang
 
Ad

Similar to Lua 语言介绍 (20)

ODP
igdshare 110220: LuaJIT intro
igdshare
 
PDF
iOS中Lua脚本的应用
Proteas Wang
 
PDF
使用Lua提高开发效率
gowell
 
PDF
未标题 1
sugarray34
 
PPTX
lua & ngx_lua 的介绍与应用
hugo
 
PDF
程式人雜誌 -- 2014 年2月號
鍾誠 陳鍾誠
 
ODP
Ihome inaction 篇外篇之fp介绍
dennis zhuang
 
PDF
Python 于 webgame 的应用
勇浩 赖
 
PDF
Adorable python
Rhythm Sun
 
PDF
Learning python in the motion picture industry by will zhou
Will Zhou
 
PDF
Go
Feng Yu
 
PDF
Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure
National Cheng Kung University
 
PPT
Lua 30+ Programming Skills and 20+ Optimization Tips
Ho Kim
 
PDF
使用Dsl改善软件设计
mingjin
 
PPT
第三章 栈和队列
Wang Yizhe
 
PPT
Scala
deathxlent
 
PDF
Clojure and FP
Qin Jian
 
KEY
Ruby basic
xiaozhestrong
 
PPTX
Erlang and HTML5
Witeman Zheng
 
PDF
Ruby基础培训
xiaozhestrong
 
igdshare 110220: LuaJIT intro
igdshare
 
iOS中Lua脚本的应用
Proteas Wang
 
使用Lua提高开发效率
gowell
 
未标题 1
sugarray34
 
lua & ngx_lua 的介绍与应用
hugo
 
程式人雜誌 -- 2014 年2月號
鍾誠 陳鍾誠
 
Ihome inaction 篇外篇之fp介绍
dennis zhuang
 
Python 于 webgame 的应用
勇浩 赖
 
Adorable python
Rhythm Sun
 
Learning python in the motion picture industry by will zhou
Will Zhou
 
Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure
National Cheng Kung University
 
Lua 30+ Programming Skills and 20+ Optimization Tips
Ho Kim
 
使用Dsl改善软件设计
mingjin
 
第三章 栈和队列
Wang Yizhe
 
Scala
deathxlent
 
Clojure and FP
Qin Jian
 
Ruby basic
xiaozhestrong
 
Erlang and HTML5
Witeman Zheng
 
Ruby基础培训
xiaozhestrong
 
Ad

More from gowell (8)

PDF
Kernel init
gowell
 
PDF
Logging develop
gowell
 
PDF
Logging introduce
gowell
 
PDF
Script meta
gowell
 
PDF
Script binding
gowell
 
PDF
Casing3d opengl
gowell
 
PDF
Pytables
gowell
 
PDF
从动态说开去
gowell
 
Kernel init
gowell
 
Logging develop
gowell
 
Logging introduce
gowell
 
Script meta
gowell
 
Script binding
gowell
 
Casing3d opengl
gowell
 
Pytables
gowell
 
从动态说开去
gowell
 

Lua 语言介绍

  • 2. 简单、高效、易移植、易嵌入 C/C++ Objective-C .Net Awesome Java Fortan LuaPerl Erlang RubyLuaBridge Lunatic Python Numeric Lua
  • 3. 了解从比较开始 Lua5.1 Python2.6 Ruby1.9 生日 1993 1989 1995 籍贯 巴西 荷兰 日本 安装 http luarocks easyinstall gem 交互 console ilua ipython irb 注释 -- # # 程序库 少 多多 多 类型数量 8 37 >50 虚拟机 VM 基于寄存器 基于栈 基于栈 体积 win dll 120k, 可裁剪 2.155M 1.983M 速度 mandelbrot GCC(0.41ms) Java(4.96ms) PHP(9.19ms) ( 分形图形 ) 1.94ms 11.85ms 29.71ms JIT 即时编译 LuaJIT ~ x150 Pypy ~ x20 Rubinius ~ x20
  • 4. 简单: 8 种类型 • string :” abcdfeg” , 0 结尾 • nil : null • boolean : true , false • number :统一 short,integer,float 到 double • function :带有逻辑的变量 local f = function (x) return x*x, x*x*x end f(2) --4, 8 • userdata : C 指针,用户自定义类型 • thread :非抢占式协程 coroutine • table : hash 表,统一了序列式和关联式容器,索引从 1 开始 t1 = {1,2,3} t2= {s=“abs”,n=1.2,f=function(x) return x end} t1[2] --2 t2.s --abs t2.n --1.2 t2.f(2) –2 只有 string, table, function, thread4 中类型分配在堆上,需要 GC 回收,其他类型分配在栈上
  • 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 用汇编重写
  • 8. 易移植 易嵌入: Lua 虚拟机快 照 lua_State lua_State stack stack callinfo callinfo global_State MM GC
  • 9. 易移植 易嵌入: Lua 虚拟机结 构 C Library
  • 10. 易嵌入: Lua 虚拟机的栈 与宿主程序交互 struct lua_State { C API 正 逆 栈 lua_State global_State *l_G; 索 索 statck 引 引 StkId stack; lua_pushlightuserdata 6 -1 <…> StkId top; lua_getglobal 5 -2 (cfunction) StkId base; … lua_pushcfunction 0x20120729 }; lua_newtable 4 -3 (table) lua_rawseti {‘lua,’ ’pyton’,’ruby’} /*Function Prototypes*/ lua_pushstring 3 -4 (string) struct Proto { lua_tostring “script language” TValue *k; /*constants */ lua_pushboolean 2 -5 true Instruction *code;   lua_pushnumber 1 -6 123 Tstring **upvalues; lua_tonumber /*inside funcs*/ function(Lua) struct Proto **p; … };
  • 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*/ }
  • 12. 嵌入示例 Lua and C array 共享同一内 存 struct CArray { CArray * new_CArray (lua_State *L, …){ size_t size; … size_t elemsize;//1:char,2;short,4:int,8:double CArray *a = (CArray*) lua_newuserdata(L, nbytes); float values[1]; … }; luaL_newmetatable(L, "CArray"); static int getarray (lua_State *L) { luaL_register(L, NULL, arraylib_m); CArray *a = (CArray*)luaL_checkudata(L, 1, “CArray"); lua_setmetatable(L, -2); size_t idx= luaL_checkint(L, 2) - 1; lua_setglobal(L, array_name); luaL_argcheck(L, 0 <= idx …, 2, “error …"); return a; … } lua_pushinteger(L, (int*)(a->values)[index]); CArray *a1 = new_CArray(L, “a1", 200, “int”); return 1; CArray *a2 = new_CArray(L, “a2", 100, “double”); } -------------------------------------------------- static const struct luaL_Reg arraylib_m [] = { Test.lua {"__newindex", setarray}, for i = 1, 10 do {"__index", getarray}, print(a1(i), a2[i]) {"__call", array_call}, a1[i] , a2[i] = i, i {NULL, NULL} print(a1(i), a2[i]) }; end 将新建的 userdata 附上 metatable(struct luaL_Reg) , 就可以在 Lua 中基于对象编程了,实际使用的是宿主函数

Editor's Notes

  • #3: 简单、高效是选择这个语言的基础。易移植、易嵌入体现在多异构平台上 Lr:Adobe photoshop LightRoom, 40% lua code, 工业级应用
  • #4: 了解一个新事物从比较开始 . 编译器占体积的 30% ,可以预编译后去掉编译器减小体积。语法 pascal ,语义 scheme. 扩展:作为配置文件,为宿主语言应用提供参数 . 宿主语言使用 Lua 作为逻辑扩展,或静态链接
  • #7: 共享内存,但不是抢占式 . Lua Lane 工业强度的语言,需要充足的人力资源、丰富的应用、配套工具来支撑 Actor 抽象的程度更高了
  • #9: 嵌入在宿主之上的 Lua
  • #10: 嵌入在宿主之上的 Lua