SLP-FORTH

Stack-Oriented Programming Language

Dial 555-0400 to Launch

Introduction

Welcome to SLP-FORTH, the Emulator.ca Systems implementation of a Forth-83-style stack interpreter with many ANS/Core words. It is not a certified complete ANS Forth system; it is a compact, interactive Forth environment for learning stack programming over the modem. This is not merely another programming language---it is a fundamentally different way of thinking about computation.

FORTH is unlike any programming language you have encountered before. Where most languages hide the machine behind layers of abstraction, FORTH invites you to think with the machine. There are no hidden mechanisms, no complex syntax rules, no operator precedence tables to memorize. Just a stack of numbers and a dictionary of words--and the freedom to extend that dictionary however you wish.

Charles H. Moore created FORTH in the late 1960s while working at the National Radio Astronomy Observatory. He needed a language that could control radio telescope equipment in real time, with limited memory and processing power. The result was a language of remarkable elegance: small enough to fit in a few kilobytes, yet extensible enough to tackle any problem. Since then, FORTH has found its way into satellites, industrial controllers, video games, and countless embedded systems where efficiency matters.

SLP-FORTH brings this heritage to your EC-series terminal. Within minutes of connecting, you can be experimenting with stack operations, defining your own words, and building programs from the ground up. The interactive nature of FORTH means you test each piece as you write it--no compile-link-run cycle, just immediate feedback.

This implementation provides:

NOTE

SLP-FORTH provides responsive interaction even during computation. You may interrupt execution at any time with the ESC key.

Quick Start

Connect to SLP-FORTH and try these examples to get a feel for stack-based programming:

+------------------------------------------------------------------+
|  QUICK START SESSION                                             |
+------------------------------------------------------------------+
|  ATDT555-0400                                                    |
|  CONNECT 1200                                                    |
|                                                                  |
|    SLP-FORTH v2.1                                                |
|    Emulator.ca Systems                                           |
|                                                                  |
|  ok 5 3 + .                      \ Add 5 and 3, print result     |
|  8 ok                                                            |
|                                                                  |
|  ok : SQUARE  DUP * ;            \ Define a new word             |
|  ok 7 SQUARE .                   \ Use your word                 |
|  49 ok                                                           |
|                                                                  |
|  ok 10 0 DO I . LOOP             \ Count from 0 to 9             |
|  0 1 2 3 4 5 6 7 8 9 ok                                          |
|                                                                  |
|  ok VARIABLE COUNTER             \ Create a variable             |
|  ok 0 COUNTER !                  \ Store 0 in it                 |
|  ok COUNTER @ 1+ COUNTER !       \ Increment it                  |
|  ok COUNTER @ .                  \ Print it                      |
|  1 ok                                                            |
|                                                                  |
|  ok : GREET  ." Hello, World!" CR ;                              |
|  ok GREET                                                        |
|  Hello, World!                                                   |
|  ok                                                              |
+------------------------------------------------------------------+

Key concepts to remember:

  1. Numbers go on the stack when you type them
  2. Operations consume values from the stack and leave results
  3. . prints and removes the top number; .S shows all without removing
  4. : begins a definition; ; ends it
  5. Everything after \ is a comment

Now read on to understand the philosophy and mechanics behind these simple commands.

The FORTH Philosophy

FORTH is built upon a deceptively simple concept: the stack. In most languages, you write expressions like 2 + 3 and the language figures out what to do. In FORTH, you place values on a stack and then invoke operations that consume and produce stack values:

2 3 +

This "Reverse Polish Notation" (RPN) style eliminates the need for parentheses and operator precedence rules. The expression (2 + 3) * 4 becomes simply:

2 3 + 4 *

Read it aloud: "Two. Three. Add them. Four. Multiply." Each word does exactly one thing, and you can see precisely what happens at each step.

Extensibility: The Heart of FORTH

In FORTH, you don't just write programs--you extend the language itself. Every word you define becomes indistinguishable from the built-in words. You build up a vocabulary specific to your problem domain, layer by layer, until solving the problem becomes a single word.

THE FORTH WAY

Write short definitions. Test each word immediately. Build complex behavior from simple, tested components. If a definition is longer than a few lines, factor it into smaller words.

The Two Stacks

SLP-FORTH maintains two stacks:

Most of your interaction will be with the data stack. The return stack is powerful but must be used carefully--it holds return addresses during word execution.

Getting Connected

To access the SLP-FORTH interpreter, configure your modem for dial-out and issue the following command:

ATDT555-0400

Upon successful connection, you will see the FORTH banner and the ok prompt:

Connection Sequence

ATDT555-0400
CONNECT 1200

  SLP-FORTH v2.1
  Emulator.ca Systems
  153 words, 4096 cells data space

ok

The ok prompt indicates FORTH is ready to accept input. Unlike other languages that use "READY" or ">", FORTH's laconic ok reflects its minimalist philosophy.

Modem Signals

The FORTH interpreter participates fully in RS-232 signal protocol:

Signal Direction Function
DTR DTE->DCE Asserted when interpreter is ready; dropped to hangup
RTS DTE->DCE Asserted when interpreter can accept output
CTS DCE->DTE When deasserted, output is throttled (flow control)
DCD DCE->DTE Carrier detect - connection status

TIP

Press ESC at any time to interrupt a running FORTH program. You'll return to the ok prompt.

The Stack Concept

The data stack is FORTH's central mechanism for passing data between words. Think of it as a stack of cafeteria trays: you can only add to the top (push) or remove from the top (pop). The last item placed on the stack is the first one removed--this is called LIFO (Last In, First Out).

    STACK VISUALIZATION
    

    After: 5 3 7

         
          7   <- Top of Stack (TOS)
         
          3   <- Next on Stack (NOS)  
         
          5 
         
           ^
        Bottom

Basic Stack Operations

Enter numbers separated by spaces. Each number is pushed onto the stack:

Pushing Numbers

5 ok
3 ok
7 ok
.S <3> 5 3 7 ok

The word .S (pronounced "dot-S") displays the stack contents without disturbing them. The <3> indicates there are 3 items on the stack.

Stack Notation Convention

FORTH uses a standard notation to document the stack effect of each word:

( before -- after )

The items before the -- are consumed from the stack; items after are left on the stack. For example:

+    ( n1 n2 -- sum )     \ Add n1 and n2, leave sum
DUP  ( n -- n n )         \ Duplicate top of stack
DROP ( n -- )             \ Discard top of stack
SWAP ( n1 n2 -- n2 n1 )   \ Exchange top two items

The backslash \ begins a comment that extends to end of line.

NOTATION

In stack diagrams: n = number, addr = address, flag = boolean (0 = false, -1 = true), c = character code, xt = execution token.

Stack Manipulation Words

These words rearrange values on the data stack without performing arithmetic. Mastering them is essential to writing elegant FORTH.

Word Stack Effect Description
DUP ( n -- n n ) Duplicate top item
DROP ( n -- ) Discard top item
SWAP ( n1 n2 -- n2 n1 ) Exchange top two items
OVER ( n1 n2 -- n1 n2 n1 ) Copy second item to top
ROT ( n1 n2 n3 -- n2 n3 n1 ) Rotate top three items
NIP ( n1 n2 -- n2 ) Discard second item
TUCK ( n1 n2 -- n2 n1 n2 ) Copy top under second
PICK ( xn...x0 n -- xn...x0 xn ) Copy nth item (0 = top)
ROLL ( xn...x0 n -- xn-1...x0 xn ) Rotate n+1 items
2DUP ( n1 n2 -- n1 n2 n1 n2 ) Duplicate top pair
2DROP ( n1 n2 -- ) Discard top pair
2SWAP ( a b c d -- c d a b ) Swap two pairs
2OVER ( a b c d -- a b c d a b ) Copy second pair to top
?DUP ( n -- 0 | n n ) Duplicate only if non-zero
DEPTH ( -- n ) Return stack depth

Stack Manipulation Examples

1 2 3 .S <3> 1 2 3 ok
DUP .S <4> 1 2 3 3 ok
DROP .S <3> 1 2 3 ok
SWAP .S <3> 1 3 2 ok
ROT .S <3> 3 2 1 ok
OVER .S <4> 3 2 1 2 ok

TIP

Use .S liberally while learning. It shows the stack without changing it, which is invaluable for debugging.

Arithmetic Operations

FORTH arithmetic words take their operands from the stack and leave results on the stack. All operations work with signed 32-bit integers.

Word Stack Effect Description
+ ( n1 n2 -- sum ) Add
- ( n1 n2 -- diff ) Subtract (n1 - n2)
* ( n1 n2 -- prod ) Multiply
/ ( n1 n2 -- quot ) Divide (n1 / n2)
MOD ( n1 n2 -- rem ) Remainder
/MOD ( n1 n2 -- rem quot ) Divide giving both
*/ ( n1 n2 n3 -- n ) n1*n2/n3 with double intermediate
*/MOD ( n1 n2 n3 -- rem quot ) */ with remainder
NEGATE ( n -- -n ) Change sign
ABS ( n -- |n| ) Absolute value
MIN ( n1 n2 -- min ) Smaller of two
MAX ( n1 n2 -- max ) Larger of two
1+ ( n -- n+1 ) Increment
1- ( n -- n-1 ) Decrement
2* ( n -- n*2 ) Double (arithmetic shift left)
2/ ( n -- n/2 ) Halve (arithmetic shift right)

Arithmetic Examples

\ Simple addition
3 4 + . 7 ok

\ Expression: (10 + 5) * 3
10 5 + 3 * . 45 ok

\ Get remainder: 17 MOD 5
17 5 MOD . 2 ok

\ Divide with remainder
17 5 /MOD . . 3 2 ok    \ quotient 3, remainder 2

\ Absolute value
-42 ABS . 42 ok

\ Find larger of two numbers
25 17 MAX . 25 ok

\ Increment and double
5 1+ 2* . 12 ok

WARNING

Division by zero will produce an error. Always validate divisors when accepting user input!

Comparison and Logic

Comparison words test relationships between values and leave a flag on the stack. In ANS FORTH, 0 represents FALSE and -1 (all bits set) represents TRUE. Any non-zero value is treated as true in conditionals.

Word Stack Effect Description
= ( n1 n2 -- flag ) Equal
<> ( n1 n2 -- flag ) Not equal
< ( n1 n2 -- flag ) Less than (signed)
> ( n1 n2 -- flag ) Greater than (signed)
U< ( u1 u2 -- flag ) Less than (unsigned)
U> ( u1 u2 -- flag ) Greater than (unsigned)
0= ( n -- flag ) Is zero?
0<> ( n -- flag ) Is not zero?
0< ( n -- flag ) Is negative?
0> ( n -- flag ) Is positive?
WITHIN ( n lo hi -- flag ) True if lo <= n < hi
TRUE ( -- -1 ) Canonical true flag
FALSE ( -- 0 ) Canonical false flag

Logical Operations

These perform bitwise operations, useful for both logic and bit manipulation:

Word Stack Effect Description
AND ( n1 n2 -- n3 ) Bitwise AND
OR ( n1 n2 -- n3 ) Bitwise OR
XOR ( n1 n2 -- n3 ) Bitwise exclusive OR
INVERT ( n -- ~n ) Bitwise complement
LSHIFT ( n u -- n' ) Logical left shift by u bits
RSHIFT ( n u -- n' ) Logical right shift by u bits

Comparison Examples

5 3 > . -1 ok          \ 5 > 3 is TRUE
5 3 < . 0 ok           \ 5 < 3 is FALSE
5 5 = . -1 ok          \ 5 = 5 is TRUE
TRUE TRUE AND . -1 ok  \ Both true, result TRUE
5 0 10 WITHIN . -1 ok  \ 5 is within [0,10)

NOTE

TRUE is -1 (all bits set to 1) because this makes AND and OR work correctly for both logical and bitwise operations.

Input and Output

FORTH provides simple but powerful I/O words for terminal interaction.

Word Stack Effect Description
. ( n -- ) Print number with trailing space
U. ( u -- ) Print unsigned number
.R ( n width -- ) Print right-justified in width
U.R ( u width -- ) Print unsigned right-justified
EMIT ( c -- ) Output ASCII character
CR ( -- ) Output carriage return/newline
SPACE ( -- ) Output single space
SPACES ( n -- ) Output n spaces
.S ( -- ) Display stack non-destructively
." ( -- ) Print string literal (compile only)
.( ( -- ) Print string immediately
TYPE ( addr len -- ) Print len characters from addr
COUNT ( addr -- addr+1 len ) Convert counted string
BL ( -- 32 ) Push blank (space) character
KEY ( -- c ) Wait for and read one character
KEY? ( -- flag ) Is a character available?
ACCEPT ( addr n -- n' ) Read line into buffer

Output Examples

\ Print a number
42 . 42 ok

\ Print multiple numbers (note: reverse order)
1 2 3 . . . 3 2 1 ok

\ Print ASCII character (65 = 'A')
65 EMIT A ok

\ Print formatted
123 8 .R      123 ok   \ Right-justified in 8 columns

\ Print string in definition
: HELLO  ." Hello, World!" CR ;
HELLO
Hello, World!
ok

Number Base

FORTH can work in different number bases:

Word Stack Effect Description
BASE ( -- addr ) Variable holding current base
DECIMAL ( -- ) Set base to 10
HEX ( -- ) Set base to 16

Number Base Examples

HEX
FF . FF ok
10 . 10 ok        \ This is 16 in decimal!
DECIMAL
255 . 255 ok

Defining New Words

The true power of FORTH lies in extending the language with your own words. A word definition begins with : (colon) and ends with ; (semicolon):

: word-name  definition... ;

Simple Word Definitions

\ Define a word to square a number
: SQUARE  ( n -- n^2 )  DUP * ;
5 SQUARE . 25 ok

\ Define a word using our new word
: CUBE  ( n -- n^3 )  DUP SQUARE * ;
3 CUBE . 27 ok

\ Define a word to add 10
: ADD10  ( n -- n+10 )  10 + ;
5 ADD10 . 15 ok

\ Chain definitions
: DOUBLE  ( n -- n*2 )  DUP + ;
: QUADRUPLE  ( n -- n*4 )  DOUBLE DOUBLE ;
7 QUADRUPLE . 28 ok

Compilation vs. Interpretation

When FORTH sees :, it enters compilation mode. Words entered are not executed immediately--they're compiled into the new definition. The ; returns to interpretation mode.

Immediate Words

Some words execute even during compilation. These are marked with IMMEDIATE after their definition. Control structure words like IF and DO are immediate--they compile branch instructions into your definition.

Documentation Comments

\ The ( comment is by convention used for stack effects
: AVERAGE  ( n1 n2 -- avg )   + 2 / ;

\ You can add descriptive comments with backslash
: CELSIUS  ( fahrenheit -- celsius )
   32 -        \ subtract freezing point
   5 *         \ multiply by 5
   9 / ;       \ divide by 9

WARNING

Redefining an existing word creates a new definition but does not update words already compiled that use the old definition.

Control Structures

FORTH provides several control structures that can only be used inside colon definitions. They compile into efficient branch instructions.

IF...ELSE...THEN

Conditional execution based on a flag:

: word  ... flag IF true-part THEN ... ;
: word  ... flag IF true-part ELSE false-part THEN ... ;

The IF consumes a flag from the stack. If true (non-zero), the true-part executes; otherwise execution jumps to ELSE (if present) or THEN.

IF Examples

: ABS  ( n -- |n| )
   DUP 0< IF NEGATE THEN ;
-5 ABS . 5 ok

: MAX  ( n1 n2 -- max )
   2DUP > IF DROP ELSE NIP THEN ;
3 7 MAX . 7 ok

: SIGN  ( n -- )
   DUP 0< IF ." negative" DROP
   ELSE DUP 0> IF ." positive" DROP
   ELSE ." zero" DROP
   THEN THEN ;
-5 SIGN negative ok

BEGIN...UNTIL

Loop that tests at the end (do-while style):

: word  ... BEGIN body flag UNTIL ... ;

The body executes, then UNTIL consumes a flag. If false, loop continues; if true, loop exits.

BEGIN...UNTIL Example

: COUNTDOWN  ( n -- )
   BEGIN
      DUP .
      1-
      DUP 0=
   UNTIL
   DROP ;
5 COUNTDOWN 5 4 3 2 1 ok

BEGIN...WHILE...REPEAT

Loop that tests at the beginning (while style):

: word  ... BEGIN condition WHILE body REPEAT ... ;

BEGIN...WHILE...REPEAT Example

: COUNTDOWN  ( n -- )
   BEGIN
      DUP 0>       \ while n > 0
   WHILE
      DUP .        \ print n
      1-           \ decrement
   REPEAT
   DROP ;
5 COUNTDOWN 5 4 3 2 1 ok

BEGIN...AGAIN

Infinite loop (use EXIT to break out):

: word  ... BEGIN body AGAIN ... ;

EXIT

Exit the current word immediately:

: FIND-ZERO  ( addr n -- addr | 0 )
   0 DO
      DUP I + C@
      0= IF DUP I + UNLOOP EXIT THEN
   LOOP
   DROP 0 ;

RECURSE

Call the word being defined from within itself. This enables recursive algorithms:

\ Recursive factorial using RECURSE
: FACTORIAL  ( n -- n! )
   DUP 1 > IF
      DUP 1- RECURSE *
   THEN ;

5 FACTORIAL . 120 ok

RECURSE compiles a call to the word currently being defined. Without RECURSE, you cannot call a word by name until its definition is complete (the ; is reached). This is the standard way to write recursive definitions in Forth.

Recursive Fibonacci

: FIB  ( n -- fib )
   DUP 2 < IF EXIT THEN
   DUP  1- RECURSE
   SWAP 2 - RECURSE + ;

10 FIB . 55 ok

Counted Loops (DO/LOOP)

FORTH provides powerful counted loops using the return stack:

Word Stack Effect Description
DO ( limit start -- ) Begin counted loop
?DO ( limit start -- ) DO, but skip if limit=start
LOOP ( -- ) Increment index, loop if < limit
+LOOP ( n -- ) Add n to index, loop if boundary not crossed
I ( -- index ) Current loop index
J ( -- index ) Outer loop index (nested loops)
LEAVE ( -- ) Exit loop immediately
UNLOOP ( -- ) Remove loop parameters (before EXIT)

The loop runs while index < limit. DO pushes the loop parameters onto the return stack; LOOP or +LOOP pops them when done.

DO/LOOP Examples

\ Print 0 to 9
: COUNT10  10 0 DO I . LOOP ;
COUNT10 0 1 2 3 4 5 6 7 8 9 ok

\ Print evens from 0 to 10
: EVENS  12 0 DO I . 2 +LOOP ;
EVENS 0 2 4 6 8 10 ok

\ Count down from 10 to 1
: COUNTDOWN  0 10 DO I . -1 +LOOP ;
COUNTDOWN 10 9 8 7 6 5 4 3 2 1 ok

\ Nested loops with J
: TABLE  3 0 DO  3 0 DO  I J * 4 .R  LOOP CR LOOP ;
TABLE
   0   0   0
   0   1   2
   0   2   4
ok

\ Skip empty loop with ?DO
: SAFE-COUNT  ( n -- )  0 ?DO I . LOOP ;
0 SAFE-COUNT ok      \ Prints nothing
3 SAFE-COUNT 0 1 2 ok

WARNING

If you use EXIT inside a DO loop, you must call UNLOOP first to clean up the return stack!

Return Stack

The return stack is primarily used by FORTH for return addresses, but you can temporarily store values there:

Word Stack Effect Description
>R ( n -- ) R:( -- n ) Move to return stack
R> ( -- n ) R:( n -- ) Move from return stack
R@ ( -- n ) R:( n -- n ) Copy from return stack
2>R ( n1 n2 -- ) R:( -- n1 n2 ) Move pair to R
2R> ( -- n1 n2 ) R:( n1 n2 -- ) Move pair from R
2R@ ( -- n1 n2 ) R:( n1 n2 -- n1 n2 ) Copy pair from R

Return Stack Examples

\ Save a value while computing
: EXAMPLE  ( a b -- a*a+b )
   >R          \ save b on return stack
   DUP *       \ square a
   R> + ;      \ retrieve b and add
3 4 EXAMPLE . 13 ok

\ Use R@ to access without removing
: CUBE  ( n -- n^3 )
   >R
   R@ R@ *     \ n * n
   R> * ;      \ * n
4 CUBE . 64 ok

WARNING

Return stack must be balanced within a word! Every >R needs a corresponding R> before the word exits. Unbalanced use will crash the system.

Variables and Constants

FORTH provides named storage locations:

Word Stack Effect Description
VARIABLE name ( -- ) Create variable
CONSTANT name ( n -- ) Create constant with value n
VALUE name ( n -- ) Create value (changeable constant)
@ ( addr -- n ) Fetch from address
! ( n addr -- ) Store to address
+! ( n addr -- ) Add n to value at address
TO name ( n -- ) Store n to VALUE

Variable Examples

\ Create and use a variable
VARIABLE COUNTER
0 COUNTER !           \ Initialize to 0
COUNTER @ .           \ Print: 0
1 COUNTER +!          \ Increment
COUNTER @ .           \ Print: 1

\ Create and use a constant
42 CONSTANT ANSWER
ANSWER .              \ Print: 42

\ Accumulator pattern
VARIABLE SUM
: ADD-TO-SUM  ( n -- )  SUM +! ;
0 SUM !
10 ADD-TO-SUM 20 ADD-TO-SUM 30 ADD-TO-SUM
SUM @ .               \ Print: 60

VALUES

VALUES are like constants but can be changed with TO:

VALUE Examples

100 VALUE LIMIT
LIMIT .               \ Print: 100

200 TO LIMIT          \ Change it
LIMIT .               \ Print: 200

\ Use in definitions
0 VALUE TOTAL
: ADD-TO  ( n -- )  TOTAL + TO TOTAL ;
10 ADD-TO 20 ADD-TO 30 ADD-TO
TOTAL .               \ Print: 60

Memory Operations

FORTH provides direct memory access:

Word Stack Effect Description
HERE ( -- addr ) Current data space pointer
ALLOT ( n -- ) Reserve n cells of data space
, ( n -- ) Compile n into data space
C, ( c -- ) Compile character into data space
C@ ( addr -- c ) Fetch byte from address
C! ( c addr -- ) Store byte at address
2@ ( addr -- n1 n2 ) Fetch double cell
2! ( n1 n2 addr -- ) Store double cell
CELLS ( n -- n ) Convert to cell units
CHARS ( n -- n ) Convert to character units
CELL+ ( addr -- addr' ) Add cell size to address
CHAR+ ( addr -- addr' ) Add char size to address
MOVE ( src dest n -- ) Copy n cells
FILL ( addr n c -- ) Fill n cells with c
ERASE ( addr n -- ) Fill n cells with 0

CREATE and Arrays

CREATE makes a word that returns an address:

Array Examples

\ Create an array of 10 cells
CREATE MYARRAY 10 CELLS ALLOT

\ Store values
100 MYARRAY !           \ First element
200 MYARRAY CELL+ !     \ Second element

\ Fetch values
MYARRAY @ .             \ Print: 100
MYARRAY CELL+ @ .       \ Print: 200

\ Create initialized table
CREATE SQUARES  0 , 1 , 4 , 9 , 16 , 25 ,

SQUARES @ .             \ Print: 0
SQUARES 3 CELLS + @ .   \ Print: 9

CREATE...DOES>

The DOES> word lets you create "defining words" that build custom data structures:

DOES> Examples

\ Define a word that creates constants
: MY-CONSTANT  ( n -- )
   CREATE ,
   DOES> @ ;

42 MY-CONSTANT ANSWER
ANSWER .              \ Print: 42

\ Define a word that creates arrays
: ARRAY  ( n -- )
   CREATE CELLS ALLOT
   DOES> SWAP CELLS + ;

10 ARRAY DATA         \ Create 10-element array
5 0 DATA !            \ Store 5 at index 0
7 1 DATA !            \ Store 7 at index 1
0 DATA @ .            \ Print: 5
1 DATA @ .            \ Print: 7

Strings

FORTH provides basic string handling:

Word Stack Effect Description
S" ( -- addr len ) String literal (in definitions)
." ( -- ) Print string literal (in definitions)
.( ( -- ) Print string immediately
TYPE ( addr len -- ) Print string
COUNT ( caddr -- addr len ) Convert counted string
CHAR ( -- c ) Parse word, return first char
[CHAR] ( -- c ) Compile char as literal

String Examples

: GREET  ." Hello, World!" CR ;
GREET
Hello, World!
ok

: BANNER
   ." ==================" CR
   ."   FORTH PROGRAM   " CR
   ." ==================" CR ;
BANNER
==================
  FORTH PROGRAM
==================
ok

\ Immediate string print
.( This prints immediately!)
This prints immediately! ok

Case Statements

For multi-way branching, use CASE:

: word  ... value
   CASE
      test1 OF action1 ENDOF
      test2 OF action2 ENDOF
      default-action
   ENDCASE ... ;

The selector value stays on the stack through the CASEs. When an OF matches, it drops the selector and executes the clause. ENDCASE drops the selector if no OF matched.

CASE Examples

: DAY-NAME  ( n -- )
   CASE
      0 OF ." Sunday"    ENDOF
      1 OF ." Monday"    ENDOF
      2 OF ." Tuesday"   ENDOF
      3 OF ." Wednesday" ENDOF
      4 OF ." Thursday"  ENDOF
      5 OF ." Friday"    ENDOF
      6 OF ." Saturday"  ENDOF
      ." Unknown"
   ENDCASE ;

3 DAY-NAME Wednesday ok
7 DAY-NAME Unknown ok

: DIGIT  ( n -- )
   CASE
      0 OF ." zero"  ENDOF
      1 OF ." one"   ENDOF
      2 OF ." two"   ENDOF
      ." many"
   ENDCASE ;

Execution Tokens

FORTH allows treating words as data through execution tokens:

Word Stack Effect Description
' ( -- xt ) Get execution token of next word
EXECUTE ( xt -- ) Execute word from token
['] ( -- ) Compile XT as literal
FIND ( caddr -- caddr 0 | xt 1 | xt -1 ) Look up word
>BODY ( xt -- addr ) Get data address from XT

Execution Token Examples

\ Get and execute a word
' DUP         \ Get XT of DUP
5 SWAP EXECUTE . . 5 5 ok

\ Store operation for later
' + CONSTANT ADD-OP
3 4 ADD-OP EXECUTE . 7 ok

\ Compile-time tick
: RUN-SQUARE  ['] SQUARE EXECUTE ;
5 RUN-SQUARE . 25 ok

Introspection

FORTH lets you examine and modify the dictionary:

Word Stack Effect Description
WORDS ( -- ) List all defined words
SEE ( -- ) Decompile next word
FORGET ( -- ) Remove word from dictionary

Introspection Examples

\ List all words
WORDS
... DUP DROP SWAP OVER ROT ...

\ See a definition
: SQUARE DUP * ;
SEE SQUARE
: SQUARE DUP * ;  ok

\ See a variable
VARIABLE X
SEE X
X is a VARIABLE at address 1234  ok

\ Forget a word (and all defined after it)
FORGET SQUARE
SQUARE   \ Error: undefined word

Advanced Compilation

These words give you control over the compilation process:

Word Stack Effect Description
[ ( -- ) Enter interpret mode (in definition)
] ( -- ) Enter compile mode
LITERAL ( n -- ) Compile number as literal
POSTPONE ( -- ) Compile compilation semantics
IMMEDIATE ( -- ) Mark last word as immediate
STATE ( -- addr ) Compilation state variable

Compile-Time Calculation

\ Calculate constant at compile time
: BUFFER-SIZE  [ 1024 16 * ] LITERAL ;
BUFFER-SIZE . 16384 ok

\ Create an immediate word
: SHOW-STATE  STATE @ . ; IMMEDIATE
: TEST  SHOW-STATE ;   \ Prints -1 during compilation
-1 ok

\ POSTPONE defers compilation
: ENDIF  POSTPONE THEN ; IMMEDIATE
: TEST  1 IF ." yes" ENDIF ;
TEST yes ok

Input Parsing

For advanced input processing:

Word Stack Effect Description
SOURCE ( -- addr len ) Current input buffer
>IN ( -- addr ) Parse position variable
WORD ( c -- caddr ) Parse word delimited by c
PARSE ( c -- addr len ) Parse to delimiter
PARSE-NAME ( -- addr len ) Parse space-delimited word
EVALUATE ( addr len -- ) Interpret string
QUIT ( -- ) Clear and restart interpreter

Error Handling

Word Stack Effect Description
ABORT ( -- ) Clear stacks and abort
ABORT" ( flag -- ) If flag, print message and abort

Error Handling Example

: SAFE-DIVIDE  ( n1 n2 -- n3 )
   DUP 0= ABORT" Division by zero!"
   / ;

10 2 SAFE-DIVIDE . 5 ok
10 0 SAFE-DIVIDE
Division by zero!
ok

Common Patterns and Idioms

Stack Manipulation Patterns

\ Square a number
: SQUARE  ( n -- n^2 )  DUP * ;

\ Double (two methods)
: DOUBLE  ( n -- n*2 )  DUP + ;
: DOUBLE  ( n -- n*2 )  2* ;

\ Absolute difference
: ABSDIFF  ( n1 n2 -- |n1-n2| )  - ABS ;

Conditional Patterns

\ Convert any non-zero to canonical TRUE
: BOOL  ( n -- flag )  0<> ;

\ Check if even/odd
: EVEN?  ( n -- flag )  1 AND 0= ;
: ODD?   ( n -- flag )  1 AND 0<> ;

\ Bounded value
: CLAMP  ( n min max -- n' )
   ROT MIN MAX ;

Loop Patterns

\ Sum 1 to n
: SUM-TO  ( n -- sum )
   0 SWAP  1+ 1 DO  I +  LOOP ;
10 SUM-TO . 55 ok

\ Factorial
: FACTORIAL  ( n -- n! )
   DUP 1 > IF
      DUP 1- FACTORIAL *
   ELSE
      DROP 1
   THEN ;
5 FACTORIAL . 120 ok

\ Iterate with callback (functional style)
: EACH  ( xt limit start -- )
   ?DO  DUP I SWAP EXECUTE  LOOP DROP ;
' . 5 0 EACH 0 1 2 3 4 ok

Quick Reference

Stack (15 words)

Word Effect Word Effect
DUP ( n -- n n ) DROP ( n -- )
SWAP ( a b -- b a ) OVER ( a b -- a b a )
ROT ( a b c -- b c a ) NIP ( a b -- b )
TUCK ( a b -- b a b ) PICK ( ...n -- ...xn )
ROLL ( ...n -- ...xn ) 2DUP ( a b -- a b a b )
2DROP ( a b -- ) 2SWAP ( a b c d -- c d a b )
2OVER ( a b c d -- ...a b ) ?DUP ( n -- 0 | n n )
DEPTH ( -- n )

Arithmetic (16 words)

Word Effect Word Effect
+ ( a b -- sum ) - ( a b -- diff )
* ( a b -- prod ) / ( a b -- quot )
MOD ( a b -- rem ) /MOD ( a b -- r q )
*/ ( a b c -- n ) */MOD ( a b c -- r q )
NEGATE ( n -- -n ) ABS ( n -- |n| )
MIN ( a b -- min ) MAX ( a b -- max )
1+ ( n -- n+1 ) 1- ( n -- n-1 )
2* ( n -- n*2 ) 2/ ( n -- n/2 )

Comparison (13 words)

Word Description Word Description
= Equal <> Not equal
< Less than > Greater than
U< Unsigned < U> Unsigned >
0= Is zero 0<> Not zero
0< Negative 0> Positive
WITHIN In range TRUE ( -- -1 )
FALSE ( -- 0 )

Logic (8 words)

Word Description Word Description
AND Bitwise AND OR Bitwise OR
XOR Exclusive OR INVERT Complement
LSHIFT Left shift RSHIFT Right shift
TRUE ( -- -1 ) FALSE ( -- 0 )

Control Flow (13 words)

Word Description
IF...ELSE...THEN Conditional
BEGIN...UNTIL Loop (test at end)
BEGIN...WHILE...REPEAT Loop (test at start)
BEGIN...AGAIN Infinite loop
CASE...OF...ENDOF...ENDCASE Multi-way branch
EXIT Return from word

Counted Loops (8 words)

Word Description
DO Begin loop (limit start --)
?DO Begin loop (skip if empty)
LOOP Increment and test
+LOOP Add n and test
I Current index
J Outer index
LEAVE Exit loop
UNLOOP Remove loop params

Return Stack (6 words)

Word Effect
>R ( n -- ) R:( -- n )
R> ( -- n ) R:( n -- )
R@ ( -- n ) R:( n -- n )
2>R ( a b -- ) R:( -- a b )
2R> ( -- a b ) R:( a b -- )
2R@ ( -- a b ) R:( a b -- a b )

I/O (17 words)

Word Description Word Description
. Print number U. Print unsigned
.R Print right-just U.R Unsigned right
.S Show stack CR Newline
EMIT Print char SPACE Print space
SPACES Print n spaces ." Print string
.( Print immediate TYPE Print addr/len
COUNT Counted string BL ( -- 32 )
KEY Read char KEY? Char ready?
ACCEPT Read line

Variables & Memory (20+ words)

Word Description Word Description
VARIABLE Create var CONSTANT Create const
VALUE Create value TO Set value
@ Fetch ! Store
+! Add to C@ Fetch byte
C! Store byte 2@ Fetch double
2! Store double HERE Data pointer
ALLOT Reserve space , Compile cell
C, Compile byte CREATE Make entry
DOES> Runtime action CELLS Cell units
CHARS Char units MOVE Copy block
FILL Fill block ERASE Zero block

Definitions & Compilation (10 words)

Word Description
: ... ; Define word
IMMEDIATE Mark immediate
[ ] Switch modes
LITERAL Compile number
POSTPONE Defer compile
STATE Compile state
' Get XT
['] Compile XT
EXECUTE Run XT
FIND Look up word

Introspection (4 words)

Word Description
WORDS List all words
SEE Decompile word
FORGET Remove word
>BODY XT to data addr

Number Base (3 words)

Word Description
BASE Base variable
DECIMAL Set base 10
HEX Set base 16

Parsing (5 words)

Word Description
SOURCE Input buffer
>IN Parse position
WORD Parse to delim
PARSE Parse string
PARSE-NAME Parse word

Evaluation (2 words)

Word Description
EVALUATE Interpret string
QUIT Restart interpreter

Error Handling (2 words)

Word Description
ABORT Abort execution
ABORT" Conditional abort

Appendix A: Quick Reference Card

+================================================================+
|                  SLP-FORTH QUICK REFERENCE                     |
+================================================================+
|                                                                |
|  DIAL: ATDT555-0400                                            |
|                                                                |
|  STACK MANIPULATION                                            |
|  DUP  DROP  SWAP  OVER  ROT  NIP  TUCK  ?DUP                   |
|  2DUP  2DROP  2SWAP  2OVER  PICK  ROLL  DEPTH                  |
|                                                                |
|  ARITHMETIC                                                    |
|  +  -  *  /  MOD  /MOD  */  */MOD                              |
|  NEGATE  ABS  MIN  MAX  1+  1-  2*  2/                         |
|                                                                |
|  COMPARISON (true = -1, false = 0)                             |
|  =  <>  <  >  U<  U>  0=  0<>  0<  0>  WITHIN                  |
|  TRUE  FALSE                                                   |
|                                                                |
|  LOGIC (bitwise)                                               |
|  AND  OR  XOR  INVERT  LSHIFT  RSHIFT                          |
|                                                                |
|  CONTROL FLOW                                                  |
|  IF...ELSE...THEN  BEGIN...UNTIL  BEGIN...WHILE...REPEAT       |
|  BEGIN...AGAIN  CASE...OF...ENDOF...ENDCASE  EXIT              |
|                                                                |
|  COUNTED LOOPS                                                 |
|  DO  ?DO  LOOP  +LOOP  I  J  LEAVE  UNLOOP                     |
|                                                                |
|  RETURN STACK                                                  |
|  >R  R>  R@  2>R  2R>  2R@                                     |
|                                                                |
|  I/O                                                           |
|  .  U.  .R  U.R  CR  EMIT  SPACE  SPACES  .S  ."  .(           |
|  TYPE  COUNT  BL  KEY  KEY?  ACCEPT                            |
|                                                                |
|  VARIABLES & MEMORY                                            |
|  VARIABLE  CONSTANT  VALUE  TO  @  !  +!  C@  C!  2@  2!       |
|  HERE  ALLOT  ,  C,  CREATE  DOES>  CELLS  CHARS               |
|  MOVE  FILL  ERASE  CELL+  CHAR+  ALIGN  ALIGNED               |
|                                                                |
|  DEFINING & COMPILATION                                        |
|  : ... ;  IMMEDIATE  [ ]  LITERAL  POSTPONE  STATE             |
|  '  [']  EXECUTE  FIND  >BODY                                  |
|                                                                |
|  NUMBER BASE                                                   |
|  BASE  DECIMAL  HEX                                            |
|                                                                |
|  INTROSPECTION                                                 |
|  WORDS  SEE  FORGET                                            |
|                                                                |
|  STRINGS & PARSING                                             |
|  S"  CHAR  [CHAR]  SOURCE  >IN  WORD  PARSE  PARSE-NAME        |
|  EVALUATE  QUIT                                                |
|                                                                |
|  ERROR HANDLING                                                |
|  ABORT  ABORT"                                                 |
|                                                                |
+================================================================+

Appendix B: Troubleshooting

Stack Underflow

Symptom: Error message when a word expects more values than are on the stack.

Solution: Use .S frequently to monitor stack contents. Check your stack comments ( before -- after ) to ensure operations have the values they need.

Wrong Values or Order

Symptom: Calculations produce incorrect results.

Solution: Walk through your code step by step with .S after each word. Remember that FORTH operations often consume values in a specific order--5 3 - means 5 - 3, not 3 - 5.

Return Stack Imbalance

Symptom: System crash or strange behavior after using >R and R>.

Solution: Every >R must have a matching R> before the word exits. If you use EXIT inside a DO loop, call UNLOOP first.

Definition Not Working

Symptom: A word you defined does not behave as expected.

Solution: Use SEE to examine what was actually compiled. Test each component word individually before combining them.

Division by Zero

Symptom: Error from /, MOD, or /MOD.

Solution: Validate divisors before dividing:

: SAFE/  ( n1 n2 -- n3 )
   DUP 0= ABORT" Division by zero!" / ;

Loop Doesn't Run

Symptom: DO loop body never executes.

Solution: Remember that DO runs while index < limit. For 10 10 DO, use ?DO instead to skip empty ranges.

Connection Issues

Problem Solution
Garbled characters Set terminal to VT100, 80 columns, 8N1
No response after connect Press ENTER; check baud rate matches
Session freezes Check flow control settings; try ESC
Disconnected unexpectedly Phone line noise; redial and continue

Appendix C: Glossary

Colon Definition -- A user-defined word created with : and terminated with ;.

Compilation Mode -- The state entered after : where words are compiled into the dictionary rather than executed.

Data Stack -- The primary stack for passing parameters between words.

Dictionary -- The collection of all defined words, both built-in and user-created.

Execution Token (XT) -- A value that identifies a word and can be used with EXECUTE.

Flag -- A boolean value on the stack; 0 represents false, -1 (all bits set) represents true.

Immediate Word -- A word that executes during compilation rather than being compiled.

Interpretation Mode -- The normal state where words are executed immediately as entered.

LIFO -- Last In, First Out. The stack discipline where the most recently added item is the first removed.

NOS -- Next on Stack. The second item from the top.

Return Stack -- Secondary stack used for return addresses and temporary storage.

RPN -- Reverse Polish Notation. The postfix notation where operators follow their operands.

Stack Effect -- The change a word makes to the stack, documented as ( before -- after ).

TOS -- Top of Stack. The most recently pushed item.

Word -- The FORTH term for a named operation, whether built-in or user-defined.

Appendix D: Word Standards Reference

This appendix shows which standard each word first appeared in. Words marked ANS were standardized in 1994; those marked F2012 are from the 2012 standard. Words marked Forth-83 were available in the 1983 standard.

Words from Forth-83 (1983)

These words have been standard since 1983 or earlier:

Stack: DUP, DROP, SWAP, OVER, ROT, 2DUP, 2DROP, 2SWAP, ?DUP, DEPTH, PICK, ROLL

Arithmetic: +, -, , /, MOD, /MOD, NEGATE, ABS, MIN, MAX, 1+, 1-, 2, 2/

Comparison: =, <, >, 0=, 0<, U<

Logic: AND, OR, XOR, INVERT (was NOT in Forth-83)

I/O: ., CR, EMIT, SPACE, SPACES, TYPE, COUNT

Memory: @, !, C@, C!, HERE, ALLOT, ,, C,, CELLS, CHARS

Definitions: :, ;, CONSTANT, VARIABLE, CREATE, DOES>

Control: IF, ELSE, THEN, BEGIN, UNTIL, WHILE, REPEAT, DO, LOOP, +LOOP, I, J, LEAVE

Return Stack: >R, R>, R@

Compilation: ', EXECUTE, IMMEDIATE, [, ], LITERAL, STATE

Other: WORD, BASE, DECIMAL, HEX

Words from ANS Forth (1994)

These words were standardized in ANS Forth 1994:

Stack: NIP, TUCK, 2OVER

Arithmetic: */, */MOD

Comparison: <>, 0<>, 0>, U>, WITHIN, TRUE, FALSE

Logic: LSHIFT, RSHIFT

I/O: U., .R, U.R, BL, .S, .", .(, ACCEPT

Memory: +!, 2@, 2!, CELL+, CHAR+, MOVE, FILL, ERASE, ALIGN, ALIGNED

Definitions: VALUE, TO

Control: ?DO, UNLOOP, AGAIN, EXIT, CASE, OF, ENDOF, ENDCASE

Return Stack: 2>R, 2R>, 2R@

Compilation: ['], POSTPONE, FIND, >BODY, CHAR, [CHAR]

Parsing: SOURCE, >IN, PARSE

Evaluation: EVALUATE, QUIT

Error: ABORT, ABORT"

Introspection: WORDS, SEE, FORGET

Words from Forth 2012

Parsing: PARSE-NAME

Notes on Historical Accuracy

SLP-FORTH implements a blend of Forth-83 and ANS Forth words, chosen for practical utility rather than strict historical accuracy. If you require a period-accurate 1983 experience, avoid using words marked ANS or F2012 above.

Key differences from a pure Forth-83 system:

  1. TRUE/FALSE values: Forth-83 used 1 for true; ANS Forth uses -1
  2. POSTPONE: Replaces Forth-83's [COMPILE] and COMPILE
  3. VALUE/TO: Did not exist until late 1980s
  4. CASE statements: Common vendor extension but not standard until ANS
  5. ?DO: ANS addition for skipping empty loops

See Also