Overview
Forth is a stack-based programming language. Values are pushed onto a
data stack, and words (commands) pop their arguments from the stack and
push results back. Forth is case-insensitive.
Data Types
All values are 64-bit signed integers (i64). Boolean results
use Forth convention: -1 for true, 0 for false.
Syntax
Forth programs are sequences of whitespace-separated tokens. Numeric
literals are pushed onto the stack. Named tokens are looked up in the
dictionary and executed. New words are defined with
: name … ;.
Stack Operations
| Word | Stack Effect | Description |
dup | ( a -- a a ) | Duplicate top of stack |
drop | ( a -- ) | Discard top of stack |
swap | ( a b -- b a ) | Swap top two items |
over | ( a b -- a b a ) | Copy second item to top |
rot | ( a b c -- b c a ) | Rotate third item to top |
nip | ( a b -- b ) | Drop second item |
tuck | ( a b -- b a b ) | Copy top below second |
Arithmetic
| Word | Stack Effect | Description |
+ | ( a b -- a+b ) | Addition (wrapping) |
- | ( a b -- a-b ) | Subtraction (wrapping) |
* | ( a b -- a*b ) | Multiplication (wrapping) |
/ | ( a b -- a/b ) | Integer division (error if b=0) |
mod | ( a b -- a%b ) | Modulo (error if b=0) |
negate | ( a -- -a ) | Negate |
abs | ( a -- |a| ) | Absolute value |
Comparison
| Word | Stack Effect | Description |
= | ( a b -- flag ) | Equal |
<> | ( a b -- flag ) | Not equal |
< | ( a b -- flag ) | Less than |
> | ( a b -- flag ) | Greater than |
<= | ( a b -- flag ) | Less than or equal |
>= | ( a b -- flag ) | Greater than or equal |
0= | ( a -- flag ) | Equal to zero |
0< | ( a -- flag ) | Less than zero |
0> | ( a -- flag ) | Greater than zero |
Logic
| Word | Stack Effect | Description |
and | ( a b -- a&b ) | Bitwise AND |
or | ( a b -- a|b ) | Bitwise OR |
xor | ( a b -- a^b ) | Bitwise XOR |
invert | ( a -- ~a ) | Bitwise NOT |
Return Stack
| Word | Stack Effect | Description |
>r | ( a -- ) R:( -- a ) | Move value to return stack |
r> | ( -- a ) R:( a -- ) | Move value from return stack |
r@ | ( -- a ) R:( a -- a ) | Copy top of return stack |
I/O
| Word | Stack Effect | Description |
. | ( a -- ) | Print top of stack followed by a space |
emit | ( a -- ) | Print value as ASCII character (0–127) |
cr | ( -- ) | Print a newline |
key | ( -- a ) | Read one byte of input (0 if no input) |
Strings
| Word | Stack Effect | Description |
s" | ( -- addr len ) | String literal (usage: s" text") |
type | ( addr len -- ) | Print a string |
Secrets
| Word | Stack Effect | Description |
env | ( addr len -- addr len ) | Read a secret by name; returns its value as a string |
HTTP Outbound
| Word | Stack Effect | Description |
http-get | ( addr len -- addr len ) | HTTP GET request; returns response body |
http-post | ( addr1 len1 addr2 len2 -- addr len ) | HTTP POST (url, body); returns response body |
KV Storage
| Word | Stack Effect | Description |
kv-get | ( addr len -- addr len ) | Get value for key; returns empty string if not found |
kv-set | ( addr1 len1 addr2 len2 -- ) | Set key (addr1/len1) to value (addr2/len2) |
kv-del | ( addr len -- ) | Delete key |
KV storage is only available for saved functions (not ad-hoc /api/run).
Control Flow
| Word | Stack Effect | Description |
if | ( flag -- ) | Begin conditional: execute if flag is nonzero |
else | ( -- ) | Begin false branch of if |
then | ( -- ) | End conditional |
recurse | ( -- ) | Call the word currently being defined |
Control flow words (if/else/then,
recurse) can only be used inside word definitions.
Loops
| Word | Stack Effect | Description |
do | ( limit start -- ) | Begin counted loop (start to limit-1) |
loop | ( -- ) | Increment index by 1, loop back to do if index < limit |
+loop | ( n -- ) | Increment index by n, loop back to do |
i | ( -- index ) | Push current loop index |
j | ( -- index ) | Push outer loop index (nested loops) |
leave | ( -- ) | Exit the current do loop |
begin | ( -- ) | Mark beginning of indefinite loop |
until | ( flag -- ) | Loop back to begin if flag is 0 |
again | ( -- ) | Loop back to begin unconditionally |
while | ( flag -- ) | Exit loop (jump past repeat) if flag is 0 |
repeat | ( -- ) | Loop back to begin (used with while) |
Loop words can only be used inside word definitions.
Memory
| Word | Stack Effect | Description |
@ | ( addr -- val ) | Fetch value from memory address |
! | ( val addr -- ) | Store value at memory address |
variable | ( -- ) | Create a named variable (usage: variable x) |
constant | ( val -- ) | Create a named constant (usage: 99 constant max) |
Comments
| Word | Description |
( | Begin inline comment (skips to next )) |
\ | Line comment (skips to end of line) |
Compilation
| Word | Description |
: | Begin word definition (usage: : name ... ;) |
; | End word definition |
Examples
Factorial
: fact dup 1 > if dup 1 - recurse * then ;
5 fact . \ prints: 120
Fibonacci
: fib ( n -- fib[n] )
0 1 rot 0 do over + swap loop drop ;
10 fib . \ prints: 55
FizzBuzz (1–20)
: fizzbuzz
21 1 do
i 15 mod 0= if 70 emit 66 emit \ FB
else i 3 mod 0= if 70 emit \ F
else i 5 mod 0= if 66 emit \ B
else i .
then then then
cr
loop ;
fizzbuzz
Variables and memory
variable counter
0 counter ! \ initialize to 0
counter @ 1 + counter ! \ increment
counter @ . \ prints: 1
Begin…while…repeat loop
: count5 0 begin dup 5 < while dup . 1 + repeat drop ;
count5 \ prints: 0 1 2 3 4
Constraints
- Cell type:
i64 (64-bit signed integer)
- Memory: 65,536 cells
- Stack depth: 1,024 (data and return stacks)
- Word name length: 32 characters max
- Instruction limit (CLI): 10,000,000
- Instruction limit (API): 500,000
- Division by zero is a runtime error
- Stack underflow/overflow is a runtime error