Forth is a “concatenative” programming language. This means that there are only minimal syntax rules, and commands or functions (“words” in Forth parlance) are written one after the other, separated by spaces. All components that are implemented in popular programming languages through syntax (comments, variable definitions, control structures such as loops or decisions with IF-THEN-ELSE) are completely normal “words” under Forth.
Conversely, this means that programmers can adapt “their” Forth themselves in any way they want. Forth is like a construction kit for your own programming languages, which allows programmers to implement the desired application as elegantly as possible.
Forth to look at The Forth source code takes getting used to. The structure is not dictated by the language, it is left to the programmer to format the source code in a readable manner. Since the space for source code on storage media was also severely limited in Forth’s early years, Forth unfortunately acquired the reputation of a write-only programming language. It takes a little discipline to write legible Forth programs.
In order to get a feel for Forth, part of the Forth source code is taken from the “Tetris for terminals “of the GNU / Forth (file tt.fs )). The code implements a pseudo-random number generator (Pseudo-Random-Number-Generator or PRNG), which is used in the Tetris game. In the source code, existing Forth words such as dup , + and ! put together to new words (functions, subroutines):
stupid random number generator variable seed: randomize time & date + + + + + seed! ; $ 10450405 constant generator: rnd (- n) seed @ generator um drop 1+ dup seed! ; The first line is a comment, introduced with the Forth word . is not a syntax as we know it from other programming languages, but a Forth word (a Function), which is executed directly when reading the source text. This function reads all characters in the source text up to the end of the line and discards these characters. This means that the comment text is no longer visible to the Forth system and the function of a comment mark is implemented. If programmers have their own ideas about which character should introduce a comment, they simply add a new comment word of their own to the Forth system.
The line variable seed is easy to understand. It creates a variable. A Forth variable can store a numeric value that corresponds to the native data bus size of the CPU. So 16, 32, 64 or in the case of RISC-V already 128 Bit. The Forth word variable is not a special syntax, but only a function written in Forth, the memory reserved and connects to the specified name. The name of the variable, here seed , is then a new Forth word that is used when the Lays the address of the variable on the data stack (more on this later). With most Forth systems, this variable is the only data structure that the system delivers. Forth programmers create arrays, structs, objects and other data structures using their own, individual Forth words. Creating your own data structures in Forth is not difficult, and even with popular programming languages, you often have to create more complex data structures yourself. So why not start at the beginning.
The Forth word : (Colon) activates the Forth compiler. All subsequent words, up to the final Forth word ; (semis), are not executed directly, but compiled into a new Forth word. The name (or identifier) of the new word immediately follows : .
This new Forth word has the task of initializing the random number generator for the Tetris game (the random number generator shown here is very simple, sufficient for games, but should not be used for security-critical applications).
The Forth word time & date defines six values (second, minute, hour, Day, month, year) on the stack of the Forth system. In a Forth system, all input and output parameters for functions are passed implicitly via a data stack. “Implicit” here means that the number of parameters is not specified when defining the Forth word and when it is called. The stack is a built-in LIFO (Last-In – First-Out) data structure of every Forth system. It takes a little practice to follow the movement of the parameters on the data stack. Beginners can help themselves with detailed comments. The number of parameters is not recognizable in the source text.
: randomize time & date + + + + + seed! ; The following addition signs + are Forth words, the function of which is the add the top two elements on the stack to each other and put the result back on the stack. Forth uses the Postfix notation for mathematical functions. The values are first placed on the stack and then the mathematical function is called, which “consumes” the values from the stack and leaves the results back on the stack.
The current date becomes here and the current time, a seed is determined for the random number generator. The word for the variable seed puts its own memory address on the stack, and the following word ! , pronounced “Store”, saves the calculated value in the memory location of the variable seed . It should be noted that ! can not only write to variables, but also to writes any memory areas.
The following line is again easier to understand:
$ 10450405 constant generator It creates a new Forth word with the Name generator . It is a numeric constant with the value hexadecimal 10450405. If this new Forth word is used in the rest of the program, it puts this value on the stack.
In the last line of the small example, a Forth word is now generated which, when executed, contains a creates a new random number and leaves it on the stack:
: rnd (- – n) generate random number seed @ reload current seed of the PRNG generator drop 1+ calculate random number dup double number seed! and save a copy as a new seed; Colon (: ) switches the Compiler on, and rnd is the name of the new Forth word defined here. The brackets ( and ) represent another form of comment (where ( is a Forth word that consumes and discards all characters in the source text up to the character ) and thus withheld from the Forth system). This is a stack comment that serves as documentation for programmers and describes which input and output parameters this function expects or generates. In this case a natural (random) number n is used after calling rnd left on the stack.
from seed begins the body of the new function. seed as a variable from above puts its own memory address on the stack. The Forth word @ (pronounced “fetch”) is the opposite of ! (store) and consumes the address as the top entry on the stack and, as a result, puts back the value stored at the address in the main memory on the stack.
The Forth word generator ( a numeric constant) puts the value hexadecimal 10450405 on the stack, which transfers the word (unsigned double multiply “um-star”) with the value from seed and leaves it on the stack as a double-exact number.
The word drop discards the upper value of the stack, here the more significant part of the double-exact number (the coincidence takes place in the lower part of the number). This result, the lower part of the double-exact number, is increased by one with the word 1 + and then duplicated with the word dup . dup reads the top entry on the data stack and places a copy of it on top of that. The copy of the value is now saved as a new seed in the variable seed , while the original value is stored on the Stack remains and, as a result of the function, waits for further use in the program. The word ; (semicolon) closes the definition of the new Forth word rng , switches off the Forth compiler and transfers control back to the interactive Forth system.