articles/forth.md: update

This commit is contained in:
tocariimaa 2025-02-15 12:55:46 -03:00
parent d38a17ba59
commit ce862bd2ca

View file

@ -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
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:
> 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>
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
- [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.
- [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,
@ -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/)
- <https://users.ece.cmu.edu/~koopman/stack_computers/appb.html>
- [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.