More WhiteSpace语言

昨天写了《什么是whitespace》简略介绍了whitespace语言的特点,感觉介绍的太简略了,今天再补充一些内容。

whitespace语言唯一识别的有效字符就是空格(ASC码为32)、Tab制表符(ASC码为9)和换行符(ASC码为10)。之所以只使用LF换行符,是为了避免DOS/UNIX文件转换时发生CR/LF问题。(注:CR/LF问题是指在DOS系统下以CR+LF表示一行结尾的换行符,而UNIX系统下只使用LF,这样在两种系统下交叉处理文件就会出现一些兼容问题)

这种whitespace语言是一种基于栈的命令解释语言。每个命令由一系列上面提到的那三种字符组成。
命令关键字说明:
[空格]:表示栈操作 (具体使用需要配合参数)
[Tab][空格]:表示算术操作
[Tab][Tab]:堆操作
[LF]:表示流控制
[Tab][LF]:输入输出操作

支持whitespace程序运行的虚拟机提供堆栈支持。开发人员可以自由地将整数(目前不支持浮点数和实数支持)压栈,也可以将变量和数据结构存储在堆中。

如上举例的许多命令都需要数字或标号(标号将在后面解释)作为参数。数字可以是任意bit宽的,用一串[空格]和[Tab]来表示,并以[LF]结尾。[空格]表示二进制0,[Tab]表示二进制1。数字的正负号由第一个字符表示,[空格]表示正,而[Tab]表示负。注意没有其他语言那种补码设计(负数取反加1),它就是简单的表示正负号。

标号就是简单的以[LF]结尾的[空格]和[tab]串(就是一个数字)。

这里没有名字空间(namespace,ANSI标准C++有使用)一说,所有的标号都必须是全局独立唯一的。

栈操作 ([空格]关键字的使用):
栈操作是最常用的操作命令之一,因此设计为使用非常短的[空格]作为命令关键字。有以下集中栈操作指令:

1:[空格][数字] 这个表示将数字压栈。
2:[LF][空格] 表示复制栈顶的元素
3:[Tab][空格][数字] 表示拷贝栈中的第n个元素到栈顶
4:[LF][Tab] 表示交换栈顶的两个元素
5:[LF][LF] 表示丢弃栈顶元素
6:[Tab][LF][数字] 表示保持栈顶元素,slide off(不知道啥意思:)) n个元素

拷贝和slide命令是whitespace3.0的扩展实现,用来辅助实现递归循环功能。

算术指令 ([Tab][空格])
算术指令用来对栈顶的两个元素做数学计算操作,然后用计算结果替换这两个元素。先入栈的那个元素是计算的左值。

[空格][空格]? 加
[空格][Tab]? 减
[空格][LF]?? 乘
[Tab][空格]? 除(整除)
[Tab][Tab]? 取模

堆操作命令 ([Tab][Tab])

堆操作命令根据栈上的地址来存储或读取元素。要存储一个元素入堆,先要把元素地址压栈,然后运行存储命令。要读取一个元素入栈,先要把元素地址压栈,然后运行读取命令,这样就把那个元素读出并放到了栈顶。
[空格] 存储命令
[Tab] 读取命令

流控操作 ([LF])
流控操作(程序流控制,类似if eles, while等功能)。子程序用标号标识,这些标号就是一些条件成立或不成立后跳转的目标,这样,就可以实现循环功能。程序必须使用[LF][LF][LF]来结尾,这样程序解释器就能完整地退出程序。

[空格][空格]标号?? ?在程序某处标记一个标号
[空格][Tab]标号?? ?调用标号指示的程序
[空格][LF]标号?? ?跳向标号指示的程序
[Tab][空格]标号?? ?如果栈顶为空,则跳向标号指示的程序
[Tab][Tab]标号?? ?如果栈顶为负,则跳向标号指示的程序
[Tab][LF]?? ?结束子程序,回到调用者调用子程序处
[LF][LF]?? ?结束程序

输入输出操作 [Tab][LF]
最后,我们要想能够与用户操作就需要输入和输出来读写数字和字符。
[空格][空格]?? ?-?? ?输出栈顶的字符
[空格][Tab]?? ?-?? ?输出栈顶的数字
[Tab][空格]?? ?-?? ?读入一个字符并把它放进栈顶元素指定的地址
[Tab][Tab]?? ?-?? ?读入一个数字并把它放进栈顶元素指定的地址

最后来一个小例子来帮助理解和记忆,它输出从1到10的十个数字:

[Space][Space][Space][Tab][LF]?? ?把数字1压栈
[LF][Space][Space][Space][Tab][Space][Space] [Space][Space][Tab][Tab][LF] ?? ?在此处记录一个标号
[Space][LF][Space]?? ?复制栈顶元素
[Tab][LF][Space][Tab]?? ?输出当前的值
[Space][Space][Space][Tab][Space][Tab][Space][LF] ?? ?把10(LF换行符的ASC码)压栈
[Tab][LF][Space][Space]?? ?? 输出这个10(换行符的ASC码)
[Space][Space][Space][Tab][LF]?? ?把1压阵
[Tab][Space][Space][Space]?? ?加法操作
[Space][LF][Space]?? ?复制这个值 然后我们可以测试它
[Space][Space][Space][Tab][Space][Tab][Tab][LF] ?? ?把11压栈
[Tab][Space][Space][Tab]?? ?减法,当栈中的数值为0时,程序就结束
[LF][Tab][Space][Space][Tab][Space][Space] [Space][Tab][Space][Tab][LF]?? ?如果为0,则结束
[LF][Space][LF][Space][Tab][Space] [Space][Space][Space][Tab][Tab][LF] ?? ?跳回开始的标号处
[LF][Space][Space][Space][Tab][Space] [Space][Space][Tab][Space][Tab][LF] ?? ?设置结束标签
[Space][LF][LF]?? ?清除计算现场
[LF][LF][LF]?? ?结束退出

不要忘记,上面[]都是把不可打印的空格、制表符和换行符用可显示的符号表示出来了,否则,这个程序的真是样子应该是这样的:

请到这里观看

我知道你什么都没看到,whitespace程序就是这样的看不见的程序。你可以把它们高亮显示看一下。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>