Skip to content

POSTPONE, DEFER and an ISR/BG bug fix

Compare
Choose a tag to compare
@TG9541 TG9541 released this 08 Apr 19:43
dde829e

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:

  1. Applications that use the BG task and an ISR that uses Forth code may suffer from BG task data stack corruption
  2. 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.