POSTPONE, DEFER and an ISR/BG bug fix
About the Release
The 2.2.28 development cycle had just started - the plan was to start making STM8 eForth a little bit more standard compliant so that using code from other embedded Forth systems gets easier when @Eelkhoorn found a configuration error of the BG task data stack size: since #377 the stack size as exactly "0" so that the ISR data stack was used (see #424 ).
Other than that, this release contains a potentially braking change: POSTPONE
was introduced and since it has some many advantages over COMPILE
and COMPILE
it's now the default. Please refer to #413 for a discussion of the differences.
New Features
POSTPONE
instead of COMPILE
or [COMPILE]
Modern Forth systems use POSTPONE
instead of COMPILE
or [COMPILE]
. The main objective is code simplification, both for the programmer but also for a Forth system that generate machine code: in STM8 eForth COMPILE
has to analyze the call type (absolute or relative) - which makes the code more complicated.
Why this is important
Making "Forth macros", words that compile code (e.g., IF ... ELSE ... THEN
), requires compiling "compilation instructions" into a word instead of executing them during compilation.
For instance IF
can be implemented as follows:
: >MARK ( --A ) HERE 0 , ;
: IF ( --A ) COMPILE ?branch >MARK ; IMMEDIATE
Since the dictionary entry of IF
is flagged IMMEDIATE
it will be executed, not compiled, when using a condition structure (e.g., 0< IF DROP 0 THEN
). When executed, the word COMPILE
takes the call address (xt
, the execution token) of the next word (?branch
) and compiles it into the destination code (e.g. the conditional phrase above). Note that ?branch
isn't flagged IMMEDIATE
- if it were different it would be executed, not compiled, and COMPILE
would not receive the expected xt
.
Sometimes IMMEDIATE
words need to be compiled into a new word, not executed. In order to get the desired effect [COMPILE]
would be required to enforce compilation of the immediate word, e.g.:
: WHILE ( a --A a ) [COMPILE] IF SWAP ; IMMEDIATE
Here [COMPILE]
overrides the IMMEDIATE
flag of IF
and compiles a call to this immediate word into the code of WHILE
. It would also be possible to write COMPILE [COMPILE] IF
, which would create a macro that compiles IF
into the target code (just like using COMPILE
on a regular word). In practice such a use case is rare.
From this release on it's sufficient to write POSTPONE
instead of COMPILE
or [COMPILE]
. This also makes porting code from more modern Forth systems easier since it's no longer necessary to figure out if it's COMPILE
or [COMPILE]
that you'll have to use instead.
Legacy code can use #require COMPILE
or #require [COMPILE]
, which will load an alias to POSTPONE
, to cover all but the most exotic use cases. If that does't work the legacy words can be re-enabled in the board configuration (and please file an issue).
More examples and technical details are in the following issues:
#413 POSTPONE supersedes COMPILE and [COMPILE]
#414 make COMPILE and [COMPILE] replaceable with ALIAS to POSTPONE
#414 add test for POSTPONE
#417 use COMPILIT instead of COMPILE in core
#419 use POSTPONE in lib
#419 use POSTPONE in >REL
#419 use POSTPONE in [']
#419 use POSTPONE in ALIAS
#419 use POSTPONE in DEFER
#419 use POSTPONE in :NVM
#419 use POSTPONE in S"
#419 use POSTPONE in EVALUATE
#419 use POSTPONE in CONSTANT
#419 use POSTPONE in MARKER
#419 use POSTPONE in VOC
#419 use POSTPONE in VOCABULARY
Add [']
and DEFER ... IS
Issue #411 adds the words [']
(compile literal with xt
of the following word) and DEFER ... IS
.
Please refer to the Forth Standard entries of [']
, DEFER
and IS
.
Other changes
Core optimizations
Issue #416 introduces a more compact CALL,
with COMPILIT
and some other core optimizations, especially for the transition from COMPILE
and [COMPILE]
to POSTPONE
.
Tool changes
Issue #421 makes the codeload.py
line length check less restrictive (trailing comments don't count).
Docs changes
Issue #409 proposes a work around for an STM8L151 serial bootloader erratum
Bug fixes
BG task data stack size configuration error
Issue #424 describes a critical problem of the BG task data stack size configuration:
- Applications that use the BG task and an ISR that uses Forth code may suffer from BG task data stack corruption
- The BG stack has been 8 cells deep since the bug was introduced - this can also lead to foreground task stack corruption!
The regression was introduced when the BG code was factored out in #377. It was still OK until the 2.2.26 release. The first release that contained this bug was 2.2.27.pre1. 2.2.27 was released 9/Mar/2021.
Incorrect TIB
constant export
Issue #420 fixes an incorrect TIB
constant export that broke EVALUATE
. The bug was introduced in release 2.2.24. An automated test of EVALUATE
was added.