2014-11-05 70 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! ;