返回入门教程首页 主页 | 开发工具 | 应用芯片 | 核心模块  
 
   
 

Forth 初学者指导 (使用Win32Forth)

原著 J.V. Noble

编译 Forth 中文网, ForthChina.com

原文 Win32Forth 系统联机在线文档

一些字符串的说明

像在其它语言中一样,字母数字串在 Forth 中用存储器中的连续数组表示,每个存储器单元是一个“字符“。传统上,字符用 ASCII 或 EBCDIC系统编码,每个编码占一个字节,共有 256 个字符。随着对非拉丁字母编码的需要(如汉语等),提出了两字节的编码方法,称为 Unicode ,它允许 65535 个不同的字符。

传统的 Forth 串由一个计数字节和多达 255 个字节的字母数字串组成(通常使用 ASCII 编码)。在 ANS Forth 中放弃了这种方法,具体的字符串存储方式依赖于实现。然而, ANS Forth 包含了一些字,可以使我们用与实现无关的方法处理字符串。

大多数 ANS Forth 系统 (Win32Forth 就是其中之一 ) 定义 S" 具有交互和解释行为。这就是说,如果我们

S" This is a string!" CR TYPE

我们会得到

This is a string! ok

发生了什么事情? S" This is a string!" 创建一个串,字符的开始地址是 ”c-address” ,并有一个 ”count” 说明其中有多少字符(包含空格)。地址和计数都放在堆栈上。对应的堆栈说明是:

S" This is a string!" ( -- c-addr u)

( 计数是一个无符号的数 u ,因为负值作为串的长度是没有意义的) 。

CR 的意思是“插入一个回车”, TYPE 的意思是“从 c-addr 输出 u 个字符到屏幕上”

练习 :

使用你学到方法编写 “Hello world!” 程序

按你自己应用程序的需要、定义自己的字符串操作字集也是非常方便的。例如,我已经编写了一个程序把类似 Fortran 格式的公式翻译成 Forth 代码,结果可以输出到屏幕上(用于测试)或者嵌入到 Forth 定义中。在计算公式中甚至还可以有变量,提供所有定义的变量和数值。为了完成这个任务,串应该大于 256 个字符,所以我定义了我自己的字。

我现在希望进行“格式化的数字输出“。在许多计算机程序中,不论内部怎么表示,都希望数值能够以特殊的格式输出。比如,会计程序可能需要以通常的“美元和美分” (dollars-and-cents) 格式输出钱币的数量。完成这个任务的字是

# , <# , #S , #> , SIGN HOLD

它们没有任何解释性状态的行为,只能用在一个字的定义中。这里是一个例子:假设我们编写了一个会计程序,因为大多数用户不会涉及超过 $100,000,000 的帐务,我们可以使用 32 位的整数来表达美元和和美分(这样可以表示多达 ±(2 31 —1) = ±2147483647 美分 ) 。在 ANS 兼容的系统中,有符号的双精度数最少 32 位长(尽管在 32 位计算机上,它们可以是 64 位长)。所以我们将使用双精度数以确保我们的程序可以运行在任何 ANS 兼容的系统上。

从键盘上输入双精度整数的格式是在其中包含一个十进制小数点,比如

-4756.325 ok

让我们来定义一个字输出双精度整数。第一部分将被翻译成一个字母数字串,把它放到 c-addr u

: (d.$) ( d -- c-adr u) TUCK DABS <# # # [CHAR] . HOLD #S ROT SIGN ##> ;

正如堆栈注释 ( d -- c-adr u) 所显示的那样 , (d.$) 消耗堆栈上一个 ( 无符号 ) 双精度整数并留下串数据,它可以被字 TYPE 用来打印到屏幕上:

4376.58 (d.$) CR TYPE

4376.58 ok

-4376.99 (d.$) CR TYPE

-4376.99 ok

很有必要研究每个部分是如何工作的。一个双精度数在堆栈上占用两个单元,最高有效位在 TOS 中。这样,字 TUCK 就把最高有效部分(包含代数符号)放到 d 的上面并使用 DABS 转换 d |d| . 接着, <# 开始构造一个字母数字串的工作。两个 # 剥离两个最低有效位数字,并把它们放入串中。短语 [CHAR] . HOLD 为串加入一个十进制的小数点。

[CHAR] 构造字符的表示方法,作为一个数字文字(ASCII 是 46). HOLD 然后把它加入到构建的串中( HOLD <# #> 之外,没有任何其它的意义) ,字 #S 转换其它的数字,并把它们放入串中。

(将近) 结束时, ROT d 的最高有效部分(包括它的符号)放入 TOS , SIGN 把代数符号加入到串的开始。 (同样,SIGN 只在 <# #> . 之间才有意义)

最后,字 #> 清除所有的东西,在堆栈上留下 c-addr u 供显示或者其它用途。

练习 :

a) 你怎样在输出的数字前面加入一个符号 ( $ ) ?

b) 你怎样把一个负号显示在括号里而不是用一个负号作为前导,比如 ( 4376.99) 而不是 -4376.99

c) 定义一个字显示一个双精度整数,格式为 dollar-and-cents (美元和美分)

 

 

 

   

(C) ForthChina.com 版权所有 2004-2010
Email:forthchina@163.com