to etc. ¶When you define a word x, you can set its execution semantics
with set-does> (see User-defined defining words using create) or set-execute (see Header methods). But you can
also change the semantics of
This is all achieved through a common mechanism described in this
section. As an example, let’s define dvalue (it behaves in
Gforth exactly like 2value, see Values). The code is as
follows, explained below:
: d+! ( d addr -- ) dup >r 2@ d+ r> 2! ; \ to +to action-of is addr to-table: d!-table 2! d+! n/a n/a [noop] ' >body d!-table to-class: dvalue-to : dvalue ( d "name" -- ) create 2, ['] 2@ set-does> ['] dvalue-to set-to ; #5. dvalue x #2. +to x x d. \ prints 7
First, we define the support word d+!.
Next, we define d!-table, a table of the various to-like
actions.
For actions that are not supported, we put n/a in the table,
and when you try to use, e.g., is x, exception -21 (unsupported
operation) is thrown.
For the to and +to actions, we have to provide words
with the stack effect ( d addr -- ), where addr is the
address where the data of the value-flavoured word is stored. For
addr (only supported for addressable: words), we have to
provide a word with the stack effect ( addr1 -- addr2 ); in the
usual case, both addresses are the same, and we can just provide
[noop]. For the general case, see the description of
to-table: below.
Next, the defining word to-class: combines the d!-table
with the address-computation word >body, resulting in the
definition of dvalue-to.18 The address-computation word has the stack effect (
... xt -- addr ). When invoking +to x, the xt of x is
pushed and then the address-computation word (>body) is called;
the result is the address that is then passed on to d+! (from
d!-table).
For dvalue that’s all, but in other cases, e.g.,
value-flavoured fields (see Value-Flavoured and Defer-Flavoured Fields), additional stack items can be consumed by the
address-computation word, and those have to be provided by the user as
stack-top values when invoking, e.g., to field.
Next, we have the definition of dvalue, which is a
straightforward create...set-does> word that also tells
name with set-to how it should behave for to etc.
Finally, we use dvalue to define x and use it. The line
using +to exercises the set-to mechanism:
performs
The >body is the address-computation word given in the
definition of dvalue-to, and the d+! is the +to
entry in d!-table.
These are the words mentioned above:
to-table: ( "name" "to-word" "+to-word" "addr-word" "action-of-word" "is-word" – ) gforth-experimental “to-table-colon”
Create a table name with entries for TO, +TO,
ACTION-OF, IS, and ADDR. The words for
these entries are called with xt on the stack, where xt
belongs to the word behind to (or +to etc.). Use
n/a to mark unsupported operations. Default entries
operations can be left away at the end of the line; the default
is for the addr entry is [noop] while the default
for the other entries is n/a.
The stack effects of the actions are:
to and +to action: ( value addr -- ), where
value has the appropriate type (e.g., a double-cell in our
dvalue example).
action-of action: ( addr -- xt )
is action: ( xt addr -- )
addr action: ( addr1 -- addr2 )
The addr input parameter in all these cases is the address of the memory where the value of the xt is stored.
The default mechanism means that d!-table could instead have
been defined as follows:
This word can be ticked, but throws an “Operation not supported” exception on interpretation and compilation. Use this for methods etc. that aren’t supported.
Create a to-class implementation name, where xt
( ... xt -- addr ) computes the address to access the
data, and table (created with to-table:) contains
the words for accessing it.
Xt is the xt of a word x defined with uvalue;
addr is the address of the data of x in the current
task. This word is useful for building, e.g., uvalue.
Do not use it to circumvent that you cannot get the address of
a uvalue with addr; in the future Gforth may perform
optimizations that assume that uvalues can only be accessed
through their name.
Changes the implementations of the to-class methods of the most recently defined word to come from the to-class that has the xt to-xt.
The same to-table is often combined with different address computation words (e.g., for global values, user values, value-flavoured fields and locals), that’s why the definition of the to-table is separated from the definition of the to-class.