4IM sous DOSEMU - Avec des SI

Rappel : le texte cité depuis le tutoriel d'Astrobe, est reproduit en bleu.
Ce site se trouve à l'adresse : http://membres.lycos.fr/astrobe/

SI

Supposons que nous voulions réaliser la fonction "valeur absolue de X": abs(x)= x si x est positif, -x sinon. Cela s'écrit:
: ABS DUP 0< IF NEG THEN .
Le mot IF est ( presque ) un mot comme les autres :
il prends ses paramètres sur la pile.
S'il y trouve 0, l'exécution saute après THEN; sinon on continue.

Remarque : si la condition est vraie, la valeur 0 est déposée sur la pile.
Du coup la "condition" se trouve avant le IF.
J'ai mis le mot "presque" entre parenthèses car cette condition n'est pas définie par la syntaxe ( et pour cause, Forth est pratiquement exempt de syntaxe).
Dans notre exemple on peut estimer que 0< est la condition. On peut aussi y inclure le DUP qui précède, c'est uniquement une question d'appréciation.

Sinon

Contrairement à ce que l'on pourrait s'attendre, 4IM n'a pas de ELSE. C'est un choix basé sur la constatation qu'on peut facilement s'en passer.
Soit par exemple la fonction :
f(x)= 0 si x< 10, 1 sinon

: F 10 < IF 0 ; THEN 1 .

Ici, on évite le ELSE par l'usage du point-virgule.
Ce mot (le point-virgule) est en fait une primitive du mot "." qui compile l'instruction qui permet le retour au 'marque-page'. Autrement dit, le point-virgule permet une "sortie anticipée" de l'exécution de la définition.

Exercice 6

Objectif : vérifier le fonctionnement du code :
: F 10 < IF 0 ; THEN 1 .

Manipulation :
: F 10 < IF 0 ; THEN 1 .
Ready
5 F ?
0 Ready
14 F ?
1 Ready

Remarque : que se passe-t-il si l'on introduit une valeur négative (obtenue par NEG de la valeur) ?
Par exemple tester la valeur -15
15 NEG F ?
1 Ready

Ce qui semble manifestement faux : -15 étant plus petit que 10, on devrait obtenir 0
L'explication, très rationnelle, tient à la manière dont sont stockées les valeurs négatives (et on relira sur ce point le texte d'Astrobe).

La quasi-totalité des autres Forth auraient écrit : F 10 < IF 0 ELSE 1 THEN .
Et cela alors qu'ils disposent d'une primitive équivalente à notre point-virgule, nommée EXIT.
Je trouve que la forme sans ELSE est nettement plus claire car plus linéaire: le ELSE introduit un saut supplémentaire, qui se retrouve d'ailleurs dans le code machine généré.
Dans l'exemple proposé cela aboutit aussi à une execution moins efficace, car le saut introduit par ELSE est purement et simplement inutile.

Commentaire supplémentaire d'Astrobe

Certes, il existe des cas défavorables où l'absence de ELSE est génante. Mais ils ne sont pas aussi nombreux qu'on le croit a priori: un peu de réflexion permet de trouver la bonne formule. C'est pour forcer cette réflexion de la part du programmeur que ELSE n'est pas proposé.
Les conditions compliquent les choses. Evitez autant que possible d'imbriquer les IF...THEN dans une définition; créez une définition à part qui absorbe le IF interne si nécessaire. Ou mieux, cherchez un moyen de les éliminer. Ce peut être par l'exploitation d'une propriété mathématique par exemple.

Les mots IF THEN et ; forment la première moitié du vocabulaire qui vous permettra de construire vos programmes. Le mot -IF, qui est l'équivalent de 2DUP - IF, a été ajouté car très utile notamment dans les boucles.



A suivre...