cnforth设计思想

c_forth改名为cnforth,以显示它不是一个传统的Forth系统。

cnforth的双栈

Forth系统以其独有的两个栈而与众不同。C语言程序的结构中,只有一个参数栈,所有的函数返回地址已经参数、临时变量都在栈中分配空间。但Forth使用了两个栈,参数栈和返回栈。参数栈中保存临时变量,返回栈中保存函数的返回地址。

cnforth的双栈跟传统的Forth系统是相同的,参数栈和返回栈使用C语言的数组来实现。

cnforth的词典结构

Forth系统中的词典是个核心的概念,词典是由一系列的词链表组成。相比较C语言,Forth的词就类似于C语言的函数。区别是,C语言函数的参数在栈上存放,在函数调用结束时自动清空栈上的参数,但Forth需要手工来清理栈上的参数。

cnforth的词使用C语言的结构体来模拟,分为两种类型,核心词和冒号词。cnforth词结构体由4个成员组成,参考了传统的F83标准。链接域是下一个词的地址;名字域是一个字符型指针,指向一个字符串;代码域是处理参数域中数据的一个函数指针;参数域中保存冒号词的定义,是一个指针数组。

cnforth的词典使用链表实现,每个cnforth词中的链接域都指向了词典中下一个词的地址。这样cnforth的词典就是一个单向链表。cnforth的词典结构体中保存4个成员,分别是最后一个词的地址、词典的词总数、当前定义的冒号词指针、当前定义的冒号词定义的临时保存区。

cnforth的解释器部分

cnforth的解释器也是参考了F83标准来实现的。跟传统的Forth系统不同的是,它一次性读入一行输入字符串,不是一个一个字去读取。

cnforth的解释器区分两种状态,解释态和编译态。

在解释态时,cnforth去读取一个词,在词典中寻找该词的地址,并执行这个Forth词的定义。如果在词典中找不到该词的地址,则尝试转换为数。转换成功将数压入参数栈,失败则清空栈并报错。

cnforth解释器遇到:时,将状态切换为编译态。在编译态时,cnforth去定义一个冒号词。它不会执行后面的每个Forth词的定义,而是会将Forth词在词典中的地址保存到一个临时的冒号词定义保存区中。当解释器遇到;时,完成冒号词的定义,并将该词加入到词典中。

cnforth与传统Forth系统的区别

cnforth之所以不能称为一个真正的Forth系统时有原因的,关键区别在于词典部分的实现。传统Forth的词典是类似数组一样的结构,而cnforth是使用了单向链表实现的。

使用单向链表实现词典的好处是词结构体中的成员可以是一个指向动态分配内存的指针。这样就没有词典空间不够的问题,而且分配词空间和释放词空间也很简单。但链表实现的缺点是无法做到传统Forth系统那样,按地址运算去修改词典中的成员。传统Forth系统的冒号词定义是直接在词典空间中按地址加减去操作的。足够底层的操作可以让Forth用简单的核心词去实现很多高级的功能,这就是Forth的优势所在。cnforth就缺少了一个关键的底层操作优势,所以只能称为一个Forth解释器。而不是真正的Forth系统。

下一步的打算

cnforth的下一步打算是,修改词典的实现方式。把通过链表实现的词典结构修改为通过数组来实现,以获得Forth最大的优势。底层的可操作性与高级语言的灵活性就是Forth系统的精髓。

2016-02-02


上一篇: 2016新年新目标 下一篇: 股票补仓问题计算