create ¶If you want the words defined with your defining words to behave differently from words defined with standard defining words, you can write your defining word like this:
This fragment defines a defining word def-word and then
executes it. When def-word executes, it CREATEs a new
word name, and executes the code code1. The code code2
is not executed at this time. The word name is sometimes called a
child of def-word.
When you execute name, the address of the body of name is
pushed on the data stack and code2 is executed. The address of
the body of name is the address HERE returns immediately
after the CREATE, i.e., the address a created word
returns by default).
You can understand the behaviour of def-word and
name by considering the following definitions:
Using name1 action1 is equivalent to using name.
You can use def-word to define a set of child words that behave
similarly; they all have a common run-time behaviour determined by
code2. Typically, the code1 sequence builds a data area in the
body of the child word. The structure of the data is common to all
children of def-word, but the data values are specific – and
private – to each child word.
As an example, here’s how you can define myconstant2 with
does>:
Here create defines a word name, then , stores w
in name’s data area, then the does> changes name’s
behaviour and returns to the caller of myconstant2: When
name is invoked, the new behaviour first pushes the address of the
data area (as before), but then also performs the code after the
does>. In the present case, this code fetches the value of the
constant from the data area.
The stack effect besides the does reflects the stack effect of
name execution, not the stack effect of the code after the
does> (this is not common practice yet but we still recommend
it).
Does> splits the definition into two subdefinitions and has a
number of disadvantages. Alternatively, Gforth allows you to provide
the second part as an execution token by using set-does>. So
the general scheme is:
The difference from the definition using does> is that on
name execution, after pushing the data address, xt-code2 is
executed, rather than calling the code after the does>.
This also allows putting code3 in def-word; this is
particularly relevant when you want to also use set-optimizer
(see User-defined compile,) on the defined word, because
does>/set-does> calls set-optimizer itself, so
using set-optimizer before does>/set-does> has no
effect.
Here xt-code2 could be the xt of an existing word, or it could be provided through a quotation (see Quotations).
Another advantage of set-does> is that the result is a little
more efficient if the execution token passed to it is that of a
primitive. This advantages comes to fruition in:
During name execution, after pushing the body address of name,
@ is executed.
The efficiency advantage shows up in the comparisons of compiled code size (see User-defined defining words with colon definitions); the execution time also benefits.