Forth
Table of Contents
- 1. Forth
- 2. Forth: some conventions
- 3. Forth: Cheatsheet
- 4. Forth examples
- 5. TODO Forth
- 6. Forth Resources
- 6.1. Moving forth
- 6.1.1. TODO Moving Forth Part 1: Design Decisions in the Forth Kernel
- 6.1.2. TODO Moving Forth Part 2: Benchmarks and Case Studies of Forth Kernels
- 6.1.3. TODO Moving Forth Part 3: Demystifying DOES>
- 6.1.4. TODO Moving Forth Part 4: Assemble or Metacompile?
- 6.1.5. TODO Moving Forth Part 5: The Z80 Primitives
- 6.1.6. TODO Moving Forth Part 6: The Z80 High-level Kernel
- 6.1.7. TODO Moving Forth Part 7: CamelForth for the 8051
- 6.1.8. TODO Moving Forth Part 8: CamelForth for the 6809
- 6.1.9. Multitasking 8051 CamelForth (PDF)
- 6.1. Moving forth
- 7. Backlinks
1. Forth
1.1. Forth: notes for newbies
- a forth has two stacks: the parameter stack and the return stack
- avoid using
thenuseexitinstead .",s",(,\must all have a space that follows it- a lot of words works differently at compile time v.s. run time. like
.s,if,loop. For example, loops and branches cannot be used outside of column defintions (: ... ;)
1.2. Forth: miscellaneous
- the notation
( ... -- ... )are called stack effects or stack comments or stack notations or stack annotations… - gforth uses
.fsas file extension. Elsewhere, I've also seen.fthor just.f. Wikipedia also mentions.forthand.4th. - gforth's official release is very old compared to the latest version, all linux distributions I've used (not that many) packages a "very" old version of gforth. The one on Android's app store is fine though.
- Words usualy have the destination on the TOS ( source destination – )
- the parsing is extremely simple:
- skip whitespaces
- read until next whitespace
- lookup the token in the dictionary
- if not found: try to interpret as number
- if not a number: 💀
2. Forth: some conventions
2.1. abbreviations
tosstands for "Top Of Stack", it refers to the "first" element on the stack (usually the parameter stack)nosstands for "Next Of Stack", it refers to the "second" element on the stacksosstands for "Second On Stack", it means the same thing asnosxtexecution token, that's analoguous to a function pointer in C or a symbol in lisp
2.2. naming conventions
These are not strict, this is forth, you do you. But it might still be useful for reading other people's code.
@- at the start of a word: save a value
- e.g.
@foocould save the ToS into the variablefoo
- e.g.
- at the end of a word: fetch a value
- e.g.
r@copies a value from the return stack into the parameter stack - e.g.
c@fetches a character at c-addr
- e.g.
- at the start of a word: save a value
!- at the start of a word: initialise or reset a value (but I much
prefer
0name) - at the end of a word: stores into
- e.g.
c!store a character at c-addr
- e.g.
- at the start of a word: initialise or reset a value (but I much
prefer
cfor characters>and<for "into"/"from"0namefor initialisation or re-initialisation:namefor defining wordsname:,;name: often used for DSLs- slight variants to a word is sometimes denoted by adding a single
quote at the end
- e.g.
allocate'could denote a variant of allocate that initialise the allocated memory with 0s
- e.g.
- surrounding a word with square brackets (
[...]) usually means that it is executed at compile-time- a.k.a. "immediate words"
- a word that ends with
,means that it puts somethings in the dictionary.- or in the case of an assembler, into the target
- an array is usually named using the pluralized name of its elements,
like
names,people,filenames - you can define a word to get the current number of elements in a
collection (an array), the convention is to prepend a
#to the pluralized name of the elements#names,#people,#filenames- "number of …"
- the current element number is denoted by appending a
#to the name (not pluralized)- e.g.
name#,person#,#filename - "… number", or "… id"
- e.g.
- advance to the next element
- e.g.
+name,+person,+filename - increments the variable
name#(e.g.name#)
- e.g.
2.3. Stack comment conventions
afor addressc-addrcharacter-aligned addressa-addr"address unit"-aligned address (pointer)
3. Forth: Cheatsheet
3.1. Basics
: word ... ;: word ... ; immediate- =/ line comment =
( block comment )
3.2. stack manipulation words
| Word | Stack Effect | Note |
|---|---|---|
drop |
( a – ) | remove the TOS |
nip |
( a b – b ) | remove the NOS |
dup |
( a – a a ) | copies the TOS |
swap |
( a b – b a ) | exchange the TOS with the NOS |
tuck |
( a b – b a b ) | copies the TOS below the NOS |
over |
( a b – a b a ) | copies the NOS |
rot |
( a b c – b c a ) | move the third stack item to the top |
-rot |
( a b c – c a b ) | move the TOS under the third stack item – equivalent to rot rot |
roll |
is often a code smell | |
pick |
is often a code smell |
many of those have variants prefixed with 2, which work on pairs of
cells instead of just one cell. for example:
2swap ( a b c d -- c d a b )
3.3. Return stack
>r,r>2>r,2r>r@,2r@n>r,nr>
3.4. Input/Output
| Word | Stack Effect | Note |
|---|---|---|
. |
( a – ) | print the TOS and drop it |
emit |
( x – ) | display the character |
type |
( c-addr u – ) | display a string |
cr |
( – ) | display a new line (*C*arriage *R*eturn) |
bl |
( – char ) | puts the character value for space on the stack |
space |
( – ) | display one space |
spaces |
( n – ) | display n spaces |
[char] c |
( "<spaces>name" – ) | e.g. [char] a would put the value 97 on the stack |
." |
( "ccc<quote>" – ) | display a constant string |
s" |
( – c-addr u ) | returns an address to a constant string |
3.5. Memory access
| Word | Stack Effect | Note |
|---|---|---|
! |
( w a-addr – ) | Pronounced "store" |
@ |
( a-addr – w ) | Pronounced "fetch" |
? |
( a-addr – ) | : ? @ . ; |
3.6. Data space (Dictionary)
| Word | Stack Effect | Note |
|---|---|---|
here |
( – addr ) | |
allot |
( n – ) | Increments HERE |
forget |
( "<spaces>name" – ) | Decrements HERE 😅 |
, |
( x – ) | stores a cell in the dictionary and increments HERE by 1 cells |
variable |
( "<spaces>name" – ) | creates a word name which puts the address of the cell on the stack |
2variable |
( "<spaces>name" – ) | reserves 2 cells instead of 1 |
constant |
( "<spaces>name" – ) | almost the same as variable |
3.7. Dynamic memory management
| Word | Stack Effect | Note |
|---|---|---|
allocate |
( u – a-addr ior ) | analog to malloc |
free |
( a-addr – ior ) | |
resize |
( a-addr1 u – a-addr2 ior ) |
3.8. GForth specifics
| Word | Stack Effect | Note |
|---|---|---|
throw |
( u – a-addr ior ) | a must for check the ior return value of syscalls and libc calls (e.g. allocate, open-pipe) |
3.8.1. Turnkey applications a.k.a. how to build an executable
/ hello.fs : greet ( -- ) ." hi!" ; :noname Defers 'cold greet bye ; IS 'cold
gforthmi --application hello hello.fs ./hello
See:
3.9. Some identities
0= |
invert |
-rot |
rot rot |
>r r@ r> |
dup |
2@ |
dup cell+ @ swap @ |
3.9.1. Bunch of things that does nothing
Those are useful for learning, for detecting issues or simply for factoring out (they might occur when factoring something else, then you can easily factor it even more).
swap swap, and any even numbers of =swap=sdup drop,dup nip
4. Forth examples
ANEW ~= if already define forget it
5. TODO Forth
- if and loops
- see
- locate
- parse v.s. word
- counted strings, cell-counted strings
- chars, cells, char+, cell+
- find
compile,- enter, next
- quit
- literal, postpone
- immediate words, code words, definig words, parsing words, etc.
- interpretation v.s. execution v.s compilation semantics
- input buffer,
>in - control stack
- the pictured numeric output string buffer
#> PAD- base, hex, etc.
- evaluate
5.1. TODO meta compilation
5.2. TODO writing an assembler
- e.g. use a buffer to store the result
- "target words"
5.3. TODO bits about the philosophy
in short: YAGNI
5.4. TODO Forth from the perspective of a lisper??
e.g. how to funcall a word?
execute
5.5. TODO The interpreters
- inner (
next?) v.s. outer
5.6. TODO The threading models
See "moving forth"
5.7. TODO Example of data structures
5.7.1. TODO cons list
ofc
6. Forth Resources
- Starting forth
- Thinking forth by Leo Brodie (PDF)
- Publications by Bradford J. Rodriguez
- forth-standard.org' Search page
- GForth's manual
- PSA: the examples are not always very idiomatic
- A discord server about Forth
- Another discord server about Forth
6.1. Moving forth
Moving Forth: a series on writing Forth kernels
6.1.1. TODO Moving Forth Part 1: Design Decisions in the Forth Kernel
Outline
- choose the cpu
- threading techniques
- itc
- dtc
- jump to
nextin each code words v.s. inlinenext - stc
- ttc
- segment threaded code
- register allocation
- classical forth registers
- hardware stack
- ToS in register
6.1.3. TODO Moving Forth Part 3: Demystifying DOES>
6.1.4. TODO Moving Forth Part 4: Assemble or Metacompile?
6.1.5. TODO Moving Forth Part 5: The Z80 Primitives
6.1.6. TODO Moving Forth Part 6: The Z80 High-level Kernel
6.1.7. TODO Moving Forth Part 7: CamelForth for the 8051
6.1.8. TODO Moving Forth Part 8: CamelForth for the 6809
6.1.9. Multitasking 8051 CamelForth (PDF)
7. Backlinks
- Related notes (cheatsheet.org)