Whitespace是一种深奥的编程语言。它由Edwin Brady和Chris Morris开发,于2003年4月1日发布。大部分的现代程式设计语言都不将空白字元视为语法的一部分。但Whitespace却只视空格(space)、制表符(tab)和换行(line feed)为语法元素,它的直译器会忽略其他所有字元。在没有特殊标记下,一段没有注释的Whitespace程式码应该是完全不可见的[1]

带语法高亮的一段Whitespace程序

Whitespace是种基于堆叠指令式程式语言。运行其程式的虚拟机器具有一个堆叠(stack)和堆积(heap)作为资料结构。使用者可自由将整数推进堆叠中(Whitespace目前并不支援浮点数或其他型别),亦可将堆积作为变数的暂存区。

这种语言有和Brainfuck一样的优点,能方便地撰写程序注释,写的注释只要不包含三种语法字元,直译器就会直接跳过。还有,借助这种语言,可以在满篇空白的代码中插入一篇文章,从而在看起来完全无关的文章中隐藏一段代码。对于一些需要保证安全性的工作来说,这种语言帮助很大,因为它可以防止别人把代码打印出来拿走。

语法

撰写Whitespace程式时,使用者透过三种语法字元的排列去表达指令,进而操作虚拟机器中的堆叠与堆积。这些指令皆分为三个部分:IMP、指令和参数。IMP决定接下来要使用的指令是哪一种类型,指令决定执行的具体工作,而部分指令需要额外的参数[1]

IMP

IMP(Instruction Modification Parameter)是Whitespace语法中的一种特色,在每个指令前要先指定IMP,接著再选择IMP中的个别指令。

IMP 意义
[Space] 堆叠操作
[Tab][Space] 数学运算
[Tab][Tab] 堆积存取
[LF] 流程控制
[Tab][LF] I/O

数字

在Whitespace中,许多指令都需要在最后加上一个整数作为参数。整数由一串不限长度的字元表示,格式为:

  • 第一个字元表示数字的正负,空白为“正”而制表符为“负”。
  • 之后的字元以二进位表示数字,空白代表数位上的“0”,制表符则代表“1”。
  • 数字结束时,须以换行标示。

堆叠操作

堆叠操作指令的IMP是[Space],因为是一种常用的指令,所以有最简短的IMP。 这里有四种操作方式。

指令 参数 意义
[Space] 数字 将某个数字放入堆叠
[Tab][Space] 数字 将堆叠里的第n个元素复制到堆叠顶
[Tab][LF] 数字 将堆叠里的第n个元素从堆叠里移除
[LF][Space] - 复制堆叠最上方的元素
[LF][Tab] - 交换两个堆叠最上层的元素
[LF][LF] - 屏弃堆叠最上层的元素

算术

算术指令的IMP是[Tab][Space],会取堆叠最上方的两个元素做运算,并以运算结果取代原本的元素。 先进入堆叠的元素将被视为运算子左方的运算元。

指令 参数 意义
[Space][Space] -
[Space][Tab] -
[Space][LF] -
[Tab][Space] - 整数除法
[Tab][Tab] - 模运算(取馀数)

堆积操作

堆积操作指令的IMP是[Tab][Tab],可以将物件存入堆叠中的特定地址,也可以取得堆叠中的特定地址的物件。 要储存一个物件至堆积里,先将位址放入堆叠,而后放入物件的值再执行储存指令。 要取出堆积里的一个物件,将位址放入堆叠而后执行取回指令,取回的值会被存放在堆叠的最上方。

指令 参数 意义
[Space] - 储存
[Tab] - 取回

控制流程

控制流程指令的IMP是[LF]。子程序可以用标签(label)作标记,进行有条件或无条件的跳转,可用于实作条件判断或回圈等复杂构造。标签是一个整数,由指令的参数栏输入,所有标签必须是独一无二的,不能重复。

这一类指令也包含了“结束”。所有程式都必须借由[LF][LF][LF]这条指令才能让直译器正确地结束程式。

指令 参数 意义
[Space][Space] 标签 标记程式中某一个流程
[Space][Tab] 标签 标签呼叫子程序
[Space][LF] 标签 从某标签无条件跳跃至另一标签
[Tab][Space] 标签 如果堆叠顶为0则跳跃至某标签
[Tab][Tab] 标签 如果堆叠顶为负数则跳跃至某标签
[Tab][LF] - 结束目前子程序并跳跃回呼叫者
[LF][LF] - 结束程式

输入与输出

输入与输出指令的IMP是[Tab][LF],可以进行资料流的输入输出。

输入指令会取用堆叠最上方的数字作为地址,将输入的物件存入堆积。输出指令可输出堆叠最上端的数字,或输出堆叠最上端的数字所对应的ASCII字元

指令 参数 意义
[Space][Space] - 输出堆叠最上方的字元
[Space][Tab] - 输出堆叠最上方的数字
[Tab][Space] - 读入一字元并写入堆叠顶的位址里
[Tab][Tab] - 读入一数字并写入堆叠顶的位址里

范例

这是一个能输出“Hello, world!”的简单范例程式,每个空白制表符和换行字元被分别以“S”、“T”和“L”表示:

S S S T	S S T	S S S L
T	L
S S S S S T	T	S S T	S T	L
T	L
S S S S S T	T	S T	T	S S L
T	L
S S S S S T	T	S T	T	S S L
T	L
S S S S S T	T	S T	T	T	T	L
T	L
S S S S S T	S T	T	S S L
T	L
S S S S S T	S S S S S L
T	L
S S S S S T	T	T	S T	T	T	L
T	L
S S S S S T	T	S T	T	T	T	L
T	L
S S S S S T	T	T	S S T	S L
T	L
S S S S S T	T	S T	T	S S L
T	L
S S S S S T	T	S S T	S S L
T	L
S S S S S T	S S S S T	L
T	L
S S L
L
L

外部链接

参考资料

  1. ^ 1.0 1.1 Whitespace. Esolang. [2023-11-27]. (原始内容存档于2023-09-21) (英语).