herkforth deferred words
herkforth now (as of herkforth-0.7) supports deferred words. This document describes how they work, and how to use them in a way that makes it clear to programmers (including yourself) that it is deferred, and each place that it is deferred.
Creating a deferred word is something that should be done very rarely. In the
entire sources for herkforth, I have only deferred one word (-emit
). For
these reasons, I have not created convenience words to make this process any
less technical. So you'll have to understand how things work.
Conventions
This is critical, as it makes it so someone browsing the source sees that it's deferred, and can find the places where it is changed.
When you define a word do be deferred to all the following:
1) Define the word to be changed with no definition:
:
-emit
2) On the next line, create a word which changes what definition it uses:
:
is-emit
`
-emit
[
dict->cfa
]
lit swap -is ;
And don't forget to set a default definition for it:
`
output-char
[
dict->cfa is-emit
How it works
`
-emit
puts a pointer to the dictionary entry on the stack at compile
time. [
dict->cfa
takes this dictionary pointer and returns its CFA (code
field address). ]
-is
takes two CFAs and makes the former call the latter.
To define a word that changes a definition, be sure to get a lit
in there
to make the CFA available at runtime, not just compiletime.