news:k672lj$82o$1...@dont-email.me...
For temporary reasons, most of my Forth stack operators, like DUP SWAP etc,
aren't currently low-level Forth "primitives". They're implemented in
high-level Forth using an even lower set of actual stack "primitives", which
I'll call sub-operators for this thread. These sub-operators could be
considered to be "stack assembly instructions" for my Forth. Currently,
only >R and R> are actually "primitives" coded in C. Eventually, DUP DROP
SWAP OVER will be actual low-level Forth "primitives", as they once were.
So, a word like OVER can be coded in many ways. I have 22 different
definitions just for OVER in a list, and one can construct many more. E.g.,
: OVER >R DUP R> SWAP ;
: OVER 1 PICK ;
: OVER SWAP TUCK ;
: OVER SWAP DUP -ROT ;
: OVER NUP SWAP ;
etc.
Which definition you choose affects how fast OVER executes and depends on
what operations you have available and on how fast each of those operations
are.
E.g., if >R >R DUP SWAP and -ROT are all very fast machine instructions for
your processor, then ">R DUP R> SWAP" and "SWAP DUP -ROT" should be fast
sequences. And, one sequence will be faster than the other, depending on
how fast each instruction is. But, if -ROT is not a machine instruction,
e.g., perhaps coded as "ROT ROT" or "SWAP >R SWAP R>", or -ROT is a very
slow machine instruction, then "SWAP DUP -ROT" is more expensive than ">R
DUP R> SWAP".
The instructions also need to be balanced acrossed many Forth words.
Originally, I had the 2xxx series words defined in terms of the simpler
stack operators, like SWAP DUP etc. When I converted to sub-operators, the
number of operations per definition dropped dramatically for some of the
2xxx definitions. Since the sub-operators are primitives, some of the 2xxx
definitions became faster. However, after converting all of the simpler
stack operators to sub-operators, a few of the non-primitive simple stack
operators ended up with more operations per definition. So some words
became much faster, while others became slightly slower. And, the former
primitives became real slow, but they'll be converted back eventually.
Let's take a look at 2OVER for my Forth interpreter. I could easily
implement it as a Forth low-level "primitive". Or, I could define it in
high-level Forth. Or, I could define it in high-level Forth in terms of
sub-operators which are actually the low-level "primitives".
In high-level Forth, 2OVER can be defined:
: 2OVER 2>R 2DUP 2R> 2SWAP ;
In terms of my sub-operators, my 2OVER definition has ten words it's
definition. Clearly, that's many more words than the four in definition
above. But, 2>R 2R> 2DUP and 2SWAP are also implemented in high-level
Forth using the same set of sub-operators. So, 2>R 2R> 2DUP and 2SWAP
aren't "primitives" nor are they a single sub-operator each.
The 2>R sequence has six items.
The 2DUP sequence has six items.
The 2R> sequence has six items.
The 2SWAP sequence has eight items.
The 2OVER sequence has ten items.
So, 2OVER is only 10 items using a single sequence of sub-operators instead
of a total 28 items using four sequences of sub-operators for the four words
in the high-level definition. If the 2>R 2DUP 2R> and 2SWAP words are
defined in terms of standard Forth words:
The 2>R sequence has three items.
The 2DUP sequence has ten items over multiple words.
The 2R> sequence has three items.
The 2SWAP sequence has twelve items over multiple words.
In this case, the counts changed, but it just happens that it's total is 28
also... Usually, it's more. Of course, you'd rather have a 2DUP of six
items instead of ten, i.e., balance. If the instructions are unbalanced,
then heavy use of a single Forth word will slow the code speed way down.
I.e., many 2DUP's of ten items is much worse than many 2DUP's with six
items, even if other used words are made slightly slower, like 2>R and 2R>.
Of course, you don't know if your user's code will follow the measured
instruction frequencies or not. But, at this point, you're the only user
...
As a primitive, 2OVER will be a small C routine which is compiled to
optimized, machine code.
Rod Pemberton