6.13.1 Combined Words

Gforth allows you to define combined words – words that have an arbitrary combination of interpretation and compilation semantics (some people call them NDCS words, and mean words with non-default and non-immediate compilation semantics).

interpret/compile: ( interp-xt comp-xt "name" –  ) gforth-0.2 “interpret/compile:”

This feature was introduced for implementing TO and S". I recommend that you do not define such words, as cute as they may be: they make it hard to get at both parts of the word in some contexts. E.g., assume you want to get an execution token for the compilation part. Instead, define two words, one that embodies the interpretation part, and one that embodies the compilation part. Once you have done that, you can define a combined word with interpret/compile: for the convenience of your users.

A typical usage example is:

: s"-int ( -- c-addr u )
  '"' parse save-mem ;
: s"-comp ( -- ; run-time: -- c-addr u )
  '"' parse postpone sliteral ;
' s"-int ' s"-comp interpret/compile: s"

Some people are not happy with the looks of the definition above, so Gforth also provides additional ways to write this kind of definition:

set-compsem ( xt –  ) gforth-experimental “set-compsem”

change compilation semantics of the last defined word

compsem: ( ) gforth-experimental “compsem:”

Changes the compilation semantics of the current definition to perform the definition starting at the compsem:.

intsem: ( ) gforth-experimental “intsem:”

The current definition’s compilation semantics are changed to perform its execution semantics (the word becomes immediate). Then its interpretation semantics are changed to perform the definition starting at the intsem:. Note that if you then call immediate, the compilation semantics are changed to perform the word’s new interpretation semantics.

Note that there are and should be only few combined words, ideally none, and their definitions don’t need to be pretty (on the contrary, their uglyness may provide a warning that “here be dragons”). So our recommendation is to use interpret/compile:.

It is a bad idea to try to use combined words for optimization of words with default compilation semantics: Gforth has a better mechanism for that (set-optimizer and opt:, see User-defined compile,), [compile] treats combined words as having non-default compilation semantics, and the intended optimization does not happen when the combined word is ticked and compile,d.

Some people try to use state-smart words to emulate combined words (words are state-smart if they check STATE during execution). E.g., they would try to code s" like this:

: foobar
  STATE @ IF ( compilation state )
    comp-s"
  ELSE
    int-s"
  THEN ; immediate

Although this works if s" is only processed by the text interpreter, it does not work in other contexts (like ' or POSTPONE). E.g., ' foobar will produce an execution token for a state-smart word, not for the interpretation semantics of the original foobar; when you execute this execution token (directly with EXECUTE or indirectly through COMPILE,) in compile state, the result will not be what you expected (i.e., it will not call int-s"). State-smart words are a bad idea. Simply don’t write them23! Gforth provides better alternatives: interpret/compile: and set->comp for implementing combined words, and set-optimizer for implementing optimizations of words with default compilation semantics.


Footnotes

(23)

For a more detailed discussion of this topic, see M. Anton Ertl, State-smartness—Why it is Evil and How to Exorcise it, EuroForth ’98.