在寒假里,虽然我一行Tenshi的代码也没写,但是它的设计却一直在我脑海里不断地更新。特别是类型系统,在Lua的metatable机制的启发下,我觉得在Tenshi中完全也可以使用。一个Tenshi对象就是一个C语言中的一个结构体:TObject,一个叫法和Lua一样,其中T是前辍,在Tenshi源代码中,所有以类似TXxx是Tenshi的类型。它由两部分构成:
这与Lua的处理方法不同之处是它的类型是一个指向TType的指针,而不是一个整数,TValue是一个共用体,用于保存对象的值。而且目前为了方便起见,暂时为4个字节,与一般32位机的字长相同。TType类似于Lua的Metatable,里面保存了相应的方法:
例如当遇到c=a+b这样的表示式时,则是调用a的add函数,把a和b作为参数传入,然后调用c的assign函数,把c和a+b的结果代入。比较函数虽然只有<(less)和==(equal)两个函数,但是其它的比较函数都是由这两个函数衍生而来。如
a>b -> b<a
a>=b -> not a<b
a<=b -> not b<a
a!=b -> not a==b
也就是遇到其它的比较操作,只须在编译期稍微做一些变动就可以了,而且这也比较符合逻辑,如果a<b,那么b必然大于a,即使被比较的不是数字,也应该符合这个规律。所以这样的约定可以将问题简化。
在Tenshi中,函数式的编程思想也是存在的,因此,只要有如foo(a,b)则是调用foo本身的call函数,并且把foo,a,b三个参数传入,因为foo也是一个对象,它可以作为参数被其它函数调用,也可以作为返回值,也可以有除调用以外的任何操作如算术比较运算等等。从这点来说,TType可看作C++中的虚函数表,这套机制类似于C++的动态绑定机制。
iterator也是重要的操作之一,它是Tenshi完成高级迭代的重要方法。如for(a in array){...}这样的for循环中,实际上就是不断地调用array的iterator函数不断改变a的取值。从而达到迭代的目的。关于Tenshi的迭代机制,下次博客里再写。
输入输出也是极为重要的操作,在它的input函数,用于从流中读入数据,而output则用于输出数据。而read和write主要用于流的读写,Tenshi提倡使用流的机制来完成输入和输出。而且流可以是文件流,也可以是网络流,还可以是字符串流,二进制数据流等等,而它的io对象我将参考glib中的GIOChannel对象,
一般这些字段不能为空,Tenshi在编译时不会进行非空测试。如果没有提供相应的操作可以赋其为tns_op_idle(什么都不做),或是tns_op_except(引发异常),tostring相当于Ruby中重载的to_s,destructor相当于Lua中Metatable的__gc。
当然,以后可以通过这个机制来进行基础类型的扩展,不过现在还没有正式开始写,一切都还是设想而已,不过我自认为这是一个很好的设计,也许已经有一些脚本语言就是这样设计的。