Whitespace

<image>

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

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

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

## 语法

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

### IMP

IMP（Instruction Modification Parameter）是Whitespace语法中的一种特色，在每个指令前要先指定IMP，接着再选择IMP中的个别指令。

IMP｜意义

Space｜堆叠操作

TabSpace｜数学运算

TabTab｜堆积存取

LF｜流程控制

TabLF｜I/O

### 数字

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

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

### 堆叠操作

堆叠操作指令的IMP是Space，因为是一种常用的指令，所以有最简短的IMP。

这里有四种操作方式。

指令｜参数｜意义

Space｜数字｜将某个数字放入堆叠

TabSpace｜数字｜将堆叠里的第n个元素复制到堆叠顶

TabLF｜数字｜将堆叠里的第n个元素从堆叠里移除

LFSpace｜复制堆叠最上方的元素

LFTab｜交换两个堆叠最上层的元素

LFLF｜屏弃堆叠最上层的元素

### 算术

算术指令的IMP是TabSpace，会取堆叠最上方的两个元素做运算，并以运算结果取代原本的元素。

先进入堆叠的元素将被视为运算子左方的算子。

指令｜参数｜意义

SpaceSpace｜加

SpaceTab｜减

SpaceLF｜乘

TabSpace｜整数除法

TabTab｜模运算（取余数）

### 堆积操作

堆积操作指令的IMP是TabTab，可以将物件存入堆叠中的特定地址，也可以取得堆叠中的特定地址的物件。

要储存一个物件至堆积里，先将位址放入堆叠，而后放入物件的值再执行储存指令。

要取出堆积里的一个物件，将位址放入堆叠而后执行取回指令，取回的值会被存放在堆叠的最上方。

指令｜参数｜意义

Space｜储存

Tab｜取回

### 控制流程

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

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

指令｜参数｜意义

SpaceSpace｜标签｜标记程式中某一个流程

SpaceTab｜标签｜标签呼叫子程序

SpaceLF｜标签｜从某标签无条件跳跃至另一标签

TabSpace｜标签｜如果堆叠顶为0则跳跃至某标签

TabTab｜标签｜如果堆叠顶为负数则跳跃至某标签

TabLF｜结束目前子程序并跳跃回呼叫者

LFLF｜结束程式

### 输入与输出

输入与输出指令的IMP是TabLF，可以进行资料流的输入输出。

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

指令｜参数｜意义

SpaceSpace｜输出堆叠最上方的字元

SpaceTab｜输出堆叠最上方的数字

TabSpace｜读入一字元并写入堆叠顶的位址里

TabTab｜读入一数字并写入堆叠顶的位址里

## 范例

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

```
S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>T<span style="background:#9999ff">&#9;</span>L&#10;T<span style="background:#9999ff">&#9;</span>L&#10;S<span style="background:#ff9999">&#32;</span>S<span style="background:#ff9999">&#32;</span>L&#10;L&#10;L&#10;
```