Whitespace
Whitespace是一種深奥的编程语言。它由Edwin Brady和Chris Morris開發,於2003年4月1日發佈。大部分的現代程式設計語言都不將空白字元視為語法的一部分。但Whitespace卻只視空格(space)、制表符(tab)和換行(line feed)為語法元素,它的直譯器會忽略其他所有字元。在沒有特殊標記下,一段沒有注釋的Whitespace程式碼應該是完全不可見的[1]。
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.0 1.1 Whitespace. Esolang. [2023-11-27]. (原始内容存档于2023-09-21) (英语).