FORTH 中有一组用户变量,由这组变量记录和保存程序的运行环境。DP 指向词典区的下一个可用地址。SP0 指向参数堆栈的起点。RP0 指向返回堆栈的起点。
SP@ | (- addr) | 参数堆栈指针 |
SP! | ( n - ) | 把参数堆栈指针设置成规定的数值 |
RP@ | (- addr) | 返回堆栈指针 |
RP! | (n - ) | 把返回堆栈指针置为规定的数值 |
: QUIT FORTH 的主要循环。接收来自终端的输入并解释执行,如果成功则显示“ok”.
SP0 @ ' TIB ! 置终端输入缓存区在参数堆栈上方。
BLK OFF 令 BLK 为0,处理来自终端的输入。
[COMPILE] [ 令 STATE 为0,使系统处于解释状态。
BEGIN 进入 FORTH 主要循环。
RP0 @ RP! STATUS 初始化返回堆栈指针。送出一个回车换行。
QUERY 催促使用者从终端输入下一行并将输入行传送到 TIB 中。
RUN 处理所接收的行。
STATE @ NOT 如果 STATE 为0,系统处于执行状态。
IF ." OK" THEN 显示出信息"ok"。
AGAIN ; 无穷循环:一行处理完毕后要求得到下一行。
: RUN ( - ) 改进了的解释程序,运行分行输入一个冒号定义。 STATE @ IF 若 STATE 不为0。系统必须处于编译状态。
] 调用编译程序。
STATE @ NOT 编译完一源行后再次检查 STATE 之值。
IF INTERPRET THEN 若系统已脱离了编译状态,那么就执行该行的剩余部分,否则退出。
ELSE INTERPRET STATE 为0,执行命令
THEN ;
RUN 的过程就是: IF 编译 ELSE 执行 THEN ; |
: INTERPRET ( - ) forth 解释程序循环:分离出输入流中的词,如果它在词典中有定义,则执行之。否则将其转换为一个数字并放置到参数栈上。 BEGIN ?STACK 检查堆栈有无上溢或下溢 DEFINED 取出输入流中的下一个词,返回它的 cfa 及一个标志 IF EXECUTE 如果该词已被定义,则执行 ELSE NUMBER 否则转换成为一个数字 DOUBLE? 它是一个双精度数吗? NOT IF DROP THEN 不是就丢弃它的高 16 位,仅保留低 16 位 THEN FALSE 在堆栈上为 DONE? 留下一个 FALSE;解释程序死循环,一直在运行 DONE? 到了行的末端了? UNTIL ; 如果已到行结束处,退出循环;否则再次循环去处理下一词。 |
// DEFINED 首先取出输入流中的下一个词并把它放到词缓冲区中,然后再词典中搜索该词,若该词在词典中存在,则把它的 cfa 放在堆栈上,并在其后跟上一个为真标志。然后就是 EXECUTE 接过堆栈上的 cfa 执行该定义。如果该词不在词典中,控制程序就传给命令 NUMBER ,以期待把缓冲区中的字符串转换成为一个数字。
在循环开始处 ?STACK 检查堆栈是否有溢出发生。若有溢出系统就被迫转去执行 ABORT,于是一切就从新开始。如果在数字转换过程中遇到错误,系统也同样转去 ABORT 处执行。这两种情况就是非正常脱离解释循环的条件。
: ?STACK ( - ) 检查参数堆栈是否上溢或下溢,若溢出则控制返回终端。 SP@ 取出现行堆栈指针的值 SP0 @ 取出栈底的位置 SWAP U< 检查是否下溢 ABORT" STACK Underflow" 若下溢则执行 ABORT" SP@ PAD PAD 之值同时也是参数栈顶的上限 U< 检查是否上溢 ABORT" Stack Overflow" ; 若上溢则也执行 ABORT" |
FORTH 工作的主要轮廓是一个二重循环:外循环是 QUIT 循环;内循环是 INTERPRET 循环。FORTH 启动后即执行 QUIT ,QUIT 选择终端作为输入设备,调用 QUERY 等待使用者从键盘输入一命令行。输入行送至终端输入缓冲区后,QUIT 调用 RUN 处理已接收进来的命令行。RUN 有两个分支:若系统处于编译状态,则 RUN 调用编译程序对所接收的源行进行编译,当从键盘上键入一个冒号开头的定义时,就进入 RUN 的这一个分支;若系统处于解释状态(又叫执行状态),则调用解释程序 INTERPRET 。INTERPRET 调用 DEFINED ,DEFINED 有两个任务:检测出输入流中下一个词并把它复制到词典缓冲区( WORD);再词典中搜索放在词缓冲区中的词( FIND )。// WORD 首先调用 PARSE-WORD ,PARSE-WORD 能够确定输入流来自哪一个输入缓存区。因此文本解释程序不仅仅能处理来自终端的源行,而且能够处理来自磁盘块的源行。输入流不能输入太多字符,如果输入流耗尽,FORTH 就退出 INTERPRET 循环而回到 QUIT 外循环。