Re: Self Modifying Code
Posted: Tue Apr 14, 2020 7:32 pm
Fleet Forth has a word, WHERE , to show where an error occurred. If the value of BLK is zero, WHERE displays the string pointed to by TIB with the length stored in #TIB . If BLK is non zero, WHERE prints the block and line numbers and displays the text on that line. Since I/O is involved (if the block is not in memory) there is a possibility of WHERE causing another error which would lead to WHERE being called which would cause another error and so on.
The solution I went with looks like this:
NH is a metacompiler directive that makes the following word headless.
If any error occurs while WHERE executes, WHERE does nothing but set the variable WHERE? to true.
Here's a solution involving self modifying code:
(IS) is the primitive compiled by IS and RECURSE compiles the CFA of the latest word so the phrase
makes EXIT the first word in the body of WHERE , effectively switching it off. All error handling in Fleet Forth eventually goes through ABORT . A slight modification to ABORT switches WHERE back on. The original ABORT :
and the new version :
WHERE becomes eight bytes smaller while ABORT becomes eight bytes bigger. No net loss or gain there. The headless variable WHERE? is no longer needed for a total savings of four bytes.
By the way, the word ERR is a deferred word to allow extending the error handling. It is normally set to the word NOOP , a no-op.
The solution I went with looks like this:
Code: Select all
NH VARIABLE WHERE? TRUE WHERE? !
: WHERE ( -- )
WHERE? @ IF
WHERE? OFF
// The main body of WHERE
.
.
.
THEN
WHERE? ON ;
If any error occurs while WHERE executes, WHERE does nothing but set the variable WHERE? to true.
Here's a solution involving self modifying code:
Code: Select all
HEX
: WHERE ( -- )
// SWITCH WHERE OFF
['] EXIT (IS) RECURSE
// The main body of WHERE
.
.
.
Code: Select all
['] EXIT (IS) RECURSE
Code: Select all
: ABORT ( -- )
ERR SP! AP!
QUIT ; -2 ALLOT
Code: Select all
: ABORT ( -- )
ERR SP! AP! ['] LIT (IS) WHERE
QUIT ; -2 ALLOT
By the way, the word ERR is a deferred word to allow extending the error handling. It is normally set to the word NOOP , a no-op.