输出操作符
TYPE ( addr 字符数 --- ) 从addr将计数字符串发送到选定的输出设备。OUT中加上字符数。如果“字符数”为零,没有发送。
S0 ( --- addr ) 含有“堆栈指针”初始值的用户变量。输入信息缓冲区中的起始地址是由用户变量S0保存的。
//TYPE 操作直接取出了输入缓冲区的数据,也就是我们刚才输入的数据。
名域 链域 代码域 参数域
//这个图有错误,名域+链域+代码域=3,后面." 和表示SAMPLE的个数6占两个,一共是5个。 ' 找到TEST在词典中的地址,偏移5来到S的首地址,6 TYPE 打印出 SAMPLE 。
从磁盘输出字符串
BLOCK 可以把一给定块复制到可利用缓冲区并把该缓冲区的地址压入堆栈。例如:要打印第16块的第0行,可以键入:CR 16 BLOCK 64 TYPE
BLOCK ( u --- addr ) addr是含有块u指定的缓冲区地址,假如该缓冲区具有的块不是块u,并且已经被UPDATE更新。则在指定该缓冲区之前就将其内容写入大容量存储器。一个给定的块不可以被指配给一个以上的缓冲区。如果u不是可利用的块号,就存在错误条件。如果u是一个没有被访问过的块,则DISK-ERROR就置为“真”。仅在由BLOCK或BUFFER最后引用的缓冲区中的数据才是有效的。块缓冲区的内容不应改变,除非该变动可以被转移到大容量存储器中。
要打印第八行只要(8*64);
-TRAILING ( adr u1 --- adr u2 ) 通过把u1(原始字节计数)减少为u2(被缩短的字节计数),删除起始地址为 adr 的字符串的尾随空格。
//这里 -TRAILING 把原始的53字节数减到20个字节数,刚好是出去了尾部的所有空格
内部串操作符
移动字符串或数组需要三个自变量:源地址、目的地址和计数。
MOVE ( addr1 addr2 u --- ) 从addr1开始,逐单元的把u个字的内存区域复制到addr2开始的内存区域。从addr1开始移动,向内存高区(就是从要复制内容的第一个开始向后移动)移动。 |
CMOVE ( addr1 addr2 u --- ) 功能和上面一样,只不过是逐字节移动。 |
CMOVE> ( addr1 addr2 u --- ) 功能和上面一样,只不过是从串尾开始移动,向内存低区(就是从要复制内容的最后一个开始向前移动)移动。这对于向较高地址传送是有溢的。 |
addr1 addr u 顺序必须是 源地址 目的地址 计数 |
如果要把某个缓冲区的全部内容移进 PAD ,尽管按单元寻址的机器上若用逐单元移动的方法进行要快(第一种),但是最好还是用逐字节的(第二种)
//词 CMOVE> 允许我们把串移动到较高的内存区域而且允许覆盖源区。
比如要把一个串向右移动一个字节 <CMOVE 要改成
//向内存高区移动最后只剩下一个H,向内存低区移动成功。
//把 PAD 中的1024个字节都存入空格。
单个字符输入
KEY ( --- c ) 留下一个终端键入字符的ASCII码。(等待从终端键入一个字符,并把相应的 ASCII 码存入堆栈的低位字节)
直接指向 KEY ,这时光标先前进一格,但终端不显示"ok",它正在等待输入。这时候如果接着按下一个字母,屏幕将显示"ok"。这时栈中存放了输入字母的ASCII码。(回车符的ASCII码是13)
KEY 可以用在定义内部。执行定义期间当遇到 KEY 时将停止执行,知道接受到输入字符时为止。
eg:定义个词,从当前块开始显示给定数量的块的内容,在显示下一块之前等待我们按下任意键。
SCR ( --- addr ) 具有最近由 LIST 引用的屏面号的变量。变量里面存放的是最近引用的屏面号。
//显示从当前引用屏面号到知道屏面数的所有屏面。DROP 丢掉键入的字母ASCII码。先1 LIST 然后执行 10 BLOCKS 将显示1-10的屏面。
改进:当键入回车(ASCII == 13)时就终止显示屏面.
串输入命令
EXPECT ( addr u -- ) 从终端将字符移到地址addr,直到"回车"或者全部字符计数已被接受。回车不存入存储器。一个"空字符"被附加在文本串的末端。实际收到的和被存入存储器中的字符将被显示。(等待从键盘输入u个字符(或一个回车)。并把他们存贮在addr开始的区域) |
WORD ( c --- addr ) 从输入流中读一个利用某字符c(通常用空格)作为界限符的词。把该串传送到HERE中的地址开始的区域,该区域中的第一个字节存贮该串的字符个数,并把HERE中的地址压栈。先行定界符会被忽略。 |
词 EXPECT 使得任务终止执行,等待从磁盘输入给定个数的字符或一个回车符,无论谁先满足都行。然后把输入文本存入给定地址开始的区域。
eg:等待输入指定个数的字符,并把他们存入输入信息缓冲区。(这个短语也被用在 QUIT 的定义中为 INTERPRET 取得输入)
//第一个回车等待输入5个字符,输入5个自动结束显示ok;第二个等待输入50个,但是可以回车提前终止。
文本解释程序扫描输入信息缓冲区是通过短语 32 WORD 来查找的。32是"空格"的十进制ASCII码值。WORD 扫描输入信息缓冲区以寻找给定的界限符(输入信息缓冲区敲入回车的时候自动过滤多余的空格);然后把此界限符分隔的子串传送到另一个缓冲区中,该缓冲区的第一个字节存放子串的字符个数;最后把缓冲区的首地压栈,这个时候 INTERPRET 就可以拿到这个地址去找到对应的词。WORD 的缓冲区通常是从词典指针 DP 开始,因此给定的地址是 HERE 。
注:你可以用 EXPECT 从诸如测量设备这样的装备中接受数据。由于提供了地址和计数,这样的数据能直接读入数组。在单用户系统中你可以把数据读入缓冲区而存入磁盘。但在多用户系统中,你必须先用 S0 然后再送到缓冲区,因为其他用户可能要使用"你的"缓冲区。
>IN ( --- addr ) 具有输入流中当前字符偏移量的变量的地址。
当你从终端直接执行 WORD 时,它将扫描从S0开始的输入信息缓冲区,随着扫描,它向前推进缓冲区的指针 >IN ,以使每执行一次 WORD 都能扫描到输入流中的下一个词。
>IN 是一"相对指针",即它包含的不是实际地址而是将要加在实际地址上的位移量。在上面的例子中,实际地址是S0,WORD 已扫描过输入信息缓冲区的"STAR"之后,>IN 的值是5。
扫描的时候 WORD 忽略初始的界限符(直到遇到任何其他字符时为止)。WORD 传送子串时包含串结尾的一个空格,但在字符计数中不包括这个空格。
数字输入转换
在终端键入一数字是,FORTH自动地把这一字符串转换成二进制数值并把它压入堆栈。FORTH 还提供两个命令,这两个命令允许你把从任何内存单元开始的一个字符串转换成二进制数值。
CONVERT ( +d1 addr1 --- +d2 addr2 ) 把从addr1+1开始的文本转换成相应数基的二进制数值。新的数值将被累加进+d1形成+d2,转换直到遇到第一个不能转换的字符为止。第一个不能转换字符的地址存放在addr2. |
NUMBER ( addr --- d ) 使用当前的基数,将在地址addr中具有先行字符计数和结尾ASCII空白符(20H)或0的字符串转换为带符号的双字长数(从addr+1开始文本转换)。如果文本中遇到小数点,则它的位置将在BPL中给出,但不发生其它影响。如果数字转换不可能,将给出错误信息。 |