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
|
||||
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.
|
||||
|
|
Loading…
Add table
Reference in a new issue