Forth Introduction

Who uses Forth?

• NASA -> Spacecraft flight system controllers, ground support systems, and more
• Sun, Apple, IBM -> Open Firmware or OpenBoot. Standard defining the interfaces of a computer firmaware system
• FedEx -> SuperTracker and Enhanced SuperTracker
• University of Minnesota -> Mount Lemmon Observatory, PC-based system for telescope control, data acquisition and graphics display.
• Eastman Kodak Company -> Quality control system monitoring photographic film density.

Basic Concepts

We end commands with a semicolon...and spaces are a must...

```
( --This is a comment ) ;
```

```
1 2 3 4 5
```

```
. . . . .
```
```
5 4 3 2 1
```

Basic Arithmetics

In Forth...we use the Polish Reversed Notation...

```5 4 + .
9
```

```5 4 + 2 - .
7
```

Stack Manipulation

Working with the stack it's not easy...that's why we have some nice and useful functions...

```5 DUP * . ( --duplicates the top of the stack )
25
```

```3 8 SWAP - . ( --swaps the top with the second item )
5
```
```1 2 3 ROT . . . ( --rotates the top 2 elements )
1 3 2
```

```3 5 DROP 2 + . ( --removes the top item )
5
```

```1 2 3 NIP .s ( --removes the second item )
1 3
```

```1 2 3 TUCK .s ( --duplicates the top item into the
--second slot )
1 3 2 3
```

```1 2 3 OVER .s ( --duplicates the second item into the
--top slot )
1 2 3 2
```

Seeing double

This operations handle the stack in pairs..

```1 2 3 2DUP
1 2 3 2 3
```

```1 2 3 4 2SWAP
3 4 1 2
```
```1 2 3 2OVER
1 2 3 2 1
```

```1 2 3 4 2DROP
1 2
```

Variables

While not used very often, variables can come handy sometimes...

```CREATE MyVariable ( --Define the variable )
37 MyVariable ! ( --Assign value )
MyVariable @ ( --Fetch value )
37
MyVariable @ 10 + MyVariable ! (--Add 10 to MyVariable)
MyVariable @
37 47
```

Arrays

Same as variables...

```CREATE MyArray 100 , 200 , 300 ,
0 CELLS MyArray + @
0 100
2 CELLS MyArray + @
0 100 300
```

Creating Words

Forth is very expressive...we can express everything using words...

```: EXPO DUP * ;
5 EXPO
25
```

We can call words inside words...

```: EXPO DUP * ;
: DOUBLE 2 * ;
: DOUBLE_EXPO EXPO DOUBLE ;
5 DOUBLE_EXPO
50
```

Conditionals

The only conditional that we have is IF...and CASE...

```25
20 > IF ." Too Big!" ELSE ." Too Small!" THEN
Too Big!
```
```2
: MAYBE
CASE 1 OF ." Num 1" ENDOF
2 OF ." Num 2" ENDOF
3 OF ." Num 3" ENDOF
ENDCASE ;
Num 2
```

Loops

Loops will repeat a command...

```: MyLoop 0 do ." Forth" cr loop ;
4 MyLoop
Forth
Forth
Forth
Forth
```

While

Yep...we can use While as well...

```: MyWhile 1 begin dup 5 < while 1 + ." Forth"
cr repeat drop ;
MyWhile
Forth
Forth
Forth
Forth
```

Reversing the stack

Now that we have the basics...and to be honest...there's not much commands to learn...a least not so much...let's make an app...

```: 4SWAP SWAP 2SWAP SWAP . . . . ;
```

Fibonacci List

```: FIBO
1 SWAP
0 DUP .
?DO
DUP . OVER OVER + ROT DROP
LOOP
DROP DEPTH
DEPTH 2 = IF 2DROP 0 THEN ;
```

Making an LED Number App

This one really took me a while...

```VARIABLE picky

: COLLECT_PICKY DUP 1- picky ! ;

: NPICK COLLECT_PICKY 2 * 0 ?DO picky @ PICK LOOP ;

: SPLIT BEGIN DUP WHILE 10 /MOD REPEAT DROP DEPTH ;
```
```: First_Line
CASE
0 OF SPACE ." _  " ENDOF 1 OF SPACE SPACE ENDOF
2 OF SPACE ." _  " ENDOF 3 OF ." _  " ENDOF
4 OF SPACE SPACE SPACE SPACE ENDOF
5 OF SPACE ." _  " ENDOF
6 OF SPACE ." _  "ENDOF 7 OF ." _   "  ENDOF
8 OF SPACE ." _  " ENDOF 9 OF SPACE ." _  " ENDOF
ENDCASE ;
```
```: Second_Line
CASE
0 OF ." | | " ENDOF 1 OF ." | " ENDOF
2 OF SPACE ." _| " ENDOF 3 OF ." _| " ENDOF
4 OF ." |_| " ENDOF 5 OF ." |_  " ENDOF
6 OF ." |_  "ENDOF 7 OF SPACE ." |  "  ENDOF
8 OF ." |_| " ENDOF 9 OF ." |_| " ENDOF
ENDCASE ;
```
```: Third_Line
CASE
0 OF ." |_| " ENDOF 1 OF ." | " ENDOF
2 OF ." |_  " ENDOF 3 OF ." _| " ENDOF
4 OF SPACE SPACE ." | " ENDOF
5 OF SPACE ." _| " ENDOF
6 OF ." |_| "ENDOF 7 OF SPACE ." |  "  ENDOF
8 OF ." |_| " ENDOF 9 OF SPACE ." _| " ENDOF
ENDCASE ;
```
```: LED
SPLIT
NPICK
DEPTH 3 / 0 ?DO First_Line LOOP CR
DEPTH 2 / 0 ?DO Second_Line LOOP CR
DEPTH 0 ?DO Third_Line LOOP ;
```

Decimal to Romans

This will include variables and arrays...

```CREATE ROMANS ASCII M , ASCII CM , ASCII D , ASCII CD ,
ASCII C , ASCII XC , ASCII L , ASCII XL ,
ASCII X , ASCII IX , ASCII V , ASCII IV ,
ASCII I ,

CREATE NUMBERS 1000 , 900 , 500 , 400 , 100 ,  90 ,
50 ,  40 ,  10 ,   9 ,   5 ,   4 ,
1 ,

VARIABLE COUNTER

0 COUNTER !
```
```: INCREASE
COUNTER @ 1 + COUNTER ! ;

: SHOW_ROMANS
DUP COUNTER @ CELLS NUMBERS + @ >= IF
COUNTER @ CELLS NUMBERS + @ -
COUNTER @ CELLS ROMANS + @ EMIT
COUNTER @
CASE 1 OF ." M" ENDOF 3 OF ." D" ENDOF
5 OF ." C" ENDOF 7 OF ." L" ENDOF
9 OF ." X" ENDOF 11 OF ." V" ENDOF
ENDCASE
```
```                RECURSE ELSE
DUP 0 > IF
INCREASE RECURSE ELSE
0 COUNTER ! DROP THEN THEN ;
```