mdhender

super secret hq

Branching In False Forth

Most programming languages support conditional logic by using a some form of “if condition then codeBlock1 else codeBlock2 end-if.” The “else codeBlock2” is usually optional.

The “condition” evaluates to either true or false. If the condition evaluates to true, the code in the first block is executed. Otherwise, the code in the second block is executed (assuming that it is present).

Most programming languages support conditional logic by using a some form of “if condition then codeBlock1 else codeBlock2 end-if.” The “else codeBlock2” is usually optional.

The “condition” evaluates to either true or false. If the condition evaluates to true, the code in the first block is executed. Otherwise, the code in the second block is executed (assuming that it is present).

In C, that code looks like:

if (value == 42) {
  CodeBlock1();
} else {
  CodeBlock2();
}
CodeBlock3();

False Forth writes the code as:1

value 42 = if codeBlock1 else codeBlock2 end-if codeBlock3

As with the C example, codeBlock1 executes if the value is equal to 42, other wise codeBlock2 is executed. CodeBlock3 is always executed since it follows the “if” statement.

The Condition

The first three words, “value 42 =,” are the condition. The “=” word pops two words off the stack and compares them. If those values are not equal, then zero is pushed on to the stack. Zero is pushed because Forth treats zero as false.

If they are equal, then a non-zero value is pushed. The exact value is not important, but it must be non-zero. In Forth, any non-zero value is considered to be true.

If you want to get philosophical, you can say there are many paths to the truth, but only one false path.

IF

The “if” word pops a value from the stack and tests it for true or false. As stated above, a value of zero is considered to be false. Any non-zero value is non-zero is treated as true.

If the condition is true, all the code between the “if” and the “else” is executed. If there is no “else,” then all the code between the “if” and the “end-if” is executed.

ELSE

The “else” functions as a label. All the code between the “else” and “end-if” is executed if the condition is not true.2

END-IF

The “end-if” also functions as a label. No matter what happens, the code will eventually flow through this label.

How this works in False Forth

The pseudo-assembler below shows how our example works:

cmp     value,42
jz      else
exec    codeBlock1
jmp     end-if

:else   ;; label used as a jump target

exec    codeBlock2

:end-if ;; label used as a jump target

exec    codeBlock3

If the code doesn’t have an “else,” the interpreter will silently insert a label just before the “end-if.” It won’t associate any code with it, so the result will be similar to:

cmp     value,42
jz      else
exec    codeBlock1
jmp     end-if

:else   ;; label used as a jump target
:end-if ;; label used as a jump target

exec    codeBlock3

That’s all that I have to say about the if/then/else for the moment. Next up, we’ll go over the code that implements this.


  1. In Forth, the code looks like value 42 = if codeBlock2 else codeBlock1 then codeBlock3. The order of the blocks is reversed, and the “then” serves to end the “if” statement. There’s a certain vibe to this, but I find it awkward to write. [return]
  2. The real code actually allows for NULL values, so this is true, but not 100% accurate. [return]

Comments