Lua1.1 程序分析二

再看看另外的几个自带的程序,简单的分析一下。
test 目录里有几个 Lua 程序,其中 sort 子目录里又有两个 Lua 程序(这两个和外面的 sort.lua 差不多)。

先看下 sort 目录里面的:
q.lua,sort.lua
里面都包含了一个快速排序和一个选择排序。不同的是,q.lua 把代码都写到了函数里,比如它的执行入口在最后一行 main(),而 sort.lua 则直接执行脚本。没有把执行入口放到函数里。
这也是脚本语言和其它通用型语言(如 C 语言)不同的地方。在 C 语言里,默认的函数执行入口是 main 函数。而脚本语言则没有这个限制。

看下代码,发现一个奇怪的地方,main 函数里调用 sort 时 sort 其实并没有定义,把选择排序的注释打开,运行了下,也是正常的。这个比较不合常理,比如在 C 语言里,调用函数之前,函数是要有前置声明或者是已经定义的。这是怎么回事?Lua 代码为什么能这样呢?

原因其实很简单,Lua 脚本代码并不是一行行从上到下解释执行的,执行的是字节码,也就是把脚本代码编译为字节码之后才执行。虽然,在编译为字节码时 sort 还没有定义,但是,sort 在全局符号表已经注册了。等到下面 function sort(a,n) 函数定义的时候,把函数体存过去。在字节码执行的时候就都是定义过的了,这算是生成中间字节码的一个好处吧。

由于这个脚本比较长,生成的字节码也很多,不再一句一句分析,只简单说一下。

可以看到,字节码分成好几个 CODE 段,每一个函数为一个段,全局调用的部分也为一个段。

这种安排倒是和汇编很像,汇编通过汇编器和链接器生成可执行程序,可执行程序交给真机 CPU 执行。Lua 脚本程序编译成字节码,交由 Lua 虚拟机执行。

说点题外话,可以认为每一个 Lua 脚本程序是对 Lua 运行时(Lua 运行的环境和虚拟机)的一定程度上的扩展,这点倒和 Lisp 很像。Lua 实现时本身就是参考了 Scheme,使用了对用户友好的语法。到后面会看到,Lua 的语法分析器也是手写的,为了实现一次扫描就能生成字节码,一定程序上对语法做了限制,这也是为什么有时候有人问 Lua 中怎么没有某种写法或者某种写法怎么就是语法错误了的原因。

扯的有点远,编译器前端是另一个话题了,还是回到正题。

对比行号和字节码里的 SETLINE 指令比较容易看出脚本代码和字节码的对应关系。这里不再详细对比分析说明。

简单说下 test 目录里的脚本代码都是干什么的。
通过学习脚本代码,可以了解到当时的语法,这些代码有的还是比较实用的。 这里只是学习之用,如果有理解上的偏差的话,请以程序的实际执行结果为准。当然,如果真是要实用的话,建议还是用比较新的 Lua 版本,比如 5.1 或 5.2。因为比较新的版本用的人多,研究的人也比较多,各种资料也比较丰富。

sort/q.lua
sort/sort.lua
sort.lua
排序,包括快速排序和选择排序。

array.lua
新建数组,赋值,并遍历输出。

dump
save.lua
递归保存 table,如果table 的元素为 table 也可以正常的保存。

loop.lua
repeat...until 循环

split.lua
分割文件路径与文件名

teste.lua
选择排序,这个可能是为了测下性能,数组元素 5000 个。

type.lua
table 的构造函数,可以对新建的 table 进行元素类型检查和赋默认值。

至此,不再对 Lua1.1 脚本的使用做进一步的分析,具体的请参考手册,开始关注于它的实现。

你可能感兴趣的:(lua,Lua1.1)