我为 J1 CPU 编写了一个 Forth 解释器,现在将其移植到 Z80。在新版本中,冒号词是解释器要调用的地址列表。
我的问题是如何将文字插入冒号定义中。
示例:
: 1+ 1 + ;
当编译器遇到文字 1 时,它没有地址可以调用将值压入堆栈。
解决方案是动态生成一个例程,例如
ld hl, 1
push hl
ret
在其他地方并在冒号定义中使用该地址。
另一种解决方案是使用无效地址(例如 0x0000)后跟文字,解释器将其视为特殊情况:遇到地址 0x0000 时,它只是将接下来的两个字节的值压入堆栈。在这种情况下,1+在内存中的定义将是这样的:
0x0000 ;
0x0001 ; literal
0x4500 ; + routine address
有更好的解决办法吗?
一个经典的方法是操纵返回地址:
: (lit) ( -- x ) ( R: addr1 -- addr2 )
\ NB: "(lit)" cannot be used as an ordinary word
r> dup cell+ >r @
;
: lit, ( x -- )
['] (lit) compile, ,
\ it is assumed that
\ code space is united with data space
;
: literal ( x -- x | )
state @ if lit, then
; immediate