Operators in Forth
Learn arithmetic, comparison, logical, and stack-manipulation operators in Forth using reverse Polish notation on the data stack
In most programming languages, an expression like (2 + 3) * 4 is parsed by the compiler with carefully defined precedence and associativity rules. Forth takes an entirely different approach: there are no operators in the conventional sense at all. Every “operator” is just another word that consumes values from the data stack and pushes its result back. Because evaluation is strictly left-to-right and operands appear before the word that uses them, Forth has no operator precedence to memorize — the order you write things is the order they happen.
This tutorial covers the categories of operators you will use most often: arithmetic (+, -, *, /, MOD), stack manipulation (DUP, SWAP, OVER, DROP, ROT), comparison (=, <>, <, >), and bitwise/logical (AND, OR, INVERT). All of them follow the same model — they are words, and they communicate through the stack.
A note on notation: Forth uses postfix (reverse Polish) form. Instead of 2 + 3, you write 2 3 +. The numbers are pushed onto the stack first, and then + pops the top two values, adds them, and pushes the result. Once this clicks, complex expressions become a simple sequence of stack transformations.
Arithmetic Operators
Forth’s arithmetic words consume operands from the stack and leave the result on the stack. Use . (dot) to pop and print a number.
Create a file named operators.fth:
| |
How each line works
2 3 +pushes 2, pushes 3, then+pops both and pushes 5.20 3 /performs integer division. Gforth follows symmetric/floored semantics for positive operands, so the result is 6.20 3 MODleaves the remainder,2, on the stack.20 3 /MODis a combined word with stack effect( n1 n2 -- rem quot ). It is more efficient than doing/andMODseparately because the underlying CPU produces both in a single divide.NEGATEandABSare unary — they consume one value and produce one.
Stack Manipulation as “Operators”
In Forth, moving values around on the stack is just as fundamental as arithmetic. These words have no analogue in infix languages because variables and parentheses normally hide the question of where values live.
The most important stack words and their effects:
| Word | Stack effect | Description |
|---|---|---|
DUP | ( a -- a a ) | Duplicate the top item |
DROP | ( a -- ) | Discard the top item |
SWAP | ( a b -- b a ) | Exchange the top two items |
OVER | ( a b -- a b a ) | Copy the second item to the top |
ROT | ( a b c -- b c a ) | Rotate the third item to the top |
These are how you “name” operands without using variables. For example, to compute x² + 1 without storing x in a variable, you duplicate it:
| |
Comparison Returns a Flag
Comparison words like =, <>, <, >, <=, >= consume two values and push a flag: -1 (all bits set) for true and 0 for false. This is the same convention used by AND, OR, and INVERT, which means logical and bitwise operations are unified — there is no separate boolean type.
| |
Because -1 is all bits set in two’s complement, bitwise AND/OR/INVERT work correctly as logical operators on these flags.
No Operator Precedence
In most languages, 2 + 3 * 4 evaluates to 14 because * binds tighter than +. In Forth, you choose the order by writing words in that order:
| |
Parentheses are not needed because the stack itself records the partial results. Many Forth programmers consider this the language’s biggest readability win once they adjust: what you see is exactly what happens, step by step.
Running with Docker
| |
Expected Output
2 + 3 = 5
10 - 4 = 6
6 * 7 = 42
20 / 3 = 6
20 MOD 3 = 2
20 /MOD 3 -> 6 2
NEGATE 5 = -5
ABS -7 = 7
DUP of 4: 4 4
SWAP 1 2: 1 2
OVER 1 2: 1 2 1
3 = 3 -> -1
3 < 5 -> -1
5 > 3 -> -1
-1 AND 0 -> 0
-1 OR 0 -> -1
INVERT 0 -> -1
(2+3)*4 = 20
Note: Gforth’s . always prints a trailing space after a number. The /MOD line shows 6 2 because the quotient was on top of the stack — the first . pops and prints it, then the second . prints the remainder underneath.
Key Concepts
- Operators are words.
+,*,=, andDUPare all just words that operate on the data stack — there is no special operator syntax. - Postfix is precedence-free. The order you write words is the order they execute. Parentheses are never needed for arithmetic.
- Stack effect comments matter. Notation like
( a b -- b a )documents what a word consumes and produces. Reading and writing these is essential Forth literacy. - Booleans are integers. True is
-1(all bits set), false is0. This letsAND,OR,INVERTserve as both bitwise and logical operators. /MODis faster than/andMODseparately. Combined words exist because the underlying machine often produces both results in one operation.- Stack manipulation replaces variables.
DUP,SWAP,OVER, andROTare the way you reuse and rearrange values without binding them to names. - Whitespace separates words.
2 3+is an error or a strange identifier — every word, including operators, must be surrounded by spaces.
Running Today
All examples can be run using Docker:
docker pull forthy42/gforth:latest
Comments
Loading comments...
Leave a Comment