The interpretation semantics of a word are what the text
interpreter does when it encounters the word in interpret state. It also
appears in some other contexts, e.g., the execution token returned by
' word
identifies the interpretation semantics of
word (in other words, ' word execute
is equivalent to
interpret-state text interpretation of word
).
The compilation semantics of a word are what the text interpreter
does when it encounters the word in compile state. It also appears in
other contexts, e.g, POSTPONE word
compiles(3) the
compilation semantics of word.
The standard also talks about execution semantics. They are used
only for defining the interpretation and compilation semantics of many
words. By default, the interpretation semantics of a word are to
execute
its execution semantics, and the compilation semantics of
a word are to compile,
its execution semantics.(4)
You can change the compilation semantics into execute
ing the
execution semantics with
immediate
-- core ``immediate''
You can remove the interpretation semantics of a word with
compile-only
-- gforth ``compile-only''
restrict
-- gforth ``restrict''
Note that ticking ('
) compile-only words gives an error
("Interpreting a compile-only word").
Gforth also allows you to define words with arbitrary combinations of interpretation and compilation semantics.
interpret/compile:
interp-xt comp-xt "name" -- gforth ``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.
You also might try to provide an optimizing implementation of the default compilation semantics with this feature, like this:
:noname foo bar ; :noname POSTPONE foo POSTPONE bar ; interpret/compile: foobar
as an optimizing version of
: foobar foo bar ;
Unfortunately, this does not work correctly with [compile]
,
because [compile]
assumes that the compilation semantics of all
interpret/compile:
words are non-default. I.e., [compile]
foobar
would compile the compilation semantics for the optimizing
foobar
, whereas it would compile the interpretation semantics for
the non-optimizing foobar
.
Some people try to use state-smart words to emulate the feature provided
by interpret/compile:
(words are state-smart if they check
STATE
during execution). E.g., they would try to code
foobar
like this:
: foobar STATE @ IF ( compilation state ) POSTPONE foo POSTPONE bar ELSE foo bar ENDIF ; immediate
While this works if foobar
is processed only 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
perform foo bar
). State-smart words are a bad idea. Simply don't
write them!
It is also possible to write defining words that define words with arbitrary combinations of interpretation and compilation semantics. In general, this looks like:
: def-word create-interpret/compile code1 interpretation> code2 <interpretation compilation> code3 <compilation ;
For a word defined with def-word
, the interpretation
semantics are to push the address of the body of word and perform
code2, and the compilation semantics are to push the address of
the body of word and perform code3. E.g., constant
can also be defined like this (except that the defined constants don't
behave correctly when [compile]
d):
: constant ( n "name" -- ) create-interpret/compile , interpretation> ( -- n ) @ <interpretation compilation> ( compilation. -- ; run-time. -- n ) @ postpone literal <compilation ;
create-interpret/compile
"name" -- gforth ``create-interpret/compile''
interpretation>
compilation. -- orig colon-sys gforth ``interpretation>''
<interpretation
compilation. orig colon-sys -- gforth ``<interpretation''
compilation>
compilation. -- orig colon-sys gforth ``compilation>''
<compilation
compilation. orig colon-sys -- gforth ``<compilation''
Note that words defined with interpret/compile:
and
create-interpret/compile
have an extended header structure that
differs from other words; however, unless you try to access them with
plain address arithmetic, you should not notice this. Words for
accessing the header structure usually know how to deal with this; e.g.,
' word >body
also gives you the body of a word created with
create-interpret/compile
.
Go to the first, previous, next, last section, table of contents.