Lua2.4 打开文件 inout.c

这里根据 luac.c 里的函数调用顺序,依次展开相关的代码。首先要看的就是 lua_openfile,该函数定义于 inout.c 中:

/*
** Function to open a file to be input unit.
** Return the file.
*/
FILE *lua_openfile (char *fn)
{
 lua_setinput (fileinput);
 if (fn == NULL)
 {
   fp = stdin;
   fn = "(stdin)";
 }
 else
   fp = fopen (fn, "r");
 if (fp == NULL)
   return NULL;
 lua_linenumber = 1;
 lua_parsedfile = luaI_createfixedstring(fn)->str;
 return fp;
}

函数一开始调用 lua_setinput,传给它一个函数指针。
lua_setinput 定义于 lex.c 中,给词法分析器一个函数指针,以后词法分析程序需要从该函数指针中得到一个个的输入字符。
这里 lua_setinput 的实际输入参数是 fileinput,fileinput 定义如下:

/*
** Function to get the next character from the input file
*/
static int fileinput (void)
{
 return fgetc (fp);
}

可以看出,这个函数的作用就是每次调用它时从文件中取得一个字符。

回到 lua_openfile ,如果传入的文件名为空,则程序认为从标准输入读入内容。设置文件描述符为标准输入 stdin,设置它的文件名为 “(stdin)”。
如果传入正常的文件名,则打开它。如果打开失败,返回 NULL。
设置当前的行号为 1。
设置当前的要分析的文件为当前打开的文件。luaI_createfixedstring 函数是在 Lua 的字符串存储空间中生成一个不可回收的字符串,这个方法以后会提到。
最后,函数返回文件描述符 fp;
lua_openfile 分析完了。

再看看相应的 lua_closefile

/*
** Function to close an opened file
*/
void lua_closefile (void)
{
 if (fp != NULL && fp != stdin)
 {
  fclose (fp);
  fp = NULL;
 }
}

这个函数就是关闭由 lua_openfile 打开的文件。

lua_openstring, lua_closestring 和上面的打开关闭文件的操作类似,就不再重复了。
注意,lua_openstring 时,给它设置的文件名为 "(string)", 这个格式和上面的以标准输入为输入文件的文件名格式相同。
这样是为了程序上的统一,就是看到文件是一个括号里有一个字符串,就知道文件并非真正的文件,而只是为了维持写程序时概念上的统一。
这也是写程序中比较常用的技巧,就是把特例转化为某种特殊的一般情况。

到这里,和编译器相关的 inout.c 中的内容已经说完了。这里可以回答在编译器那里提出的 compile 里打开关闭文件相关的问题了。

那里提出的为什么要调用 lua_openfile 这样的问题,这里解答一下,把输入输出这样的放到一块是出于设计上的考量,程序结构很清晰。

再夸一句,Lua 的设计做的很好,模块化做得很漂亮,代码质量也很高。

luac.c 里提到和打开关闭文件相关的问题已经解答了。不过,在上面的看代码的过程中又发现一些新的问题,列在下面:
> lua_setinput 在词法分析里的作用?相关的词法分析内容又是什么?
> luaI_createfixedstring 是什么? 那个 TaggedString 是个什么数据结构?

记点题外话,其实也不算是偏题太远。目前计划的是 Lua2.4 先跟编译器这条线儿,这条线儿结束了,再看看解释器那条。只看代码,写代码相关的东西,原理性的东西,不影响解释的情况下,尽量少说。因为原理性的东西,网上还是比较多的,相关的书籍也有很多。这里说的原理性的东西主要是指编译原理相关的。

----------------------------------------
记一下到目前为止的问题:
inout.c
> lua_setinput 在词法分析里的作用?相关的词法分析内容又是什么?
> luaI_createfixedstring 是什么? 那个 TaggedString 是个什么数据结构?

luac.c
> do_compile 里的 TFunc 是什么?那个初始化 luaI_initTFunc 是什么?
> lua_parser 是什么? do_dump 方法里调的那几个方法又分别是干什么的?
----------------------------------------

你可能感兴趣的:(lua,Lua2.4)