FORTH

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 FORTH!

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!