基本介紹
- 中文名:Piet
- 屬於:是一種非常深奧的編程語言
- 使用:顏色編寫代碼
- 設計原則 :程式代碼表現為抽象藝術的形式
特點
介紹
設計原則
程式代碼表現為抽象藝術的形式
語言概念
調色板
#FFC0C0 light red | #FFFFC0 light yellow | #C0FFC0 light green | #C0FFFF light cyan | #C0C0FF light blue | #FFC0FF light magenta |
#FF0000 red | #FFFF00 yellow | #00FF00 green | #00FFFF cyan | #0000FF blue | #FF00FF magenta |
#C00000 dark red | #C0C000 dark yellow | #00C000 dark green | #00C0C0 dark cyan | #0000C0 dark blue | #C000C0 dark magenta |
#FFFFFF white | #000000 black |
亮度漸變:light->normal->dark->light
注意light比dark更dark,反之亦然(這是計算差值方法的需要,如green比yellow dark 1,cyan 比 yellow dark 2 但yellow 比 cyan dark 4)。亮度規則也類似。
白色黑色不納入漸變規則。
也可以使用20這種外的顏色,但這些顏色會被當做這20種顏色中的一種,具體是哪一種依賴具體實現。一般是白,也可能是黑。
codel
Piet代碼是認可的顏色組成的圖形。在語言中,每個單獨的像素有其功能,所以編程中常將圖形放大以方便的操作和觀察每個一個像素。此時出現像素有兩個意思,一個是一塊很多像素組成的圖形表示的原圖的一個像素;另一個則是放大圖的像素本身(元素一個像素放大圖的眾多像素之一)。術語codel指代前者,即原圖的像素而不是顯示的像素(雖然顯示的像素有時候就是原圖的像素)
色塊
Piet的簡單代碼單位是色塊。一個色塊是一個由任意數量相鄰的codel組成的形狀,被其他顏色分隔。只是對角連線不算相鄰。一個色塊可以是任意形狀,也可以有洞在裡面,這個洞對有洞的色塊本身沒有任何影響。
Stack
Piet使用stack儲存所有數據。數據只有整數,雖然這些整數可以被讀取或以unicode之類的格式被合適的命令列印出來。
程式執行
Piet解釋器由圖形左上角的codel開始執行。解釋器維護一個方向指針(DP),被初始化為向右。DP指針可以指向上下左右。解釋器還維護一個codel選擇器(CC),初始指向左。CC可以指向左或右。DP和CC指針常常改變程式的流程。
解釋器按照以下規則遍歷色塊:
1.解釋器按照DP指針所指的方向選擇當前所在圖形的在此方向最遠的邊(如對正方形DP指針向右,就是選擇到正方向最右的一列codel)
2.按照CC指針偏移的DP指針所指定的方向,選擇到這個邊在這個方向的最遠的codel。(繼承上述例子,若CC指針向左,則選擇最右一列codel的最上的codel。因為向右的左是向上)
3.選擇了一個codel,這個codel的DP指針方向的前一個codel應該是另一個色塊。將程式轉移到這個新的色彩格,這將引發命令的執行等。
(總之,你可以想像自己站在程式上,先按DP指針走到當前所在色彩格上最遠的一排/列codel。然後按CC指針轉向,繼續往前走到一個特定的codel。再轉回DP指針向前踏出一步)
以上流程不斷重複直到程式結束。
語法成分
數字
每個非黑或白的色塊的codel總個數代表一個數字。注意非正整數不能被以這樣的方式直接表示出來,雖然它們可以被命令構造出來。當解釋器遇到一些數字時,並不直接做任何事,尤其注意不會把數字自動壓入stack里,壓入操作是一個明確的命令。
黑色色塊和邊
圖形邊緣視為黑色色塊。黑色色塊限制程式的運行。當程式嘗試按照一組DP/CC指針進入一個黑色色塊時。動作將停止並將CC指針調換(左->右或右->左)並再次嘗試。若一個DP指針的兩種CC指針都導致進入黑色色塊,則將DP指針順時針旋轉90度再次嘗試,包括對此的DP指針的CC指針兩種情況。如此這般若8個可能的選擇都將進入黑色色塊,程式終止。
白色塊
跳轉判定的第三階段,若跳轉進的是一個白色codel,不立即取得當前codel代表的色塊像正常流程那樣,而是繼續向前(即DP的指向)一直移動。若移到一個彩色codel,完成流程。若移到一個白色codel,繼續移動。若移到一個黑色codel,返回上一個移動到的白codel,並將這個codel視為一個只有一個codel的色塊,重新進行跳轉轉移的三步直到結束或到達一個色塊。
但這個“視為”對命令的執行無影響,做改變數計算的仍是最開始移動的色塊。
命令
一個色塊跳轉發生後,一個命令被執行。跳轉前的色塊的codel個數可以作為命令的參數。具體哪個命令被執行則由跳轉前的塊和跳轉後的塊色相的漸變的變化量和亮度的漸變的變化量兩者一同決定。見表
Lightness change | |||
Hue change | None | 1 Darker | 2 Darker |
None | push | pop | |
1 Step | add | subtract | multiply |
2 Steps | divide | mod | not |
3 Steps | greater | pointer | switch |
4 Steps | duplicate | roll | in(number) |
5 Steps | in(char) | out(number) | out(char) |
命令的解釋見下:
push:將跳轉到的色塊的codel值加入stack。
pop:將stack彈出並丟棄。
add:將stack頂兩個值彈出後將其相加和壓回。
subtract:將stack頂兩個值彈出後將其相減差壓回。
multiply:將stack頂兩個值彈出後將其相乘積壓回。
divide:將stack頂兩個值彈出後將其相除商後壓制。
mod:求余,同上,
not:彈出stack頂的值,若此值為0,壓回1.否則壓回0.
greater:彈出stack頂的兩個值,若頂第二個值大於頂第一個值則壓回1,否則壓回0.
pointer:彈出stack頂值並將DP順時針旋轉90度值數。若為負值,則逆時針旋轉其絕對值數的次數。
switch:彈出stack頂值並將CC指針轉換數值的絕對數值的次數。
duplicate:彈出stack頂值,複製一個後將兩個壓回去。
roll:彈出stack頂兩個值(記為x1,x2),在新stack的x1後的位置插入x2.
in:輸入一個數字或字元(數字被當做字元與被當做字元是不一樣的)並壓入stack中。分為兩個模式。
out:以數字或字元形式(同上)輸出從stack頂彈出的值。