解釋器原理

 

文字解碼完後,你能夠想象有一條紙帶,上面寫着代碼。從左側向左拉動紙帶,用剪刀將程序數據結構

紙帶剪成紙片,在內存中依次擺放這些紙片,而後才能夠執行內存中的這些紙片。函數

 

執行內存中代碼的時侯,會用到一種名爲堆棧(stack)的數據結構(也就是數據的組織處理.net

方式)。堆棧像個容器,放東西與取東西都在同一端,越晚放進去的東西,越早被取出來(後blog

進先出)。用通俗一點的比喻:堆棧就像是停車場,越早停進去的車,會停在越裏面的位置,內存

要等到比它晚進的車都開走以後,才能開走。容器

爲何須要堆棧?由於程序在執行的過程當中,有時候須要把某些事暫時保留不作(由於條件不原理

成熟),等到後面的事作完才能回頭去作以前保留的事,這時候用堆棧是最適合的。程序

從下一頁開始連續有好幾個範例,你會看到這些範例在執行的過程當中堆棧如何變化,並且屏幕im

上的輸出如何變化。經過這些範例,你應該能夠理解解釋器的運行原理。

d3

對於abs -1 這段代碼來講,會被剪成兩個值:abs 與-1,而後開始執行。

在狀態A,堆棧與屏幕都是空的。而後把abs 放進堆棧中,abs 是求絕對值的函數,它後面

須要跟着一個數字,但堆棧中目前只有abs 本身,因此執行不了,這是狀態B。

到了狀態C,-1 也被放進堆棧。有了這一個參數,abs 終於能夠計算了,計算方式是把這兩

個值都從堆棧中取出,計算以後獲得的值是1,再把1 放回堆棧,如今是狀態D。

內存中的代碼已經執行完畢,堆棧中也沒有任何進一步的計算要進行,這表示程序要結束了。

結束時,堆棧中剩下的1 就是返回值。因此在狀態E 中,咱們看到堆棧被清空,但屏幕上出

現== 1。

對於power 2 6 這段代碼來講,會被剪成power、二、6 這三個值,而後開始執行。

在狀態A,堆棧與屏幕都是空的。而後把power 放進堆棧中,成爲狀態B。power 是求冪的

函數,它後面須要跟着兩個數字,分別是底數與指數,因此目前計算不了。狀態C,把2 放進

堆棧,依然沒法執行。

狀態D,把6 放進堆棧,如今power 的兩個參數都到齊了,能夠計算了。方式是把三個值都

取出來計算,結果獲得64,再把結果放回堆棧,進入狀態E。

內存中的代碼已經執行完畢,堆棧中也沒有任何進一步的計算要進行。這表示程序要結束了。

結束時,堆棧中剩下的64 就是返回值。因此在狀態F 中,咱們看到堆棧被清空,但屏幕上出

現== 64。

對於print add 3 -4 這段代碼來講,會被剪成print、add、三、-4 這四個值,而後

解釋其原理

 

開始執行。

先把print 放進堆棧,進入狀態A。print 須要一個參數,因此此時沒法計算。再把add 放

進堆棧,進入狀態B。add 如今沒法當作print 的參數,由於add 本身就是一個函數,必須

等add 計算完畢的值才能當print 參數。add 須要兩個參數。

3 與-4 被依次放進堆棧,進入狀態C。這個時候,add 的兩個參數已經到齊,能夠計算了。

把這三個值取出來,計算以後獲得結果-1,把-1 放回堆棧,如今是狀態D。

這個時候,print 須要的參數(-1)已經出現了,取出這兩個值,計算(執行)的結果是屏

幕上出現-1。print 是沒有返回值的。沒有返回值也就是說返回值是一個特殊值unset(未

設)。把unset 放進堆棧中。如今狀態是E。

內存中的代碼已經執行完畢,堆棧中也沒有任何進一步的計算要進行。這表示程序要結束了。

結束時,堆棧中剩下的特殊值unset 就是返回值,返回值爲特殊值unset 至關於沒有返回值。

因此在狀態F 中,咱們看到堆棧被清空,屏幕中沒有出現==。

 

 

對於power 2 6 abs add 3 -4 這段代碼來講,會被剪成power、二、六、abs、add、三、

-4 這7 個值,而後開始執行。

把power、二、6 依次放進堆棧,進入狀態A。終於能夠計算了,計算以後進入狀態B。堆棧

中已經沒有任何進一步的計算要進行,但內存中還有後續的代碼,因此還沒有結束。

把內存中的abs、add、三、-4 依次放進堆棧,進入狀態C。終於能夠計算了,取出最上面的

三個值,計算以後把結果-1 放回堆棧,進入狀態D。狀態D 也能夠計算,取出兩個值,計算

結果1 放回堆棧,進入狀態E。

內存中的代碼已經執行完畢,堆棧中也沒有任何進一步的計算要進行。這表示程序要結束了。

結束時,堆棧中如有多個值,最上層的值就是返回值。因此在狀態F 中,咱們看到堆棧被清空,

屏幕中出現== 1,而64 直接被扔了。

 

 

這個例子其實有兩個段落,因此最後堆棧會有兩個值。段落之間彼此獨立,所以寫代碼時,我

們喜歡讓段落之間換行,能夠幫助閱讀理解。

每次發生計算,其實就是找到一個段落。堆棧最後的值分別由power 與abs 產生,因此它們

兩個就是段落的起點。

既然每次發生計算就是一個段落,那麼add 應該也是段落的起點。但由於add 只是abs 的一

部分(也就是說它是abs 段落的子段落),並且add 沒有兄弟段落(power 與abs 在這裏就

是兄弟關係,是平級的),再說abs 太簡單,讓abs 和add 擺一塊兒比較好。把add 段落拆出

去沒有太大必要。

最後一個例子。對於power 26 print add 3 -4 這段代碼來講,這個例子和前一個例子

差很少,只是abs 換成了print。這致使狀態E 的堆棧中有兩個值,而最上面的值是特殊值

unset。

相關文章
相關標籤/搜索