6.14.6 How to define words with non-default semantics

In a few cases (and most of those are a bad idea) you want to define a word that has some other combination of interpretation and compilation semantics than words with default compilation semantics or immediate words (a combined word22). The following contrived example shows how you can define a combined word:

: foo ." foo" ;
: bar ." bar" ;
' foo ' bar interpret/compile: foobar1

foobar1     \ "foo"
] foobar1 [ \ "bar"
interpret/compile: ( int-xt comp-xt "name" –  ) gforth-0.2 “interpret-slash-compile-colon”

Defines name.
Name execution: execute int-xt.
Name compilation: execute comp-xt.

There are two kinds of uses for combined words:

One use of combined words is parsing words that should be copy-pasteable between interpreted and compiled code; these words should parse at text-interpret time both in their interpretation and their compilation semantics (like an immediate word), but then should perform an action in their interpretation semantics and compile that action in their compilation semantics, like a normal word. An example is ." in Gforth:

: ."-int ( 'ccc"' -- )  '"' parse type ;
: ."-comp ( 'ccc"' -- ) '"' parse postpone sliteral postpone type ;

' ."-int ' ."-comp interpret/compile: ."
( interpretation 'ccc"' -- ; compilation 'ccc"' -- ; run-time -- )

." foo"         \ "foo"
: foo ." foo" ;
foo             \ "foo"

The parsing code is the same in both cases, the action type is directly executed in the interpretation semantics and compiled in the compilation semantics. The compilation semantics also contains postpone sliteral to transfer the parsed string from text-interpretation time to the run-time of the action. This kind of parse/literal/action split with the use of postpone is typical for the implementations of the compilation semantics of such parsing words, and the interpretation semantics consist just of the parse and the action parts.

We discourage the definition of additional combined words for copy-pasteability. They do not work as intended within ]]...[[ (see Macros) and their behaviour is also confusing in other contexts, e.g., when ticking or postponeing such a word. A way to achieve copy-pasteability without needing to define combined words is recognizers (see Recognizers). "foo" type uses the string recognizer (see Dealing with existing Recognizers) and can be copied and pasted between interpreted code, compiled code and code inside ]]...[[ without problem.

On the other hand, combined words are still far better than state-smart words.23

The other kind of use of combined words is for words like [: (see Quotations). These are not parsing words, but [:...;] sequences should be copy-pasteable between interpreted and compiled code; the whole sequence pushes an xt at its run-time. At text-interpret time, it restores the state at the end to what it was at the start. Ideally we would find a clean way to implement all this without needing combined words, but for now the implementation is pretty messy, including combined words.

Some people also have the idea to use combined words for optimization. However, the resulting words do not work as intended with [compile] (see Macros). Gforth has a better mechanism for optimization: set-optimizer (see User-defined compile,).

Some people worry about the aesthetics of interpret/compile: and have proposed alternative syntaxes, and the following ones are supported in Gforth:

: foobar2
  ." foo" ;
[: ." bar" ;] set-compsem

foobar2     \ "foo"
] foobar2 [ \ "bar"

: foobar3
  ." foo" ;
compsem:
  ." bar" ;

foobar3     \ "foo"
] foobar3 [ \ "bar"

: foobar4
  ." bar" ;
intsem:
  ." foo" ;
  
foobar4     \ "foo"
] foobar4 [ \ "bar"

You can use where (see Locating uses of a word) to find out how rarely which syntax is used in Gforth.

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

change compilation semantics of the last defined word

compsem: ( ) gforth-experimental “comp-sem-colon”

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

intsem: ( ) gforth-experimental “int-sem-colon”

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


Footnotes

(22)

Some people call combined words “NDCS”, but immediate words also have non-default compilation semantics

(23)

State-smart words are immediate words that do state-dependent things at run-time. 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.