摘要。
所有這些特殊標記,[
,]
,<<
,>>
,來掃描儀作爲可執行名稱出來。 [
和<<
被定義爲產生標記類型對象(因此它們本身不是運算符,但是它們是在所有運營商都在的systemdict
中定義的可執行名稱)。 ]
和>>
被定義爲像任何其他過程或操作符一樣執行的過程或操作符。這些使用counttomark
運算符來查找左括號。但是,所有這些令牌都被掃描器專門處理,因爲它們是其分隔符集的一部分,所以它們可以識別它們而不會包含空格。
詳情。
這一切都取決於當你看看它。讓我們來看看解釋者對這些令牌的作用。我將用一個字符串來說明這一點,但它對文件的作用是一樣的。
所以,如果你有一個輸入字符串
([4 5 6]) cvx exec
cvx
使得文本對象可執行。該程序流是也被標記爲可執行文件的文件對象。 exec
在執行堆棧上推送一個對象,解釋器在內部解釋器處理循環的下一次迭代中遇到該對象。執行程序流時,可執行文件對象在執行堆棧上處於最頂層。
解釋器使用token
調用掃描儀。掃描程序跳過最初的空格,然後讀取所有非空白字符直到下一個分隔符,然後嘗試將該字符串解釋爲數字,並且失敗它成爲可執行文件名稱。括號是分隔符集的一部分,因此被稱爲「自我分隔」。所以掃描器讀取一個括號字符,停止閱讀,因爲它是一個分隔符,發現它不能是一個數字,所以它會產生一個可執行文件名稱。
Top of Exec Stack | Operand Stack
(4 5 6]) [ |
接着,解釋器循環執行任何可執行(除非它是陣列)。 執行令牌意味着從字典中加載它,然後執行定義,如果它是可執行文件。 [
定義爲-mark-
對象,與定義名稱mark
相同。這在技術上不是操作員或程序,而只是一個定義。自動加載發生的原因是名稱從設置了可執行標誌的掃描器中出來。
(4 5 6]) | -mark-
掃描器然後產生4,圖5和6,其是數字,並獲得直接推到操作數棧。 6由]
定界,該碼流被推回到流上。
(]) | -mark- 4 5 6
的解釋並不執行的數量,因爲它們不是可執行,但它也不過,如果它這麼做的。執行數字的動作僅僅是將其推入堆棧。
然後,最後掃描儀遇到右括號]
。這就是魔術發生的地方。自分隔,不需要任何空白。掃描儀產生的可執行文件名]
和解釋通過加載執行它,它會找出...
{ counttomark array astore exch pop }
或者,也許實際操作者做這個。但是,是的。 counttomark
產生元素的數量。 array
創建一個這樣大小的數組。 astore
用堆棧中的元素填充數組。並且exch pop
一勞永逸地丟棄那個討厭的標記。
對於字典,<<
與[
完全相同。它下降了一個標記。然後,你行了一些鍵值對,並>>
是過程,做一些事情來實現的......
{ counttomark dup dict begin 2 idiv { def } repeat pop currentdict end }
製作一本字典。定義所有的對。彈出標記。產生字典。該版本的程序嘗試通過使其成爲雙倍大小來創建快速字典。將2 idiv
移至dup
之前製作小字典。
所以,爲了得到哲學,counttomark
是你正在使用的操作符。它需要一個特殊的對象類型,它不用於其他任何事情,marktype對象-mark-
。剩下的只是語法糖,讓您訪問這個堆棧計數功能來創建線性數據結構。
附錄
下面是模型解釋器從currentfile
閱讀的過程。
{currentfile token not {exit} if dup type /arraytype ne {exec} if }loop
exec
負責load
ING(和進一步執行)任何可執行的名稱。從這裏可以看出,token
確實是掃描儀的名稱;並且由解釋器循環直接遇到的程序(數組)未被執行(type /arraytype ne {exec} if
)。
在字符串上使用token
可以讓你做真的很酷的東西,但是。例如,您可以使用替代名稱動態構建過程主體。這非常像一個lisp宏。
/makeadder { % n . { n add }
1 dict begin
/n exch def
({//n add}) token %() {n add} true
pop exch pop % {n add}
end
} def
token
從字符串讀取整個過程,替換立即評估名稱//n
以其當前定義的值。這裏注意到掃描器一次全部讀取一個可執行數組,在返回之前在內部有效執行[
... ] cvx
(在某些解釋器中,像我自己的xpost
,這允許您繞過堆棧大小限制來構建數組,因爲數組是建立在單獨的內存中的,但2級垃圾收集使得這在很大程度上不相關)。
還有bind
運算符,它通過用運算符對象本身替換運算符名稱來修改過程。這些技巧可以幫助您在快速關鍵的過程中分解名稱查找(如內部循環)。
給了你答案。良好的信息。謝謝! – juFo 2013-02-11 08:21:36
@juFo不,謝謝*你*。好問題。這是一個有趣的小角落。 – 2013-02-11 08:26:56
但是關於[[4 5 6])會導致只是一個字符串[4 5 6]或將實際上導致一個空字符串(因爲它作爲一個數組執行?) 因爲我從來沒有想過它那樣(在一個字符串中) – juFo 2013-02-11 08:32:14