DEFER isn't in the ANS-Forth document, so I can't RTFM. If IS is STATE-smart (it is in the novice-package) then it will work during compilation --- with most implementations it only works during interpretation --- because it is not standardized in ANS-Forth, the ANS-Forth programmer can't expect any particular behavior (if he assumes interpretation only, then his code should be portable to most systems).
This code is in the novice-package:
: bad-vector \ pre-initialize vectors with this and overwrite it with a good vector later
true abort" *** uninitialized vector ***" ;
: defer ( -- ) \ stream: name \ defines a deferred word
create ['] bad-vector ,
does>
@ execute ;
: is ( xt -- ) \ stream: name \ resolves a deferred word
state @ if
postpone [']
postpone >body
!,
else
' >body ! then ;
immediate
\ DEFER and IS are very traditional, so I provided them.
\ VECTOR is much more efficient.
: <vector> { name | xt -- }
here ['] bad-vector , to xt
c" is-" name get-current :2name \ runtime: xt --
xt lit, !, ;,
name get-current :name \ runtime: -- \runtime runtime: i*x -- j*x
state@, if, xt lit, postpone lit, postpone @, postpone execute,
else, xt lit, @, execute, then, ;,
immediate
;
: vector ( -- )
bl word hstr dup >r <vector> r> dealloc ;
Under SwiftForth, this is what gets compiled for DEFER words:
defer aaa ok
: test-aaa aaa ; ok
see test-aaa
48E98F 48E94F ( aaa ) JMP E9BBFFFFFF ok
see aaa
48E94F 4867D9 ( defer +1A ) CALL E8857EFFFF
see defer
4867BF 40FAFF ( CREATE ) CALL E83B93F8FF
4867C4 4 # EBP SUB 83ED04
4867C7 EBX 0 [EBP] MOV 895D00
4867CA 8276F # EBX MOV BB6F270800
4867CF 40AA2F ( , ) CALL E85B42F8FF
4867D4 40DA4F ( (;CODE) ) CALL E87672F8FF
4867D9 4 # EBP SUB 83ED04
4867DC EBX 0 [EBP] MOV 895D00
4867DF EBX POP 5B
4867E0 0 [EBX] EBX MOV 8B1B
4867E2 40434F ( EXECUTE ) JMP E968DBF7FF ok
see execute
40434F EBX ECX MOV 8BCB
404351 0 [EBP] EBX MOV 8B5D00
404354 4 # EBP ADD 83C504
404357 ECX ECX OR 09C9
404359 40435F JZ 7404
40435B EDI ECX ADD 01F9
40435D ECX JMP FFE1
40435F RET C3 ok
This is what gets compiled for VECTOR words:
vector bbb ok
: test-bbb bbb ; ok
see test-bbb
48EA3F 4 # EBP SUB 83ED04
48EA42 EBX 0 [EBP] MOV 895D00
48EA45 48E994 # EBX MOV BB94E94800
48EA4A 0 [EBX] EBX MOV 8B1B
48EA4C 40434F ( EXECUTE ) JMP E9FE58F7FF ok
As you can see, my VECTOR is more efficient than DEFER is.