The FORTH compiler
published: 21 May 2025 / updated 21 May 2025
Le compilateur FORTH
article: 15 mai 2019 / mis à jour 24 mai 2019
Le compilateur FORTH travaille en une seule passe et sans gérer de table de référence. Son rôle est d'accroître les fonctions disponibles dans le dictionnaire.
Compilation d'une définition
La compilation d'une définition ordinaire débute par le mot :
(deux-points) et
s'achève par le mot ;
(point- virgule). Le mot :
est suivi du libellé
du mot à définir. Tout ce qui se trouve entre ce mot et le mot ;
fait partie de
la définition du mot et sera ensuite exécuté, soit directement depuis l'interpréteur,
soit depuis une autre définition de mot FORTH. Pour exemple, compilons une définition
que l'on nommera AFFICHE-BINAIRE
et dont le rôle sera d'afficher en binaire un
nombre préalablement déposé au sommet de la pile de données:
: AFFICHE-BINAIRE ( n --- )
2 BASE ! . DECIMAL ;
Le mot :
(deux-points) ouvre une séquence de compilation et est suivi du libellé
du mot à définir. Le nom peut être composé de tous les caractères ASCII dont le code est
compris entre 33 et 126, donc à l'exclusion de tout espace ou caractère de contrôle.
La longueur d'un mot est comprise entre 1 et 31 caractères maximum.
Le nom est suivi de la définition:
2 BASE ! \ passage en base numérique binaire . \ affichage du nombre précédemment empilé DECIMAL \ restitution de la base numérique décimale
La fin de la séquence de compilation est marquée par le mot ;
(point-virgule).
Forth revient en mode interprétation. Cette définition peut être tapée depuis le clavier
ou faire partie d'un fichier ASCII.
Tout mot compilé dans le dictionnaire FORTH peut être intégré à une nouvelle définition. En FORTH, un mot peut être considéré comme programme principal ou comme procédure d'un programme plus général.
Lors de la compilation d'une nouvelle définition tapée au clavier, vous pouvez taper sur <RET> à peu près n'importe quand:
: AFBIN 2 BASE ! . DECIMAL ; puis <RET>Cette définition peut être tapée depuis le clavier en plusieurs fois de la manière suivante:
: AFBIN <RET> 2 BASE <RET> ! . <RET> DECIMAL <RET> ; <RET>
La disposition des mots, le nombre d'espaces entre les mots, ainsi que la frappe en majuscule ou minuscule importe peu:
: afbin 2 BaSe ! . DecimaL ;
sera également accepté pourvu que le format des nombres soit cohérent et que les mots utilisés soient définis dans le dictionnaire.
ATTENTION: sur certaines versions FORTH disponibles sur micto-contrôleurs, il est nécessaire de respecter la casse des caractères constituant les mots du dictionnaire. C'est le cas pourFalshForth sur Arduino.
A ce jour, le langage FORTH est le seul langage connu acceptant de compiler du code source tapé directement depuis le clavier de manière aussi interactive. Cette dualité interpréteur/compilateur est également exploitable lorsque l'on veut compiler le contenu d'un fichier.
Mots définis plusieurs fois
Si deux mots portent le même nom, seul le dernier mot défini sera exécutable en interprétation:: TEST1 ." Premier test " CR ; : TEST1 ." Second test " CR ;
Ne tenez pas compte du message TEST1 "existe déjà" (ou équivalent):
TEST1 \ affiche SECOND TEST
L'interpréteur accède au contenu du dictionnaire à partir du dernier mot défini
et exécute la définition la plus récemment définie parmi deux ou plusieurs
définitions de même nom. Si une définition utilise la première version de
TEST1
, la création d'un nouveau mot portant également le nom
TEST1
ne modifie pas le comportement de cette définition:
: TEST1 ." Premier test " CR ;
: REGARDE TEST1 ;
: TEST1 ." Second test " CR ;
REGARDE \ affiche Premier test
Pour modifier REGARDE
et lui faire utiliser la nouvelle version
de TEST
, il faut également recompiler REGARDE
:
: TEST1 ." Premier test " CR ;
: REGARDE TEST1 ;
: TEST1 ." Second test " CR ;
: REGARDE TEST1 ;
REGARDE \ affiche Second test
Cette homonymie tolérée par FORTH permet de compiler successivement plusieurs programmes comportant des définitions de même nom sans avoir à rééditer le programme source pour renommer les noms de définitions identiques.
Cependant, dans une phase de mise au point de définition, on peut être gêné par la présence d'homonymes, et il est souhaitable de supprimer les versions de certaines définitions devenues inutiles, soit pour conserver la cohérence du programme, soit pour récupérer de l'espace mémoire ou toute autre raison pratique.
Enfin, l'existence de plusieurs vocabulaires définis par le programme est une façon élégante de lever les ambiguités entre homonymes.
Supprimer un mot du dictionnaire
Pour supprimer un mot du dictionnaire, il faut exécuter le mot FORGET
suivi du nom de la définition à supprimer:
FORGET MOT1
supprime du dictionnaire MOT1
et tous les mots définis après lui.
Si MOT1
est défini plusieurs fois, seule la dernière version de
MOT1
est supprimée. Exemple:
: TEST1 ." Premier test " CR ; : REGARDE TEST1 ; : TEST1 ." Second test " CR ; : REGARDE TEST1 ;
WORDS affiche REGARDE MOT1 REGARDE MOT1 ...etc...
FORGET MOT1 WORDS affiche REGARDE MOT1 ...etc...
Pour oublier tous les mots définis depuis le lancement de FORTH, taper EMPTY
.
Vous pouvez marquer le début d'une application en exécutant MARK
suivi du nom
de l'application. Exemple, soit à compiler les fonctions graphiques contenues dans le
fichier GRAPHIC.FTH, puis à compiler un programme utilisant ces fonctions graphiques:
INCLUDE GRAPHIC MARK DESSIN
Si le contenu de a été modifié et doit être recompilé, il ne sera pas nécessaire
de taper EMPTY
puis de tout recompiler; en tapant DESSIN
,
vous supprimerez du dictionnaire les seules définitions compilées après le mot DESSIN
.
Si vous essayez de supprimer une primitive du dictionnaire, un message d'erreur s'affichera:
FORGET DUP \ affiche Partie dictionnaire protégée
Il est possible de protéger son application contre une destruction accidentelle en tapant la séquence:
HERE FENCE !
Exemple:
: TEST1 ." Troisième test " CR ;
: REGARDE TEST1 ;
HERE FENCE !
FORGET TEST1 \ affiche Partie dictionnaire protégée
Le mot FORGET
teste d'abord la valeur contenue dans la variable
FENCE;
si son contenu est inférieur à l'adresse de compilation
du mot à supprimer, le mot est supprimé du dictionnaire; dans le cas contraire,
un message d'erreur s'affiche. La séquence HERE FENCE !
réinitilialise
le contenu de FENCE
en lui attribuant la valeur du pointeur de
dictionnaire actuelle, c'est à dire une valeur supérieure à l'adresse de
compilation de TEST1
, ainsi TEST1
et REGARDE
deviennent des mots protégés.
Constantes et variables simple précision
Tout programme écrit en FORTH, aussi sophistiqué soit-il, ne peut pas toujours traiter des
données provenant de la pile de données. Dans certains cas on fera appel à des constantes
et des variables. Les constantes sont définies à l'aide du mot CONSTANT
:
2019 CONSTANT ANNEE-COURANTE
Les variables sont définies à l'aide du mot VARIABLE
:
VARIABLE JOURS
La constante ANNEE-COURANTE
et la variable JOURS
figurent maintenant
dans le dictionnaire FORTH, c'est-à-dire qu'elles sont disponibles au même titre qu'un
mot compilé par :
(deux-points) ou n'importe quelle autre primitive déjà définie
dans FORTH. Seule l'exécution de ces mots diffère de celle d'un mot défini par :
(deux-points).
Une constante dépose au sommet de la pile de données la valeur affectée au moment de sa définition:
ANNEE-COURANTE . 2019
Une variable dépose au sommet de la pile de données l'adresse contenant la valeur qui lui a été affectée ou qui devra y être affectée.
JOURS .
affiche une adresse simple précision (ou 32 bits selon la version Forth).
Le contenu de cette adresse est déposé sur la pile de données par l'exécution du mot @
:
JOURS @ .
affiche 0. Zéro est la valeur attribuée par défaut à une variable lors de sa création.
Une valeur numérique simple précision peut être stockée dans une variable par l'exécution du mot !
:<:p>
15 JOURS ! JOURS @ . 15