2014-11-05 49 views
0

我正在嘗試編寫一個Forth單詞,它將刪除堆棧中的所有項目。我正在使用一個非常笨的方法,通過運行帶有'drop'的無限循環並在'drop'失敗時捕獲錯誤,因爲堆棧是空的。捕捉循環中的異常

我的話被定義爲這樣的:

(Infinite drop loop) 
: droploop begin drop true while drop repeat ; 

(Experimental catch with a single drop) 
: dropcatcher ['] drop catch drop ; 

(Like dropcatcher, but with 'droploop' instead of 'drop') 
: dropall ['] droploop catch drop ; 

當我運行droploop,我得到一個錯誤,就像我期望和執行之後,堆棧爲空。 當我運行dropcatcher時,如果堆棧不是空的,它會下降,如果堆棧爲空,則不報告任何內容。 當我運行dropall時,我得到堆棧上剩餘的各種東西。

它看起來像這樣:

2 3 4 5 6 7 8 9 10 dropall .S < 9> -1 3 -1 -1 5 7 9 -1 -1 OK

我希望dropall能簡單地清除堆棧而不用投訴,因爲droploop和dropcatcher似乎可以自行工作,但是,唉,我不明白爲什麼dropall不工作。

爲什麼dropall似乎比droploop和dropcatcher的工作方式不同?或者,我在這裏做錯了什麼?

回答

1

droploop發生錯誤時,它可能會調用ABORT-1 THROW,根據定義清除數據堆棧。因此,droploop很可能不會在檢測到錯誤之前丟失正確數量的堆棧項目,但系統異常處理程序會爲您執行此操作。

當我自己運行droploop時,它崩潰或掛起。這似乎證實了我的理論,即存在嚴重的堆棧下溢。

至於dropall之後的堆棧狀態,我的猜測是gforth在正確的時間可能沒有檢測到堆棧下溢,而你看到的是一些半隨機垃圾。因此,在調用ABORT之前,這是droploop離開堆棧。

備註:您的droploop每次迭代都會丟棄兩個堆棧物品,這可能是也可能不是您想要的。此外,使用again爲無限循環而不是true while。即: droploop begin drop again;

當然,更好的辦法來清除棧將

: clear depth 0 ?do drop loop ; 

: clear begin depth while drop repeat ; 

: clear sp0 sp! ;