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 postpone
ing
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.
Some people call combined words “NDCS”, but immediate words also have non-default compilation semantics
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.