:
, create
, and variable
are definition words: They
define other words. Constant
is another definition word:
5 constant foo foo .
You can also use the prefixes 2
(double-cell) and f
(floating point) with variable
and constant
.
You can also define your own defining words. E.g.:
: variable ( "name" -- ) create 0 , ;
You can also define defining words that create words that do something other than just producing their address:
: constant ( n "name" -- ) create , does> ( -- n ) ( addr ) @ ; 5 constant foo foo .
The definition of constant
above ends at the does>
; i.e.,
does>
replaces ;
, but it also does something else: It
changes the last defined word such that it pushes the address of the
body of the word and then performs the code after the does>
whenever it is called.
In the example above, constant
uses ,
to store 5 into the
body of foo
. When foo
executes, it pushes the address of
the body onto the stack, then (in the code after the does>
)
fetches the 5 from there.
The stack comment near the does>
reflects the stack effect of the
defined word, not the stack effect of the code after the does>
(the difference is that the code expects the address of the body that
the stack comment does not show).
You can use these definition words to do factoring in cases that involve (other) definition words. E.g., a field offset is always added to an address. Instead of defining
2 cells constant offset-field1
and using this like
( addr ) offset-field1 +
you can define a definition word
: simple-field ( n "name" -- ) create , does> ( n1 -- n1+n ) ( addr ) @ + ;
Definition and use of field offsets now look like this:
2 cells simple-field field1 create mystruct 4 cells allot mystruct .s field1 .s drop
If you want to do something with the word without performing the code
after the does>
, you can access the body of a create
d word
with >body ( xt -- addr )
:
: value ( n "name" -- ) create , does> ( -- n1 ) @ ; : to ( n "name" -- ) ' >body ! ; 5 value foo foo . 7 to foo foo .
Assignment: Define
defer ( "name" -- )
, which creates a word that stores an XT (at the start the XT ofabort
), and upon executionexecute
s the XT. Defineis ( xt "name" -- )
that storesxt
intoname
, a word defined withdefer
. Indirect recursion is one application ofdefer
.
Reference: User-defined Defining Words.