articles/forth.md: update
This commit is contained in:
parent
d38a17ba59
commit
ce862bd2ca
1 changed files with 67 additions and 24 deletions
|
@ -11,6 +11,68 @@ Being a stack language, Forth has two stacks: the data stack (where you push val
|
||||||
Both stacks are of course modifiable by the user. Because the return pointer can also be modified manually, this allows
|
Both stacks are of course modifiable by the user. Because the return pointer can also be modified manually, this allows
|
||||||
implementing loops and control flow in the language itself.
|
implementing loops and control flow in the language itself.
|
||||||
|
|
||||||
|
Since Forth is a stack language, it uses a RPN syntax; valued are pushed to the data stack and then an operation
|
||||||
|
is applied:
|
||||||
|
```forth
|
||||||
|
2 2 + \ easy: 2 + 2
|
||||||
|
\ now the result in on the top of the data stack
|
||||||
|
\ and to print the top of the stack, use the `.` word:
|
||||||
|
. \ ==> 4
|
||||||
|
3 8 + 16 4 / * \ (3 + 8) * (16 / 4)
|
||||||
|
```
|
||||||
|
|
||||||
|
## User defined words
|
||||||
|
The programmer can of course define his own words, in Forth this is called "compiling":
|
||||||
|
```forth
|
||||||
|
: \ the `:` word starts compilation
|
||||||
|
sq \ name of our word
|
||||||
|
dup \ DUPplicate the value at the top of the stack
|
||||||
|
* \ multiply
|
||||||
|
; \ `;` ends compilation mode
|
||||||
|
|
||||||
|
8 sq . \ ==> 64
|
||||||
|
```
|
||||||
|
When compilation mode is entered (with `:`), the Forth environment reads the next word, which becomes
|
||||||
|
the name of our defined word (in this case `sq`) and after that it appends the addresses of all words
|
||||||
|
it reads to the current compiled word buffer until it finds the `;` word (which does not get added into
|
||||||
|
the word definition), exiting compilation mode and adding the new defined word to the dictionary.
|
||||||
|
|
||||||
|
How does Forth know to not add the `;` word into the defined word buffer? By executing it in compilation
|
||||||
|
mode. And how it knows when to execute a word at compile time and when not? By checking the immediate flag.
|
||||||
|
When a word has the immediate flag, aside from executing in normal mode, it also executes in compilation mode.
|
||||||
|
Moreover, in Forth words can have both *execution* semantics and *compilation* semantics. This is how Forth
|
||||||
|
supports metaprogramming. To mark a defined word as immediate, use the `immediate` word right after the `;`.
|
||||||
|
|
||||||
|
In Forth, everything is a word (what other languages call "functions"), including numbers, comments, and more.
|
||||||
|
For instance, this is how pForth (a public domain Forth implementation) defines comments in the language itself:
|
||||||
|
```forth
|
||||||
|
: ( 41 word drop ; immediate
|
||||||
|
( That was the definition for the comment word. )
|
||||||
|
( Now we can add comments to what we are doing! )
|
||||||
|
( Note that we are in decimal numeric input mode. )
|
||||||
|
|
||||||
|
: \ ( <line> -- , comment out rest of line )
|
||||||
|
EOL word drop
|
||||||
|
; immediate
|
||||||
|
```
|
||||||
|
From [system.fth](https://raw.githubusercontent.com/philburk/pforth/refs/heads/master/fth/system.fth).
|
||||||
|
|
||||||
|
## Compilation of words
|
||||||
|
Forth compiles its code to indirectly threaded code, consisting of pointers to pointers of words rather than [bytecode](bytecode.md)
|
||||||
|
or native machine code (although some Forths may compile to machine code, see DuskOS for example). Then, a word would be interpreted
|
||||||
|
by reading the pointers in the word definition and jumping to them, also keeping a return stack (Forth implementations usually keep
|
||||||
|
their own return stack).
|
||||||
|
|
||||||
|
## Numbers are also words
|
||||||
|
Since numbers are also words, you can do this:
|
||||||
|
```forth
|
||||||
|
: 2 4 ;
|
||||||
|
2 2 + 8 = . \ true
|
||||||
|
```
|
||||||
|
Of course other than being a example of Forth extreme flexibility, it is also a way to troll someone else Forth program
|
||||||
|
by breaking his entire program arithmetic.
|
||||||
|
|
||||||
|
## Charles Moore view on the Forth standard
|
||||||
Despite Forth being formally standardized (ANS Forth), Moore himself disavows any standardization:
|
Despite Forth being formally standardized (ANS Forth), Moore himself disavows any standardization:
|
||||||
|
|
||||||
> I had reservations about ANSI. I worried that it would be a disaster and not merely
|
> I had reservations about ANSI. I worried that it would be a disaster and not merely
|
||||||
|
@ -23,31 +85,10 @@ Despite Forth being formally standardized (ANS Forth), Moore himself disavows an
|
||||||
|
|
||||||
From: <https://www.ultratechnology.com/moore4th.htm>
|
From: <https://www.ultratechnology.com/moore4th.htm>
|
||||||
|
|
||||||
In Forth, everything is a word (what other languages call "functions"), including numbers, comments, and more.
|
|
||||||
For instance, this is how pForth (a public domain Forth implementation) defines comments in the language itself:
|
|
||||||
```forth
|
|
||||||
: ( 41 word drop ; immediate
|
|
||||||
( That was the definition for the comment word. )
|
|
||||||
( Now we can add comments to what we are doing! )
|
|
||||||
( Note that we are in decimal numeric input mode. )
|
|
||||||
```
|
|
||||||
From [system.fth](https://raw.githubusercontent.com/philburk/pforth/refs/heads/master/fth/system.fth).
|
|
||||||
|
|
||||||
Since numbers are also words, you can do this:
|
|
||||||
```forth
|
|
||||||
: 2 4 ;
|
|
||||||
2 2 + 8 = . \ true
|
|
||||||
```
|
|
||||||
Of course other than being a example of Forth extreme flexibility, it is also a way to troll someone else Forth program
|
|
||||||
by breaking his entire program arithmetic.
|
|
||||||
|
|
||||||
Forth compiles its code to indirectly threaded code, consisting of pointers to pointers of words rather than [bytecode](bytecode.md)
|
|
||||||
or native machine code (although some Forths may compile to machine code, see DuskOS for example). Then, a word would be interpreted
|
|
||||||
by reading the pointers in the word definition and jumping to them, also keeping a return stack. (Forth implementations usually keep
|
|
||||||
their own return stack)
|
|
||||||
|
|
||||||
## Forth implementations
|
## Forth implementations
|
||||||
- [pForth](https://www.softsynth.com/pforth/): public domain almost-ANS Forth like implementation.
|
Because Forth is so simple, there are countless implementations available:
|
||||||
|
|
||||||
|
- [pForth](https://www.softsynth.com/pforth/): public domain, "almost" ANS Forth like implementation.
|
||||||
- [gforth](https://gforth.org/): GNU project implementation of ANS Forth.
|
- [gforth](https://gforth.org/): GNU project implementation of ANS Forth.
|
||||||
- [DuskOS](duskos.md) and [CollapseOS](collapseos.md).
|
- [DuskOS](duskos.md) and [CollapseOS](collapseos.md).
|
||||||
- [colorForth](https://colorforth.github.io/cf.htm): by Moore himself, notable for using colors for word type categorization,
|
- [colorForth](https://colorforth.github.io/cf.htm): by Moore himself, notable for using colors for word type categorization,
|
||||||
|
@ -59,3 +100,5 @@ also for running without an [OS](operating_system.md); colorForth is its own ope
|
||||||
- [Official site of ANS Forth](https://forth-standard.org/)
|
- [Official site of ANS Forth](https://forth-standard.org/)
|
||||||
- <https://users.ece.cmu.edu/~koopman/stack_computers/appb.html>
|
- <https://users.ece.cmu.edu/~koopman/stack_computers/appb.html>
|
||||||
- [Simple Forth](http://www.murphywong.net/hello/simple.htm)
|
- [Simple Forth](http://www.murphywong.net/hello/simple.htm)
|
||||||
|
- [Tumble Forth](http://tumbleforth.hardcoded.net/): series on building a Forth from scratch; from DuskOS creator.
|
||||||
|
- Making your own Forth! This is one of the best ways of learning how Forth works.
|
||||||
|
|
Loading…
Add table
Reference in a new issue