Lua 没有内置的调试设施。它使用一种特殊的接口,这种接口依赖函数和 钩子(hooks)。该接口允许构造不同种类的调试器,分析器以及其他工具用以从解释器得到所需的信息。
得到解释程序运行时堆栈信息的主要函数是:
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
这个函数用一个指定等级的函数的 activation record 的标示符填充一个 lua_Debug
结构,等级 0 是当前运行函数,然而等级 n+1 是在等级 n 上调用的函数。当没有错误发生时,lua_getstack
返回 1;当在比栈更深的等级上调用的时候,它返回 0;
lua_Debug
结构被用来携带一个处于活动状态的函数的各种信息:
typedef struct lua_Debug { int event; const char *name; /* (n) */ const char *namewhat; /* (n) `global', `local', `field', `method' */ const char *what; /* (S) `Lua' function, `C' function, Lua `main' */ const char *source; /* (S) */ int currentline; /* (l) */ int nups; /* (u) number of upvalues */ int linedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ ... } lua_Debug;
lua_getstack
只填充结构的私有部分以备之后使用。要填充 lua_Debug
其他有用信息,调用
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
这个函数发生错误是返回 0 (举个例子,一个无效的 what
选项)。what
字符串中的每个字符选择填充一些 ar
结构的字段,把上面在 lua_Debug
定义中用圆括号括起来的字母作为指示: `S
´ 填充在 source
, linedefined
和 what
字段中;`l
´ 填充在 currentline
字段中,等等...。而且,`f
´ 将正在运?性谒燃渡系暮谷攵颜弧?
想要从一个不处于活动状态的函数那得到信息(就是不在栈上的函数),你需要将其压入栈并且用 >
´ 作为 what
字符串的开始。举个例子,要知道函数 f
定义在第几行,你需要这样写
lua_Debug ar; lua_pushstring(L, "f"); lua_gettable(L, LUA_GLOBALSINDEX); /* get global `f' */ lua_getinfo(L, ">S", &ar); printf("%d/n", ar.linedefined);
lua_Debug
的字段有如下的含义:
source
如果函数在一个字符串中定义,那么 source
就是那个字符串。如果函数定义在一个文件中,source
开始于一个 `@
´ 后面跟随文件名。 short_src
一个可打印版的 source
,用于错误信息。 linedefined
函数定义起始的行号。 what
如果这是一个Lua函数,显示 "Lua"
字符串, "C"
为C 函数,"main"
如果这是一个语句段的main部分,"tail"
如果这是一个做了尾部调用的函数。在后面的情况里,Lua 没有其他关于这个函部的信息。 currentline
代表当前函数执行到的行数。如果没有行信息可用,currentline
被设置为 -1。 name
一个所给函数合理的函数名。因为函数在Lua中属于第一类值,它们没有固定的名字:一些函数可能是多个全局变量的值,其他的可能只储存在一个表字段里。lua_getinfo
函数检测函数如何被调用或者是否为一个全局变量的值以寻找一个合适的名字。如果找不到合适的名字,name
被设置为 NULL
。 namewhat
name
字段的解释。根据函数如何被调用,namewhat
的值可以是 "global"
, "local"
, "method"
, "field"
或者 ""
(空字符串)。(当没有其他可选项的时候Lua使用空字符串代替) nups
函数上值的数量。 为了更多的操作局部变量和上值,调试接口使用索引:第一个参数或者局部变量索引为 1,以此类推,直到最后一个活动的局部变量。整个函数中的活动的上值没有特定的顺序。
下面的函数允许操作一个所给激活记录的局部变量:
const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
参数 ar
必须是一个被前一个 lua_getstack
调用填充的有效的激活记录或者作为一个钩子函数的参数(见 4.3)。lua_getlocal
获得一个局部变量的索引 n
,将变量的值压入栈,并且返回变量名。lua_setlocal
从栈顶分配一个值给变量并且返回变量名。当索引超过活动的局部变量的数量时,两个函数都返回 NULL
。
以下的函部可以操作所给函数的上值(不像局部变量,函数的上值即使在函数不处于活动状态的时候都可以被访问):
const char *lua_getupvalue (lua_State *L, int funcindex, int n); const char *lua_setupvalue (lua_State *L, int funcindex, int n);
这些函数可以作为Lua 函数使用也可以作为C 函数使用。(作为Lua 函数,上值是函数外部使用的局部变量,因此它被包含在函数闭包中。)funcindex
指向栈中的一个函数。lua_getupvalue
得到一个上值的索引 n
,将上值的值压入栈,并返回其变量名。lua_setupvalue
从栈顶分配一个值给上值并返回变量名。当索引大于上值数量时,两个函数都返回 NULL
。对于C 函数来说,这些函数使用空字符串作为所有上值的变量名。
作为一个例子,下面的函数列举了所给等级的栈中的函数的所有局部变量名和上值变量名:
int listvars (lua_State *L, int level) { lua_Debug ar; int i; const char *name; if (lua_getstack(L, level, &ar) == 0) return 0; /* failure: no such level in the stack */ i = 1; while ((name = lua_getlocal(L, &ar, i++)) != NULL) { printf("local %d %s/n", i-1, name); lua_pop(L, 1); /* remove variable value */ } lua_getinfo(L, "f", &ar); /* retrieves function */ i = 1; while ((name = lua_getupvalue(L, -1, i++)) != NULL) { printf("upvalue %d %s/n", i-1, name); lua_pop(L, 1); /* remove upvalue value */ } return 1; }
Lua offers a mechanism of hooks, which are user-defined C functions that are called during the program execution. A hook may be called in four different events: a call event, when Lua calls a function; a return event, when Lua returns from a function; a line event, when Lua starts executing a new line of code; and a count event, which happens every "count" instructions. Lua identifies these events with the following constants: LUA_HOOKCALL
, LUA_HOOKRET
(or LUA_HOOKTAILRET
, see below), LUA_HOOKLINE
, and LUA_HOOKCOUNT
.
A hook has type lua_Hook
, defined as follows:
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
You can set the hook with the following function:
int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
func
is the hook. mask
specifies on which events the hook will be called: It is formed by a disjunction of the constants LUA_MASKCALL
, LUA_MASKRET
, LUA_MASKLINE
, and LUA_MASKCOUNT
. The count
argument is only meaningful when the mask includes LUA_MASKCOUNT
. For each event, the hook is called as explained below:
count
instructions. (This event only happens while Lua is executing a Lua function.) A hook is disabled by setting mask
to zero.
You can get the current hook, the current mask, and the current count with the following functions:
lua_Hook lua_gethook (lua_State *L); int lua_gethookmask (lua_State *L); int lua_gethookcount (lua_State *L);
Whenever a hook is called, its ar
argument has its field event
set to the specific event that triggered the hook. Moreover, for line events, the field currentline
is also set. To get the value of any other field in ar
, the hook must call lua_getinfo
. For return events, event
may be LUA_HOOKRET
, the normal value, or LUA_HOOKTAILRET
. In the latter case, Lua is simulating a return from a function that did a tail call; in this case, it is useless to call lua_getinfo
.
While Lua is running a hook, it disables other calls to hooks. Therefore, if a hook calls back Lua to execute a function or a chunk, that execution occurs without any calls to hooks.
|
|
共享空间主页
|
工具
|
|
11月30日
Lua - 附录致谢The Lua team is grateful to Tecgraf for its continued support to Lua. We thank everyone at Tecgraf, specially the head of the group, Marcelo Gattass. At the risk of omitting several names, we also thank the following individuals for supporting, contributing to, and spreading the word about Lua: Alan Watson. André Clinio, André Costa, Antonio Scuri, Asko Kauppi, Bret Mogilefsky, Cameron Laird, Carlos Cassino, Carlos Henrique Levy, Claudio Terra, David Jeske, Ed Ferguson, Edgar Toernig, Erik Hougaard, Jim Mathies, John Belmonte, John Passaniti, John Roll, Jon Erickson, Jon Kleiser, Mark Ian Barlow, Nick Trout, Noemi Rodriguez, Norman Ramsey, Philippe Lhoste, Renata Ratton, Renato Borges, Renato Cerqueira, Reuben Thomas, Stephan Herrmann, Steve Dekorte, Thatcher Ulrich, Tomás Gorham, Vincent Penquerc'h. Thank you! 与以前版本的不兼容性 Incompatibilities with Previous VersionsLua 5.0 是一个主版本,所有与 Lua 4.0 有一些地方不兼容。 与 v4.0 的不兼容性 Incompatibilities with version 4.0语言上的变动
库的变更
API 上的改动
Lua 完整语法参考chunk ::= {stat [`;´]} block ::= chunk stat ::= varlist1 `=´ explist1 | functioncall | do block end | while exp do block end | repeat block until exp | if exp then block {elseif exp then block} [else block] end | return [explist1] | break | for Name `=´ exp `,´ exp [`,´ exp] do block end | for Name {`,´ Name} in explist1 do block end | function funcname funcbody | local function Name funcbody | local namelist [init] funcname ::= Name {`.´ Name} [`:´ Name] varlist1 ::= var {`,´ var} var ::= Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name namelist ::= Name {`,´ Name} init ::= `=´ explist1 explist1 ::= {exp `,´} exp exp ::= nil | false | true | Number | Literal | function | prefixexp | tableconstructor | exp binop exp | unop exp prefixexp ::= var | functioncall | `(´ exp `)´ functioncall ::= prefixexp args | prefixexp `:´ Name args args ::= `(´ [explist1] `)´ | tableconstructor | Literal function ::= function funcbody funcbody ::= `(´ [parlist1] `)´ block end parlist1 ::= Name {`,´ Name} [`,´ `...´] | `...´ tableconstructor ::= `{´ [fieldlist] `}´ fieldlist ::= field {fieldsep field} [fieldsep] field ::= `[´ exp `]´ `=´ exp | name `=´ exp | exp fieldsep ::= `,´ | `;´ binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `..´ | `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ | and | or unop ::= `-´ | not
21:51 | 添加评论 | 发送消息 | 固定链接 | 查看引用通告 (0) | 写入日志 | Lua
Lua - 独立程序6 - Lua 独立程序 Lua Stand-alone尽管Lua被设计为一种内嵌于C 语言宿主程序中的扩展语言,它还是经常被用作一个独立程序语言。一个Lua的解释程序将Lua作为一个独立的语言,我们称之为简化的 lua [options] [script [args]] options 可以是以下内容:
在停止处理选项后, Before running any argument, the interpreter checks for an environment variable All options are handled in order, except $ lua -e'a=1' -e 'print(a)' script.lua will first set Before starting to run the script, $ lua -la.lua b.lua t1 t2 the interpreter first runs the file arg = { [-2] = "lua", [-1] = "-la.lua", [0] = "b.lua", [1] = "t1", [2] = "t2"; n = 2 } and finally runs the file 在交互模式中,如果你写入了一个不完整的语句,解释器将等待你的完成。 If the global variable $ lua -e"_PROMPT='myprompt> '" -i (the outer pair of quotes is for the shell, the inner is for Lua), or in any Lua programs by assigning to 在Unix系统中,Lua脚本可以用 #!/usr/local/bin/lua (当然,Lua解释器的位置可能有所不同,如果 #!/usr/bin/env lua 就是一个更通用的解决方案。)
21:48 | 添加评论 | 发送消息 | 固定链接 | 查看引用通告 (0) | 写入日志 | Lua
Lua - 标准库5 - 标准库The standard libraries provide useful functions that are implemented directly through the C API. Some of these functions provide essential services to the language (e.g., All libraries are implemented through the official C API and are provided as separate C modules. Currently, Lua has the following standard libraries:
Except for the basic library, each library provides all its functions as fields of a global table or as methods of its objects. To have access to these libraries, the C host program must first call the functions 5.1 - 基本函数 Basic FunctionsThe basic library provides some core functions to Lua. If you do not include this library in your application, you should check carefully whether you need to provide some alternative implementation for some of its facilities.
|
|
|