Lua4.0 解释器入口

开始解释器了。

解释器的入口文件为 lua.c,在文件中找到 C 语言的 main。

int main (int argc, char *argv[]) {
  struct Options opt;
  int status;
  opt.toclose = 0;
  getstacksize(argc, argv, &opt);  /* handle option `-s‘ */
  L = lua_open(opt.stacksize);  /* create state */
  userinit();  /* open libraries */
  register_getargs(argv);  /* create `getargs‘ function */
  status = handle_argv(argv+1, &opt);
  if (opt.toclose)
    lua_close(L);
  return status;
}

设置结构体 struct Options 的栈尺寸 stacksize。

struct Options 结构体的定义如下:

/*
** global options
*/
struct Options {
  int toclose;
  int stacksize;
};

在 getstacksize 中给 stacksize 赋值。需要命令行传入 "-s" 参数。

lua_open 新建 lua_State L。

userinit 注册库。

register_getargs 注册获取命令行输入参数的函数 getargs。

handle_argv 程序执行。

toclose 如果为 1 的话,在程序退出前调用 lua

返回程序执行的状态。

分别看下其中的调用:

static void getstacksize (int argc, char *argv[], struct Options *opt) {
  if (argc >= 2 && argv[1][0] == ‘-‘ && argv[1][1] == ‘s‘) {
    int stacksize = atoi(&argv[1][2]);
    if (stacksize <= 0) {
      fprintf(stderr, "lua: invalid stack size (‘%.20s‘)\n", &argv[1][2]);
      exit(EXIT_FAILURE);
    }
    opt->stacksize = stacksize;
  }
  else
    opt->stacksize = 0;  /* no stack size */
}

如果命令行参数中有 "-s" ,取它后面的值作为 struct Options 的 stacksize。

static void userinit (void) {
  lua_baselibopen(L);
  lua_iolibopen(L);
  lua_strlibopen(L);
  lua_mathlibopen(L);
  lua_dblibopen(L);
  /* add your libraries here */
}

这个是调用各种库的注册函数。

接下来是注册 getargs 函数

static void register_getargs (char *argv[]) {
  lua_pushuserdata(L, argv);
  lua_pushcclosure(L, l_getargs, 1);
  lua_setglobal(L, "getargs");
}

把命令行参数压栈,把函数 l_getargs 压栈,设置给 Lua 变量 getargs。

然后在 Lua 代码里调用  getargs 就会调用  l_getargs 这个 C 函数了。

l_getargs 这个函数调用的时候执行过程如下:

static void getargs (char *argv[]) {
  int i;
  lua_newtable(L);
  for (i=0; argv[i]; i++) {
    /* arg[i] = argv[i] */
    lua_pushnumber(L, i);
    lua_pushstring(L, argv[i]);
    lua_settable(L, -3);
  }
  /* arg.n = maximum index in table `arg‘ */
  lua_pushstring(L, "n");
  lua_pushnumber(L, i-1);
  lua_settable(L, -3);
}
static int l_getargs (lua_State *l) {
  char **argv = (char **)lua_touserdata(l, -1);
  getargs(argv);
  return 1;
}

从栈上取得一个 userdata,从中通过 getargs 取得所有的命令行参数。

取得的命令行参数都存在于一个 Lua table 中。

handle_argv 分析命令行参数,主流程执行。

程序主体部分是一个大的循环判断,以解析各个参数。

manual_input 用来进行交互模式的处理,其它的文件及字符串处理由 ldo 进行。

manual_input 程序也是一个循环,通过调用 ldo(lua_dostring, buffer) 来执行用户的输入。

ldo 如下所示:

static int ldo (int (*f)(lua_State *l, const char *), const char *name) {
  int res;
  handler h = lreset();
  int top = lua_gettop(L);
  res = f(L, name);  /* dostring | dofile */
  lua_settop(L, top);  /* remove eventual results */
  signal(SIGINT, h);  /* restore old action */
  /* Lua gives no message in such cases, so lua.c provides one */
  if (res == LUA_ERRMEM) {
    fprintf(stderr, "lua: memory allocation error\n");
  }
  else if (res == LUA_ERRERR)
    fprintf(stderr, "lua: error in error message\n");
  return res;
}

第一个参数是个函数指针,可以传入 lua_dofile,lua_dostring 分别来对应文件输入和字符串输入。

第二个参数根据第一个函数指针的不同而可代表不同的意思: 文件名或者字符串。

通过调用 lreset() 设置中断信号处理程序。

调用结束时 signal(SIGINT, h) 来恢复中断信号处理。

解释器入口就说到这里。

----------------------------------------

到目前为止的问题:

> lua_dofile,lua_dostring

----------------------------------------

时间: 2024-10-09 11:36:55

Lua4.0 解释器入口的相关文章

Lua4.0 解释器文档

解释器文档(lua.html)---------------------------------------------------------名字lua - Lua 解释器 概要lua [ arguments ] 描述lua 是独立的 Lua 解释器.它加载并执行 Lua 程序,程序可以是文本源代码形式,或由 Lua 编译器 luac 输出的预编译二进制形式.lua 可以用作批处理解释器,也可用做交互式解释. 参数可以是选项,赋值,文件名,它们从左到右按顺序执行. 选项以中划线 - 开始,描述

Lua4.0 编译入口

解决上一篇的问题,上代码了. C 语言程序的入口为 main 函数,Lua 编译器的入口为 luac.c 文件里的 main 函数. 先来看一下 main 函数: int main(int argc, const char* argv[]) {  Proto** P,*tf;  int i=doargs(argc,argv);  argc-=i; argv+=i;  if (argc<=0) usage("no input files given",NULL);  L=lua_o

Lua2.4 解释器入口 lua.c

开始解释器篇. 解释器部分会写几节还说不准,因为,不少相关内容在之前的版本中是有覆盖到的. 同样,还是从解释器入口的 main 函数说起. int main (int argc, char *argv[]) {  int i;  int result = 0;  iolib_open ();  strlib_open ();  mathlib_open ();  lua_register("argv", lua_getargv);  if (argc < 2)    manual

Lua4.0 开篇

标题说是 4.0,其实这里分析的是 4.0.1.不过按照 Lua 的版本号规则,小号只做 bug fix .所以,下面的所说的 4.0 指的就是 release 4.0.1(在不引起混淆的情况下). 4.0 发布于 2000 年 11 月,4.0.1 发布于 2002.7,我们看的上一个版本 2.4 则是发布于 1996 年 5 月,怎么说这个版本也是二十一世纪的了. 4.0 算是比较新的版本了,因为它有在线版的代码和文档.在线文档在 http://www.lua.org/manual/,其实从

Lua4.0 语法分析

Lua 最初使用的是 Yacc 生成的语法分析器,后来改为手写的递归下降语法分析器(Recursive descent parser).因为一般在语言发展的早期,语言的语法还没有稳定下来,变动可能会比较多,用工具可以快速的验证自己的想法.当语法稳定下来之后,一般都会采用手写的语法分析器.因为这样程序员是调试可控的,并且一般也能有更好的性能表现.递归下降的语法分析对编程语言的语法有要求.因 Lua 的语法比较简单,是 LL(1) 文法.所以,手工编写语法分析也就是情理之中的事了. 关于递归下降的语

Lua4.0 参考手册(一)1-3

说明:这个文档是 doc 目录里的 manual.html 文件.原文版权归原作者所有,这篇翻译只是作为学习之用.如果翻译有不当之处,请参考原文.-------------------以下是正文-------------------编程语言 Lua4.0 的参考手册--------------------------------------1 简介--------------------------------------Lua 是一个扩展编程语言,支持通用编程功能与数据描述功能.作为一个强大

Lua4.0 代码

这个标题是 2014.11.13 号写的,今天总算是写入内容了. 离上次写代码分析时间有点长,都忘记自己之前是如何写的了. 不管这些历史包袱了,这次轻装上阵,想到哪就写到哪. 开始. 参照 4.0 的 INSTALL 文档内容,编译下.在 Linux 机器上比较简单,make 一下就好了. 在 Windows 上建工程的话,也算是比较容易.这部分之前有描述,这里就不再重复了. 简单的说一下这次的代码分析可能会写什么内容.(注意,这里用"可能"的原因的是,依目前的想法,最大程度上会这么写

Lua4.0 参考手册(八)6.2-6.5

(接上篇)-------------------6.2 字符串处理-------------------这个库提供字符串处理的通用函数,如查找,提取子串和模式匹配.在 Lua 中索引一个字符串的时候,第一个字符的索引是 1(不像 C 中是 0).另外,索引可以为负数,负数被解释为逆向索引,从字符串的结尾开始.所以,最后一个字符位置是 -1,以此类推. strbyte (s [, i])返回 s 的第 i 个字符的内部数值码(例如:ASCII 码).如果没有 i,它被认为是 1 .i 可以为负.

Lua4.0 参考手册(二)4.1-4.4

(接上篇)--------------------------------------4 语言--------------------------------------这节描述 Lua 的词法,语法和语义. -------------------4.1 词法约定-------------------Lua 中的标识符可以是任何字母,数字,下划线组成的字符串,且首字母不可为数字.这符合大多数语言中标识符的定义,除了字母的字义依赖于当前的区域设置:所有的在当前的区域设置中被认为是字母的字符可以被用