Go Forth Again

In which I learn how to regain control.

In Forth ifwhile, and similar control flow constructs are not builtin but implemented. Implement them in your Forth.

http://beza1e1.tuxen.de/articles/forth.html

Let’s start with IF ... ELSE ... THEN. This construct doesn’t have a run time primitive word (or words). Instead it compiles as follows:

cond IF conditional-words THEN trailing-words

becomes

cond 0 = BRANCH? conditional-words trailing-words

In the above <trailing-words> is the relative offset of *trailing-words*. The 0 = logically inverts the original condition.

cond IF conditional-words ELSE else-words THEN trailing-words

becomes

cond 0 = BRANCH? conditional-words BRANCH else-words trailing-words

The problem is that we can’t put in the offset for the branch at the point where we encounter the IF because we don’t know how far along the ELSE or THEN will be. Instead we’ll put in a placeholder to be filled in with the offset later. When we get to the THEN or the ELSE we need to know where the placeholder was so we can go back and put it in. For an ELSE we then have to repeat the process for the THEN.

It as to be possible to nest control structures, so the natural way to implement this is through a stack called the control-flow stack. You can fold the control flow stack into the data stack as gforth does, but I am going to keep it separate for now on the grounds that my data stack only holds integers and we will need two types of value: dest for backward jumps (e.g. a loop) and orig for forward jumps (THEN and ELSE).

The code for IFELSETHEN is tagged blog-1070-1

It has not escaped my notice that I now have a failing unit test. Because I tightened up the conditions for executing in interpreting mode and executing in compile mode, comments no longer work in interpreting mode. I was going to continue this blog by discussing loops, but that is going to have to go by the wayside while I refactor compilation and interpreting semantics.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.