如何访问 Forth 中的隐藏定义?

How to access a shadowed definition in Forth?

当一个词被重新定义时,是否可以访问旧词?

假设有一个词foo被定义和重新定义

: foo ( n -- 2*n ) 2* ;  ok
: foo ( n -- 2*n+1 ) foo 1+ ; redefined foo   ok
10 foo . 21  ok

foo 这里执行了两个定义。

是否可以执行第一个定义(“second-foo”)?

21 second-foo . 42 ok

see吗?

see second-foo
: foo
  2* ; ok

访问隐藏定义的一种简单方法是在创建具有相同名称的新定义之前为该定义创建一个同义词。

synonym old-foo foo
: foo ... ;

另一种方法是使用内省工具,即traverse-wordlist这个词。使用这个词我们可以定义一个类似于标准化词find-name-in ( c-addr u wid -- nt|0 )的词find-name-nth-in,但是它找到了第n个阴影词,如下:

: find-name-nth-in ( c-addr1 u1 u wid -- nt|0 )
  >r 1+
  [: ( sd u nt -- sd u true | sd nt 0 false )
    2>r 2dup r@ name>string compare if rdrop r> true exit then
    r> r> 1- dup if nip then dup 0<>
  ;] r> traverse-wordlist ( sd u | sd nt 0 )
  if 2drop 0 exit then nip nip
;

This find-name-nth-in word returns an nt for the word that have the given name in the given word list, and after在单词列表 中定义了 u 个具有相同名称(区分大小写)的单词,否则为 0。

一个测试用例:

: ?name ( nt|0 -- nt ) dup 0= -13 and throw ;

: foo ." old" ;
: foo ." new" ;

"foo" 0 forth-wordlist find-name-nth-in ?name name>interpret execute
\ prints "new"

"foo" 1 forth-wordlist find-name-nth-in ?name name>interpret execute
\ prints "old"

在 Gforth 中,单词 xt-see 可以用作:

"foo" 1 forth-wordlist find-name-nth-in ?name name>interpret xt-see