"DOES>"这个词到底有什么作用?

  • 本文关键字:作用 DOES forth gforth
  • 更新时间 :
  • 英文 :


我一直在努力理解它,所以我写了一个简单的词来测试它:

: test ." compile time" DOES> ." runtime" ;

问题是,这个词的表现方式根本不一致。它的输出似乎取决于许多因素,如:

  • 这是要解释的第一行吗
  • 在它之后还有其他词定义吗

此外,有时它根本不打印任何内容。

(使用Gforth(

这是您的代码:

: test ." compile time" DOES> ." runtime" ;

输入后,我可以使用你的单词,而不必你遇到的模糊行为:

CREATE def 12345 , test  prints "compile time"

它打印compile time,因为这是在DOES>之前编译到test中的行为。注意:这实际上并不是在编译时运行的

DOES>结束单词的定义,但对其进行更改,使test也修改最后定义的单词,使其将数据字段地址放在堆栈上,然后运行在DOES>之后找到的行为。

使用我创建的单词,它具有您定义的实例化行为,遵循推送地址的隐含行为:

def @ .  prints runtime 12345

Forth 2012注:根据Forth 2012中DOES>的定义,如果最后一个词没有用CREATE定义,这将导致歧义行为。然而,Gforth允许修改任何单词的定义

我希望这个例子有助于解释为什么通常在使用DOES>的定义中使用CREATE,但它肯定不是必需的。

ruvim的答案在Gforth中可能更容易理解。

下面的代码定义了一个"经典"定义词,该词在编译时创建初始化为堆栈上的项的变量。我希望定义中的跟踪语句将有助于显示正在发生的事情

: var     create: n <name> -- ; does>: -- addr ; initialised VARIABLE
create       create a dictionary item for <name>.
." HERE at compile time: " HERE .
,            place n at HERE in the dictionary
does>        Push the HERE as at compile time to the stack
." Run time address on the stack:" dup .
;

CCD_ 11现在可以用于定义具有在DOS>之后定义的运行时动作的新词;。

10 var init10     Use var to define a new word init10
 HERE at compile time: 135007328
init10 CR DUP . @ .
 Run time address on the stack:135007328
 135007328 10    addr of init10, content of that address.
12 var init12     Use var to define a new word init12
 HERE at compile time: 135007376
init12 CR DUP . @ .
 Run time address on the stack:135007376
 135007376 12
100 init10 !     Store 100 in init10
 Run time address on the stack:135007328
init10 @ .
 Run time address on the stack:135007328  100
 init10 now contains 100

希望这些答案将提供一个框架来探索DOS>的定义词和动作;。

互动播放

在Gforth中,您可以对does>进行解说。

create foo 123 ,
foo @ .  prints 123
does> ( addr -- ) @ . ;
foo  prints 123
does> ( addr -- ) @ 1+ . ;
foo  prints 124
' foo >body @ .  prints 123

因此,当最后一个单词通过create定义时,does>只是改变了最后一个词的行为。如果在最后一个单词未通过create定义的情况下运行does>,这是一个错误。

实践中的使用

通常,CCD_ 17仅用于为通过CCD_ 18定义的单词设置一次新行为。多次改变这种行为的能力只是历史实施的副作用,而这种影响几乎没有在实践中使用。


替代方式

在实践中,使用does>的情况也可以在没有does>的情况下实现。

例如,让我们想要实现一个字counter,它创建一个计数器,每次返回下一个值,并以以下方式使用:

1 counter x1
x1 .  prints 1
x1 .  prints 2
x1 .  prints 3

通过createdoes>实现

: counter ( x0 "ccc" -- )  Run-Time: ( -- x )
create ,  does> ( addr -- x ) dup >r @ dup 1+ r> !
;

使用报价的实现

[undefined] lit, [if] : lit, ( x  -- ) postpone lit, ; [then]
[undefined] xt,  [if] : xt,  ( xt -- ) compile, ;      [then]
: counter ( x0 "ccc" -- )  Run-Time: ( -- x )
align here >r , [: ( addr -- x ) dup >r @ dup 1+ r> ! ;] >r
:  r> r> lit, xt, postpone ;
;

通过单词]]:使用宏(代码内联(的实现

: counter ( x0 "ccc" -- )  Run-Time: ( -- x )
align here >r , 
:  r> lit, ]] dup >r @ dup 1+ r> ! [[ postpone ; 
;

定义分配内存的单词的单词可以通过DOS>其将地址提供给存储器块。

一个简单的例子是CONSTANT,它可以定义为

:常量(n--(创建,确实>@;

相关内容

  • 没有找到相关文章

最新更新