我是 Forth 新手,正在尝试开发一些(伪有用的)玩具来学习语言。我想精简以下操作:
[ifundef] vehicles 2variable vehicles [then]
[ifundef] cars< 2variable cars< [then]
vehicles 2@ s" cars " s+ vehicles 2!
cars< 2@ s" vehicles" s+ cars< 2!
通过以下(更紧凑的)指令
-> vehicles cars
或者,换句话说:
- "->" 解析以下两个名字
- 为第一个名称创建一个字典条目“车辆”,用于类似 2 变量的结构,如果它不存在,将为其分配一个字符串
- 对于第二个名称,创建另一个条目“cars<”(注意 <),如果它不存在,也是一个 2 变量
- 然后将字符串“cars”添加(而不是替换)到变量车辆
- 并将字符串“vehicles”添加到变量 cars<
我做了一个黑客攻击,使用字符串操作和评估来获得这种行为......
: space+ ( str -- ) s" " s+ ;
\ use like: cars add alfa-romeo (first is a 2variable name, second a parsed name)
: add ( a "name" -- ) dup >r 2@ parse-name space+ s+ r> 2! ;
create _x 256 chars allot align
: _x@ ( -- ) _x count ;
: _x! ( -- ) _x place ;
create _y 256 chars allot align
: _y@ ( -- ) _y count ;
: _y! ( -- ) _y place ;
: init_x ( str -- ) 2dup s" [ifundef] " 2swap s+ s" 2variable " s+ 2swap s+ s" [then]" s+ evaluate ;
: init_y ( str -- ) 2dup s" [ifundef] " 2swap s+ s" < 2variable " s+ 2swap s" <" s+ s+ s" [then]" s+ evaluate ;
: make-dictionary-entries ( -- ) _x@ init_x _y@ init_y ;
: add-strings-to-entries ( -- ) _x@ s" add " s+ _y@ s+ evaluate
_y@ s" < add " s+ _x@ s+ evaluate ;
: -> parse-name _x! parse-name _y!
make-dictionary-entries
add-strings-to-entries ;
\ CUSTOM TESTING to improve readability of the examples
: test( POSTPONE assert( ; immediate
: true! 0= throw ;
: false! throw ;
: same-string! str= true! ;
-> vehicles cars
test( vehicles 2@ s" cars " same-string! )
test( cars< 2@ s" vehicles " same-string! )
-> vehicles trucks
-> vehicles dreams
test( vehicles 2@ s" cars trucks dreams " same-string! )
test( trucks< 2@ s" vehicles " same-string! )
-> cars ferrari
-> cars lamborghini
-> dreams lamborghini
test( cars 2@ s" ferrari lamborghini " same-string! )
test( lamborghini< 2@ s" cars dreams " same-string! )
我认为存在另一种更直接、更优雅的方式,但这是我目前能做的最好的方式。有什么建议么?