Forth by Examples

Download as pdf or txt
Download as pdf or txt
You are on page 1of 20

FORTH by examples

Table des matières

FORTH by examples iv

Memento and examples v


Forth basics . . . . . . . . . . . . . . . . . . . . . . . . . . . v
Conditions and loops . . . . . . . . . . . . . . . . . . . . . . ix
Variables and arrays . . . . . . . . . . . . . . . . . . . . . . xi
New definitions . . . . . . . . . . . . . . . . . . . . . . . . . xiii
Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Non standard common practices . . . . . . . . . . . . . . . xv

Annexes xvi
Lessons & Links . . . . . . . . . . . . . . . . . . . . . . . . . xvi
Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Some FORTH implementations . . . . . . . . . . . . . . . . xvii
FORTH for microcontrollers . . . . . . . . . . . . . . . . . . xviii
Some more exotic FORTH implementations . . . . . . . . . xix
Practical uses . . . . . . . . . . . . . . . . . . . . . . . . . . xix

ii
TABLE DES MATIÈRES

Credits and informations . . . . . . . . . . . . . . . . . . . . xix


TODO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx

iii
FORTH by examples

FORTH by examples

There are already many books about the FORTH language.


This one is a simple memento which covers some core FORTH
WORDS with a few examples of how to use them in practice.
Most of them are ANS or from the 2012 STANDARD and should
work with GFORTH or PFORTH.

https://gitlab.com/garvalf/forth-is-fun

iv
Memento and examples

All examples will display the basic core words in capital letters.
Some FORTH might accept both commands in lower and upper
case letters, while some others might behave differently.

Forth basics
First of all:
\ is for a comment.

( n1 n2 – n3 ) is another comment, usually for printing the stack


effect (n3 is the result of n1 and n2 affected by the command)
: is for starting the definition (compilation) of a word, ; is for
ending it.
CR is for carriage return

: test_cr
CR CR CR
;

SPACE is for a single space

SPACE
SPACES ( n – ) is for n spaces

v
FORTH by examples

: test_spaces
10 SPACES
;

PAGE clears the screen and resets the cursor position to top left
corner
. is for displaying the top value on the stack (consuming it)

.S is for displaying the values on the stack (not consuming them)

." is for appening some text into the console (use a space after
it!). " The text output ends after the second double-quote
Arithmetics are in RPN (reverse polish notation), with integer
numbers.
You can use + , - , * and /
: test_arithmetics
8 5 + 3 - 2 / 3 * .
\ 15 ok
;

MOD ( n1 n2 – n3 ) Modulo of n1 by n2. The result n3 is the remain


of an euclidean division.
/MOD ( n1 n2 – n3 n4 ) Modulo of n1 by n2, with rest in u3 and
result in u4
: test_mods
150 84 MOD .S
\ 66
4 /MOD .S
\ 2 16 ok
;

Some operations on the stack (counting is from 0 in FORTH)

vi
FORTH BASICS

DUP ( x – x x ) Duplicates topmost value on stack. 2DUP ( x1 x2 –


x1 x2 x1 x2 ) Duplicates 2 topmost values on stack. ?DUP Duplicates
if not 0
DROP ( x – ) Drop topmost stack value. 2DROP ( x1 x2 – ) Drop 2
topmost stack values.
SWAP ( x y – y x ) Swaps topmost stack values. 2SWAP ( x1 y1 x2 y2
– x2 y2 x1 y1 ) Swaps topmost stack values, by 2 pairs.
NIP Drop the first item below the top of stack ( = SWAP DROP )
: test_2swap
11 22 33 44
2SWAP .S
\ 33 44 11 22 ok
;

OVER ( x y – x y x ) Pushes second value on stack. ROT ( x y z – y z


x ) Rotate values on stack.
ROLL ( n – ) Rotate n to the top.
: test_roll
11 22 33 44 55 2 ROLL .S
\ 11 22 44 55 33 ok
;

note: 2 ROLL is equivalent to ROT, 1 ROLL is equivalent to SWAP


and 0 ROLL is a null operation.
PICK ( n – ) copies the item at n position in the stack to the top
: test_pick
11 22 33 44 55 2 PICK .S
\ 11 22 33 44 55 33 ok
;

MIN and MAX select the minimum or maximum between 2 values


on the stack and put it back on stack

vii
FORTH by examples

: test_min_max
4 12 2DUP 2DUP
." between " . ." and " . CR
MIN . ." is the smallest and "
MAX . ." is the biggest"
\ between 12 and 4
\ 4 is the smallest and 12 is the biggest ok
;

NEGATE negates the value on the stack while ABS absolutes it

: test_negate_abs
5 -2 * ABS .S
\ 10
NEGATE .
\ -10 ok
;

DEPTH displays the number of elements in the stack

WORDS lists all the known words in the dictionnary

FORGET ( w – ) (obsolete) removes custom words from word ’w’

EMIT ( n – ) displays a character by its ascii code

: test_emit
68 EMIT
\ D ok
;

." displays a string

: test_string
." Hello World "
;

SEE inspects the code of a word

viii
CONDITIONS AND LOOPS

: test_see
see test_emit
\ : test_emit #68
\ emit ; ok
;

Conditions and loops


IF and THEN are for conditions.

< , > , = and <> are for comparisons.

: test_if ( n -- )
12 < IF ." This number was lower than 12" THEN
CR ." This part will always be displayed."
;

: test_if_else ( n -- )
12 < IF
." This number was lower than 12."
ELSE
." This number was higher than 12 or equal to it."
THEN
CR ." This part will always be displayed."
;

CASE OF and ENDCASE

DO and LOOP are for definite loops. I is the index of the current
loop and J is the second index in the case of two imbricated loops.
There is also K as a third index.
: test_loop_definite ( -- ) \ loop from 1 to 12

ix
FORTH by examples

13 1 DO ." looping " I . LOOP CR ." End of the loop"


;

+LOOP and -LOOP are for changing the step

: test_+loop_definite
130 1 DO ." looping " I . 8 +LOOP CR ." End of the
loop"
;

LEAVE can exit a DO LOOP before reaching the end

: test_loop_leave
." TODO "
;

BEGIN and UNTIL are for indefinite loops.

: test_indefinite_loop ( -- ) \ loop from 1 to 12


0 BEGIN 1 + DUP DUP ." looping " . 12 = UNTIL
CR ." End of the loop"
;

BEGIN and AGAIN are for endless loops. They can be exited with
EXIT though (or ctrl+c)

: test_loop_again
0 BEGIN 1 + DUP .
DUP 500000 = IF DROP EXIT THEN
AGAIN
;

BEGIN WHILE REPEAT : the loop repeats while something is true

: test_loop_while ( displays ascii characters )


31 BEGIN 1 + DUP 129 < WHILE DUP . ." = " DUP EMIT CR
REPEAT

x
VARIABLES AND ARRAYS

[IF] , [ELSE] and [THEN] are for conditional definitions

Variables and arrays


VARIABLE reserves space for a value, uninitialised, and the created
word puts the address of the variable on the stack.
! stores a value in a variable, while @ will fetch it to the stack and
? will display it.

VARIABLE Apples
: test_variables
5 Apples !
Apples @ .
\ 5 ok
Apples @ 1 + Apples !
Apples~?
\ 6 ok
;

+! ( n addr – ) Adds n to the number at address


: test_plusstore
test_variables
5 Apples +!
Apples~?
\ 11 ok
;

VALUE like a variable VALUE takes an initial value, and the created
word puts the value directly on the stack like CONSTANT. The value
can still be changed using TO. Word definitions in many Forths using
VALUE’s will be smaller, because they just need to reference the
created word and not !.

xi
FORTH by examples

VARIABLE is useful when you want to take the address of the


variable, and VALUE is useful when you don’t need to.
5 VALUE Pears
: test_value
Pears 1 + TO Pears
Pears .
\ 6 ok
Pears 2 - TO Pears
Pears .
\ 4 ok
;

a CONSTANT behaves like a VALUE, but it shouldn’t be redefined once


its content has been fixed (it can be in some FORTH implementations,
but it’s not standard)
5 CONSTANT Cherries
: test_constant
Cherries .
\ 5 ok
;

CREATE can create a single variable but also a whole array

CREATE MyArray 100 , 150 , 200 , 250 ,


: test_create
MyArray 2 CELLS + @ . CR \ fetch 3rd value
\ 200 ok
50 MyArray 0 CELLS + ! \ store 50 in 1st cell
4 0 DO MyArray i CELLS + @ . LOOP \ list all cells
;

xii
NEW DEFINITIONS

: MyCharacter CREATE CR DUP DUP , ." storing " . ." as


" EMIT CR
DOES> @ DUP . ." in ascii is " EMIT
;

67 MyCharacter myC storing 67 as C ok


MOVE ( addr1 addr2 n – ) copies the n elements of addr1 into addr2

VARIABLE Peaches
: test_move
0 Peaches !
test_plusstore
CR ." There are " Peaches~? ." peaches"
CR ." but now we move..."
Apples Peaches 1 MOVE
CR ." There are " Apples~? ." apples"
CR ." There are " Peaches~? ." peaches"
;

FILL ( addr n char – ) stores char in n characters of memory. ERASE


( addr n ) fills n characters of memory with zero

New definitions
: test_define_does>
myC
\ mya 67 in ascii is C ok
;

IMMEDIATE Marks the most recently defined word as one which,


when encountered during compilation, will be executed rather than
being compiled.

xiii
FORTH by examples

POSTPONE can create an alias for a word see


https://www.forth.com/starting-forth/11-forth-compiler-defining-
words/
test_postpone
: si \ creates "si" (‘‘if‘‘ in French) to be used
instead of ‘‘if‘‘
POSTPONE IF
;
IMMEDIATE

SYNONYM can also create an alias for a word, it’s a standard but not
always implemented
SYNONYM ensuite THEN not included by default
should behave the same as:
: ensuite POSTPONE THEN ; IMMEDIATE
DEFER creates a placeholder for a word name which will be defined
later. IS will define such a word whose definition will start with
:NONAME instead of :

DEFER test_defer
Some more definitions can be set here. You can reference
test_defer now
: test_defer_bis
." Here is the result of the addition of 3 + 3: "
test_defer
;

:NONAME
CR
3 3 + . CR
." It was the defered definition"

xiv
STRINGS

;
IS test_defer

BYE Exits the interpreter

Strings
PAD is an address used to store temporary data ACCEPT ( addr n1 –
n2) receives a string of n1 characters )
variable myVar variable myVarLen
: testInput
." type a number (4 characters max):"
PAD 4 ACCEPT myVarLen !
PAD myVarLen @ s>number? drop drop myVar !
." You have typed: " myVar @ .
;

Tools
DUMP ( addr n1 – ) displays the n1 lines of content from an adress

Non standard common practices


Local variables (gforth, ueforth)

xv
FORTH by examples

Annexes

Lessons & Links


• "Starting FORTH", an essential beginner guide by Leo Brodie
◦ https://www.forth.com/starting-forth/
• Learn forth in 15 minutes ("Learn X in Y minutes")
◦ https://learnxinyminutes.com/docs/forth/
• Lessons about gforth in French
◦ https://www.jchr.be/linux/gforth.htm
• Other lessons in French:
◦ https://lecrapouille.github.io/forth-fr.html
◦ https://eforth.arduino-forth.com/
• Some older books: "The complete forth" by Alan Winfield is pretty
interesting.
◦ https://jupiter-ace.co.uk/index_forth_books.html
• Some other ressources:
◦ http://www.murphywong.net/hello/simple.htm
◦ https://pfe.sourceforge.net/4thtutor/
◦ https://skilldrick.github.io/easyforth/
◦ https://wiki.gentoo.org/wiki/Forth
◦ https://www.code4th.com/
◦ https://www.forth.org/tutorials.html

xvi
STANDARDS

◦ And so Forth by Hans Bezemer (pdf):


· https://ficl.sourceforge.net/pdf/Forth_Primer.pdf

Standards
• Forth 79 standard
◦ https://www.complang.tuwien.ac.at/forth/fth79std/FORTH-
79.TXT
• Forth 83 standard
◦ https://www.complang.tuwien.ac.at/forth/fth83std/FORTH83.TXT
• Forth 94 ANS standard
◦ http://www.forth.org/svfig/Win32Forth/DPANS94.txt
• Forth 2012 standard
◦ http://forth200x.org/documents/forth-2012.pdf
• Forth 200x Standard liste core bib
◦ https://forth-standard.org/standard/core
• UF Forth glossary
◦ https://gitlab.com/b2495/uf/-/blob/master/GLOSSARY
https://gforth.org/manual/Word-Index.html gforth index

Some FORTH implementations


• https://gforth.org/
• http://www.softsynth.com/pforth/
• https://eforth.appspot.com/linux.html
• A list of many ANS systems:
◦ https://forth-standard.org/systems

xvii
FORTH by examples

• For Atari / ST:


◦ http://gtello.free.fr/forth_e.htm
◦ https://github.com/forth-ev/VolksForth/tree/master/AtariST
◦ https://atariwiki.org/wiki/Wiki.jsp?page=Forth
• For Amiga:
◦ http://www.jforth.org/
• For ZX Spectrum:
◦ https://github.com/programandala-net/solo-forth
◦ https://github.com/Veltas/zenv
• For ZX Spectrum Next:
◦ https://github.com/mattsteeldue/vforth-next
◦ https://github.com/robzed/vforth-next/wiki/05.How-to-
install-vForth-Next-on-ZEsarUX-for-the-Spectrum-Next

FORTH for microcontrollers


• Arduino:
◦ https://flashforth.com/
• Raspberry Pico and ARM:
◦ https://github.com/tabemann/zeptoforth/
◦ https://mecrisp-stellaris-folkdoc.sourceforge.io/
• ESP32:
◦ https://esp32forth.appspot.com/ESP32forth.html
◦ https://esp32.arduino-forth.com/
• Scamp:
◦ https://udamonic.com/getting-started.html
• MyNor & ForthDeck:
◦ http://mynor.org/my4th_forthdeck.htm

xviii
SOME MORE EXOTIC FORTH IMPLEMENTATIONS

Some more exotic FORTH implementations


• SmithForth: https://dacvs.neocities.org/SF/
• FORTHOS: https://sources.vsta.org/forthos/
• DuskOS: http://duskos.org/
• WAForth: https://github.com/remko/waforth

Practical uses
• GameBoy development kits: https://gbforth.org/
https://github.com/Reinboar/pixelforth
• Gforth sdl 2 binding : https://github.com/JeremiahCheatham/Gforth-
SDL2-Bindings/

Credits and informations


This book is written in FORTH source code and exported to the
markdown and txt2tags markup.
The source has been processed by textallion
https://textallion.sourceforge.io/ so it can be displayed on the
https://gitlab.com/garvalf/forth-is-fun website.
It is released:

• in FORTH source code (forth_by_examples.fth)


• in markdown export (forth_by_examples.md)
• in pdf export (forth_by_examples.pdf)
• in epub export (forth_by_examples.epub)
• in html export (forth_by_examples.html)

xix
FORTH by examples

TODO
Words to add in the examples:
RECURSE IMMEDIATE R> >R R@ ] [ LITERAL AND OR 0< 0=
0> 1+ 1- 2+ 2- 2/ 2* +! KEY ’ EXECUTE CELL CREATE QUIT CHAR
[CHAR]

xx

You might also like