When looking at Forth, the boundaries between compiling and interpreting are very fluid. Even when interpreting, compilation is commonplace, which is one of the strong points of Forth, the system is built incrementally.
On a Harvard architecture like AVR this is unfortunately not so simple. I implemented a compiler first with CoreForth and Janus, using subroutine threading as the execution model. This allows easy debugging of core words, and results in quite fast code even without any inlining. On the other hand, it does not allow for incremental development since code can only be executed from flash. While it would be possible to write to flash, it is not entirely straightforward, especially when using a bootloader.
Thus the next step was to implement the indirectly threaded
counterpart. The code generated by an ITC compiler consists (almost)
only of memory addresses, and the inner loop (NEXT
) can dynamically
decide whether they resolve to RAM or flash. This incurs a speed
penalty, ITC is in general slower, and the RAM/flash handling still
adds some overhead on top. As a result, the ITC code is about 50%
slower.
What is however interesting is to develop a program first in the interactive Forth style, and then when it is ready, just compile it using the STC model.