97 lines
3.8 KiB
Markdown
97 lines
3.8 KiB
Markdown
# Forth
|
|
|
|
Forth is a based [minimalist](minimalism.md) stack-based untyped programming language with [postfix](notation.md) (reverse Polish) notation.
|
|
|
|
{ It's kinda like usable [brainfuck](brainfuck.md). ~drummyfish }
|
|
|
|
It is usually presented as [interpreted](interpreter.md) language but may as well be [compiled](compiler.md), in fact it maps pretty nicely to [assembly](assembly.md).
|
|
|
|
There are several Forth standard, most notably ANSI Forth from 1994.
|
|
|
|
A free interpreter is e.g. GNU Forth ([gforth](gforth.md)).
|
|
|
|
## Language
|
|
|
|
The language is case-insensitive.
|
|
|
|
The language operates on an evaluation **stack**: e.g. the operation + takes the two values at the top of the stack, adds them together and pushed the result back to the stack. Besides this there are also some "advanced" features like variables living outside the stack, if you want to use them.
|
|
|
|
The stack is composed of **cells**: the size and internal representation of the cell is implementation defined. There are no data types, or rather everything is just of type signed int.
|
|
|
|
Basic abstraction of Forth is so called **word**: a word is simply a string without spaces like `abc` or `1mm#3`. A word represents some operation on stack (and possible other effect such as printing to the console), for example the word `1` adds the number 1 on top of the stack, the word `+` performs the addition on top of the stack etc. The programmer can define his own words which can be seen as "functions" or rather procedures or macros (words don't return anything or take any arguments, they all just invoke some operations on the stack). A word is defined like this:
|
|
|
|
```
|
|
: myword operation1 operation2 ... ;
|
|
```
|
|
|
|
For example a word that computes and average of the two values on top of the stack can be defined as:
|
|
|
|
```
|
|
: average + 2 / ;
|
|
```
|
|
|
|
Built-in words include:
|
|
|
|
```
|
|
GENERAL:
|
|
|
|
+ add a b -> (a + b)
|
|
- subtract a b -> (b - a)
|
|
* multiply a b -> (a * b)
|
|
/ divide a b -> (b / a)
|
|
= equals a b -> (-1 if a = b else 0)
|
|
< less than a b -> (-1 if a < b else 0)
|
|
> greater than a b -> (-1 if a > b else 0)
|
|
mod modulo a b -> (b % a)
|
|
dup duplicate a -> a a
|
|
drop pop stack top a ->
|
|
swap swap items a b -> b a
|
|
rot rotate 3 a b c -> b c a
|
|
. print top & pop
|
|
key read char on top
|
|
.s print stack
|
|
emit print char & pop
|
|
cr print newline
|
|
cells times cell width a -> (a * cell width in bytes)
|
|
depth pop all & get d. a ... -> (previous stack size)
|
|
bye quit
|
|
|
|
VARIABLES/CONSTS:
|
|
|
|
variable X creates var named X (X is a word that pushed its addr)
|
|
N X ! stores value N to variable X
|
|
N X +! adds value N to variable X
|
|
X @ pushes value of variable X to stack
|
|
N constant C creates constant C with value N
|
|
C pushes the value of constant C
|
|
|
|
SPECIAL:
|
|
|
|
( ) comment (inline)
|
|
\ comment (until newline)
|
|
." S " print string S
|
|
X if C then if X, execute C // only in word def.
|
|
X if C1 else C2 then if X, execute C1 else C2 // only in word def.
|
|
do C loop loops from stack top value to stack second from,
|
|
top, special word "i" will hold the iteration val.
|
|
begin C until like do/loop but keeps looping as long as top = 0
|
|
begin C while like begin/until but loops as long as top != 0
|
|
allot allocates memory, can be used for arrays
|
|
|
|
```
|
|
|
|
example programs:
|
|
|
|
```
|
|
100 1 2 + 7 * / . \ computes and prints 100 / ((1 + 2) * 7)
|
|
```
|
|
|
|
```
|
|
cr ." hey bitch " cr \ prints: hey bitch
|
|
```
|
|
|
|
```
|
|
: myloop 5 0 do i . loop ; myloop \ prints 0 1 2 3 4
|
|
```
|
|
|