本lua版本为5.2.1
在lua的源码中,lua.c 实现了可执行的解释器,用于解释执行.out文件,luac.c 实现了字节码的编译器,用于将.lua文件编译为.out文件,即字节码文件。
更加宏观的东西,则在打印的两份文档里,此处不详述,由于整个读入解析到解释执行的过程是先从读入.lua文件开始的,所以我这份lua源码解析大业便先从这luac.c文件的阅读学习开始了,以下是它的main程序源代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int (int argc, char* argv[]) { lua_State* L; int i=doargs(argc,argv); argc-=i; argv+=i; if (argc<=0) usage("no input files given"); L=luaL_newstate(); if (L==NULL) fatal("cannot create state: not enough memory"); lua_pushcfunction(L,&pmain); lua_pushinteger(L,argc); lua_pushlightuserdata(L,argv); if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1)); lua_close(L); return EXIT_SUCCESS; }
|
tip1:在C语言中,函数内部的局部变量需要在开头定义
首先先定义了一个代表lua虚拟机的数据结构lua_State,然后执行参数解析工作,即调用doargs函数,并将命令行参数传了进去
以下是其源代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
static int doargs(int argc, char* argv[]) { int i; int version=0; if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; for (i=1; i<argc; i++) { if (*argv[i]!='-') break; else if (IS("--")) { ++i; if (version) ++version; break; } else if (IS("-")) break; else if (IS("-l")) ++listing; else if (IS("-o")) { output=argv[++i]; if (output==NULL || *output==0 || (*output=='-' && output[1]!=0)) usage("'-o' needs argument"); if (IS("-")) output=NULL; } else if (IS("-p")) dumping=0; else if (IS("-s")) stripping=1; else if (IS("-v")) ++version; else usage(argv[i]); } if (i==argc && (listing || !dumping)) { dumping=0; argv[--i]=Output; } if (version) { printf("%sn",LUA_COPYRIGHT); if (version==argc-1) exit(EXIT_SUCCESS); } return i; }
|
在说明doargs
函数之前,先列出在luac.c文件中前面的局部变量:
1 2 3 4 5 6 7 8 9
| #define PROGNAME "luac" #define OUTPUT PROGNAME ".out"
static int listing=0; static int dumping=1; static int stripping=0; static char Output[]={ OUTPUT }; static const char* output=Output; static const char* progname=PROGNAME;
|
未完待续……