Transcript Forth

Forth
A stack language
Free implementations

For our purposes, pforth seems to be best



http://www.softsynth.com/pforth/
Another alternative is SwiftForth
http://www.forth.com/swiftforth/dl.html
Both are ANS compliant
2
Forth syntax



A word consists of a sequence of printable (nonwhitespace) characters
A program consists of a sequence of words, separated
by whitespace
Any questions?
3
Basic execution


Forth uses a dictionary to hold function definitions, and
a stack to hold data
Words are evaluated left to right, top to bottom, in the
usual order

Forth is case insensitive


Most documentation uses words in all caps, but lowercase is also ok
If a word is in the dictionary,


then the function is looked up and executed
else Forth converts the word to a number, if it can, and
places it on the stack
4
Defining and calling functions

A function is defined with
: functionName ( old -- new , words ) body ;





For example, addition might be documented as
( n1 n2 -- n3 , adds top two items )
A function is called by mentioning its name



The function expects to find its parameters on the stack
The function places its return values on the stack
The ( old -- new , words ) tells how the stack is changed
Parameters, if any, are taken from the stack
Return values, if any, are placed on the stack
Example:


: add3 ( n1 n2 n3 -- n4 , add 3 items) + + ;
1 2 3 4 5 add3 .s
1 2 12 <-Top ok
ok
5
Displaying the stack

. ( N -- , print number on top of stack )



Removes (“pops”) the top number from the stack and prints it
2 2 + . 4 ok
.s ( -- , print the entire stack )





This does not modify the stack contents
1 2 3 4 5 .s
1 2 3 4 5 <-Top ok
+ . 9 ok
.s
1 2 3 <-Top ok
The top of the stack is on the right


The above examples are from SwiftForth, which prints <- Top
Most other Forth implementations just take this for granted
6
Manipulating the stack

0sp ( clears the stack ) (pforth only)


dup ( n -- n n , duplicate top of stack )


ok
1 2 3 4 5 swap .s
1 2 3 5 4 <-Top ok
over ( a b -- a b a , copy second item on stack )


1 2 3 4 5 dup .s
1 2 3 4 5 5 <-Top
swap ( a b -- b a , swap top two items on stack )


0sp 0sp ?
.s
<-Top ok
1 2 3 4 5 over .s
1 2 3 4 5 4 <-Top
ok
pick ( ... v3 v2 v1 v0 N -- ... v3 v2 v1 v0 vN )

Makes a copy of the Nth stack item; 0 PICK is equivalent to DUP
7
More stack manipulations










DROP ( a -- , remove top item from the stack )
ROT ( a b c -- b c a , ROTate third item to top )
?DUP ( n -- n n | 0 , duplicate only if non-zero, '|'
means OR )
-ROT ( a b c -- c a b , rotate top to third position )
2SWAP ( a b c d -- c d a b , swap pairs )
2OVER ( a b c d -- a b c d a b , leapfrog pair )
2DUP ( a b -- a b a b , duplicate pair )
2DROP ( a b -- , remove pair )
NIP ( a b -- b , remove second item from stack )
TUCK ( a b -- b a b , copy top item to third position )
8
Arithmetic



Arithmetic is integer
+ - * / mod are add, subtract, multiply, integer divide,
modulus, all ( n1 n2 -- n3 )
Some “shorthand” operators are 1+ 1- 2+ 2- 2* 2/









10 2/ . 5
ok
/MOD ( n1 n2 -- rem quot , remainder and quotient of n1/n2 )
MIN ( n1 n2 -- n3 , minimum of n1 and n2 )
MAX ( n1 n2 -- n3 , maximum of n1 and n2 )
ABS ( n -- abs(n) , absolute value of n )
NEGATE ( n -- -n , negate value, faster then -1 * )
LSHIFT ( n c -- n<<c , left shift of n )
RSHIFT ( n c -- n>>c , logical right shift of n )
ARSHIFT ( n c -- n>>c ) , arithmetic right shift of n )
9
Output

EMIT ( n -- , display character with ASCII value n )


CHAR ( <char> -- char , get ASCII value of a character )
 Unusual: Uses the following text, not the stack!


111 108 dup 101 72 emit emit emit emit emit Hello ok
char A . 65 ok
." ( -- , print string up to next " )

." Hello from pforth!" Hello from pforth!
ok
Works in SwiftForth when in a function, but not by itself in REPL (?)
SPACE ( -- , output a space )
SPACES ( n -- , output n spaces )
CR ( -- , start new line , carriage return )




10
Strings

." will output a string, up to a "


ok
S" will put a string on the stack



." hello" hello
Stack<10>
Format: Character count on top, machine address below that
s" Hello from Forth!"
ok
Stack<10> 140255546192593 17
TYPE will remove a print a string from the stack

type Hello from Forth!
Stack<10>
ok
11
Strings, character by character


Given the machine address of a string, C@ will return the first
character
CHAR+ will advance to the next character





s" ABCDE"
ok
Stack<10> 140354489823953 5
drop dup
ok
Stack<10> 140354489823953 140354489823953
c@ emit A
ok
Stack<10> 140354489823953
char+ dup c@ emit B
ok
Stack<10> 140354489823954
char+ char+ char+ dup c@ emit E
ok
Stack<10> 140354489823957
12
Input

KEY ( -- char , input character )


: testkey ( -- ) ." Hit a key: " key cr ."
That was " . cr ; ok
testkey Hit a key: A
That was 65
13
Loading from a file

In file sample.fth, in same directory as sf:


\ Sample Forth Code
\ Author: Phil Burk
ANEW \ forget what was loaded before
: SQUARE ( n -- n*n , square number )
DUP *
;
: TEST.SQUARE ( -- )
CR ." 7 squared = "
7 SQUARE . CR
;
In SwiftForth:



include sample.fth ok
test.square
7 squared = 49
ok
Very similar in pforth
forget square – forgets everything from square on down (pforth only)
14
More about loading

FORGET definition is supposed to forget the named
definition and everything that follows



This works in pforth, but I don’t think it does in SwiftForth
ANEW should forget what was loaded before
INCLUDE? filename will only load code if it isn’t
already in the dictionary
15
Constants and variables

Constants can be defined as value CONSTANT name



42 constant theAnswer
theAnswer . 42 ok
ok
Variables can be defined with VARIABLE name




VARIABLE ( <name> -- , define a 4 byte memory storage
location )
@ ( address -- value , FETCH value FROM address in
memory )
! ( value address -- , STORE value TO address in
memory )
variable ans ok
42 ans ! ok
ans ? 42 ok
ans @ . 42
16
Logic


true and false are constants -1 and 0
Comparisons are < <= = >= >


2
2
2
2
3
3
3
3

0> 0<
< . -1 ok
> . 0 ok
<= . -1 ok
>= . 0 ok
Logical operators are and

0=
true -1 and . -1 ok
true true and not . 0
or
not
ok
17
IF-ELSE-THEN statements

Forth has an “if” statement






: showIf ( flag -- , print logical value )
if ." true" else ." false" then ; ok
true showIf true ok
false showIf false ok
55 showIf true ok
The “else” part is optional
It helps to think of then as “end if
18
BEGIN … END Loops

BEGIN … END will loop until a given condition is
true


5 begin 1- dup . dup not until 4 3 2 1 0
Stack<10> 0
0 begin dup . 1+ dup 3 = until 0 1 2
ok
Stack<10> 3
ok
19
DO … LOOP Loop

end start DO … LOOP will loop a fixed number of times

5 1 do ." hi! " loop hi! hi! hi! hi!
Stack<10>
ok

You can access the loop counter with I


5 1 do ." hi#" i 48 + emit loop hi#1 hi#2 hi#3 hi#4
ok
Stack<10>
70 65 do i . i emit space loop 65 A 66 B 67 C 68 D 69 E
ok

You can leave the loop with LEAVE

50 1 do ." hi " i 5 > if leave then loop hi hi hi hi hi hi ok
Stack<10>
20
BEGIN … WHILE … REPEAT Loop

BEGIN test WHILE body REPEAT acts like a while loop
in more traditional languages

2 begin dup 1000 < while dup . 2* repeat
2 4 8 16 32 64 128 256 512
ok
Stack<10> 1024
21
“Case” statements

On file sample.fth:


: day-of-week ( n -- str , return day of week, Sunday = 1 )
case
1 of s" Sunday" endof
2 of s" Monday" endof
3 of s" Tuesday" endof
4 of s" Wednesday" endof
5 of s" Thursday" endof
6 of s" Friday" endof
7 of s" Saturday" endof
endcase ;
include sample.fth
Include sample.fth
include added 768 bytes,39236 left.
ok
Stack<10>
4 day-of-week type Wednesday
ok
Stack<10>
22
References
Most of this lecture based on (or shamelessly stolen from)
the excellent Forth Tutorial by Phil Burk:
http://www.softsynth.com/pforth/pf_tut.php
23
The End
The first time I combined the ideas I had been developing
into a single entity, I was working on an IBM 1130, a “thirdgeneration” computer. The result seemed so powerful that I
considered it a “fourth generation computer language.” I
would have called it Fourth, except that the 1130 permitted
only five-character identifiers. So Fourth became Forth, a
nicer play on words anyway.
--Charles “Chuck” Moore
24