FORTH - as well as LISP,
etc. - are very interesting programming languages of - as we say - 'artificial
intelligence':
You may improve them adding new terms and structures simply by means
of the existing language kernel!
FORTH consists uniquely of words. Such a word can be a number or a string or the name of a procedure.
Then, there is a simple Data Stack: words are fetching the values they need (their parameters as we say) from there and finally they bring back their output to this stack – ready for use by the next words.
And when you are working with FORTH you do nothing else than lining up such individual words.
That's all. – There is no more else!
So, inspite of FORTH having a very simple architecture, you actually can do anything with it! (Just like it is with LISP again.)
You can extend the language yourself – exclusively by using the existing language – you can define new language elements and language structures or new data structures and objects - and so on.
So, it's absolutely exciting to work with FORTH! – When you start working with FORTH, it will inspire an incredible creative power in you!
The Book I read: Die Programmiersprache FORTH, written by
Ronald Zech, ISBN 3-7723-7262-7.
And now let's make an example of what I just told to you in !
We improve the IF structure adding an ELSIF keyword, so that it can be used in the same way as the IF structure of Modula-2 or FORTRAN 77.
The syntax (in EBNF) is:
IfClause = condition "IF" {word}
{"ELSIF"
condition "THEN" {word}}
["ELSE"
{word}]
"ENDIF"
| "THEN"
Here the keyword definitions:
: IF ( -> ADDR, N ) ( compile-time)
( f -> )
( run -time )
?COMP
COMPILE 0BRANCH
HERE [ LATEST PFA ] LITERAL
0 ,
; IMMEDIATE
: ELSIF ( addr1 [, addr2], n1 -> addr3, n2 )
( compile-time)
( -> )
( run-time )
?COMP
COMPILE BRANCH
DUP ' IF =
IF
DROP
HERE NIL , ( 0BR, BBR)
ELSE
LIT [ HERE >R 0 , ] ( ' THEN)
?PAIRS
HERE ROT , ( 0BR, BBR)
ENDIF
SWAP FROW
[ LATEST PFA ] LITERAL
; IMMEDIATE
: THEN (addr1, n1 -> addr1, add2, n2 ) (
compile-time)
( f -> )
( run-time )
?COMP
DUP ' ELSIF =
IF ( 'proper' THEN)
DROP
COMPILE 0BRANCH
HERE 0 ,
[ LATEST PFA ] LITERAL
ELSE ( 'exotic' THEN)
[ HERE >R 0 , ] ( ' ENDIF CFA)
ENDIF
; IMMEDIATE
: ELSE ( addr1 [, addr2], n1 -> addr3, n2 )
( compile-time)
( -> )
( run-time )
[COMPILE] ELSIF
DROP ( drop ' ELSIF)
[ LATEST PFA ] LITERAL
; IMMEDIATE
: ENDIF ( addr1 [, addr2], n -> ) ( compile-time)
( -> )
(run-time )
?COMP
DUP ' IF = OVER ' THEN = OR
IF
SWAP
( Fix up BBR:)
FROW
ENDIF
DUP ' THEN = OVER ' ELSE = OR
IF
DROP
( Fix up BBR:)
BEGIN
?DUP
WHILE
DUP @ SWAP
FROW
REPEAT
ELSE
' IF ?PAIRS
ENDIF
; IMMEDIATE
( Resolution of Forward References:)
' ENDIF CFA R> !
' THEN
R> !
Note: The green IF-structure
keywords are 'metasymbols' only:
For an actual compilation you will need to translate them into corresponding
0BRANCH and BRANCH operations before!