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;
```