Introduction
Téléchargement
Spécificité
Installation
Aide Dos
Les langages
Mini-théorie
Responsabilité
Quelques mots
Entrainement 1
4 mot de vocabulaire
Mots de pile
Mots de pile 2
Lumière sur l'ordinateur
Boucle d'or
Les variables
Les constantes
Entrainement 2
SEE
Personnalisation
exercice 11
vocabulaire supp'
notions nouvelles
le code ASCII

Introduction :

Ce petit tutoriel a pour objet une première introduction au Forth. Il s'adresse au novice en matière d'informatique et de programmation _Je suis moi même débutant_ Je poursuis deux buts en écrivant ce tutoriel :

  • Le premier très pretentieux: aider le novice à approcher ce langage, et lui donner envie d'aller voir plus profond.

    Le second assurement atteint: bien faire rigoler ceux qui s'y connaissent.

Quoi qu'il en soit je suis disponible (dans la maigre mesure de mes connaissances) à répondre à toutes les questions de ceux qui auraient des difficultés, il suffit de me passer un courriel à:
jcboisserie@free.fr, ou poser vos questions sur la liste de diffusion forth, pour vous abonner :
forth-abonnement@club.voila.fr

Téléchargement :
le plus simple est de lire le fichier telech.htm sinon...

Le Forth utilisé pour les exemples est Turbo-Forth, disponible gratuitement sur le site internet suivant:
ftp://ftp.acbm.com/pub/tforth/TF83.exe        ou sur:
http://www.acbm.com/magasin.html
Les deux manuels qui l'accompagnent dans sa version complète, étaient disponibles auprès son auteur pour 100,00 F TTC
Si vous télécharger le fichier TF83.exe, pour simplifier, nous considérerons que vous l'enregistrez sur le A: (Ce qui indique qu'il faudra une disquette 1,44Mo formatée dans le lecteur de disquette).

Je vous passerais toutes les manipulations sur le téléchargement du fichiers.

Maintenant que vous avez enregistrer TF83.exe sur la disquette, laisser la disquette dans le lecteur, il suffit de cliquer sur Démarrer, puis clic sur exécuter (une fenêtre s'ouvre) tapez a:\forth83 clic sur OK

Lors de l'installation des question vous sont posée:
Voulez-vous extraire cette archive (oui/non) ? O
RÚpertoire de destination : [c:\tf83] si vous voulez le répertoire dans c:\dudulle il suffit de tapez c:\dudulle sinon, si le répertoir c:\tf83 vous convient taper sur [entrée]
Le rÚpertoire c:\dudulle   \tf83 n'existe pas. Faut-il le crÚer ? (oui/non) O

Un échantillon ci-dessous de se qui défilera à l'écran.
faits : c:\dudulle   \tf83   \EXEMPLES   \MP   \MP.DOC faits : c:\dudulle   \tf83   \EXEMPLES   \LIST   \LIST.DOC faits : c:\dudulle   \tf83   \EXEMPLES   \LIST   \LIST.FTH faits : c:\dudulle   \tf83   \EXEMPLES   \ASTRING   \ASTRING.FTH faits : c:\dudulle   \tf83   \lisezmoi.txt faits : c:\dudulle   \tf83   \Update.txt 400 fichiers extraits contenant 2,668,909 octets.

Voilà pour l'installation

maintenant allez dans le répertoire de Forth est double cliquer sur tfx386.exe pour en appréciez toute la puissance et l'on se retrouve dans la leçon suivante...

Spécificité :

Turbo-Forth tourne sous le système d'exploitation MS-DOS et avec les processeurs X86 d'intel, donc même un vieux PC de 15 ans suffit, même si tout fonctionne encore plus vite avec une machine plus récente.

Installation :

Si vous avez la version disquette, la procèdure à  suivre est décrite ci-dessous ( elle suppose que vous possédiez Windows 95 ou plus ). Si vous n'avez que MS-DOS, vous n'aurez pas de mal a adapter la méthode, si vous avez la version disponible en téléchargement, je pense que vous pourrez aussi vous débrouiller avec ce qui suit:
Pour commencer, il faut recopier la disquette sur le disque dur : passer d'abord sous MS-DOS, une fois MS-DOS ouvert, vous pouvez mettre la fenetre en plein écran en tapant Alt-Entree, et la réduire ensuite de la même façon. Après chaque ligne de commande, la frappe de la touche entrée est symbolisée par le caractère ¬
Une fois sous DOS l'écran affiche ceci :
C:>    C'est a dire "je suis sur le disque C: dans le répertoire Windows et j'attends des instructions". On va donc retourner au répertoire racine C: en tapant :
cd.. ¬   
l'écran affiche alors :    C:>
On va créer un répertoire FORTH, et un sous-répertoire TF83 en tapant les commandes suivantes :
md Forth ¬
cd Forth ¬
md TF83 ¬
cd TF83 ¬
l'écran affiche alors :    C:>
On est alors dans le répertoire Forth, le sous répertoire TF83. On va maintenant copier la diquette en tapant :
a: ¬
copy *.* c:¬
c: ¬
l'écran affiche alors :
C:>Forth>
On tape :
dir ¬
l'écran affiche la liste des fichiers présents dans le répertoire. Maintenant on peut lancer TF83 en tapant :
TFX386 ¬
Pour les prochaines fois qu'on redemarrera, on se retrouvera dans MS-DOS, avec l'affichage suivant :
C:>
Là il vous faudra taper :
cd.. ¬
cd forth ¬
cd tf83 ¬
tfx386 ¬
ou bien créer un ficher avec le programme Dos "EDIT" qu'on lance sous dos en tapant :
edit ¬
dans lequel vous taperez les 4 lignes de commandes, et que vous enregistrerez dans le répertoire Windows sous le nom (par exemple) TF.BAT, ainsi lorsque vous serez avec l'affichage :
C:>
Vous taperez simplement :
tf ¬
et Turbo-Forth 83 sera lancé.

Aide Dos :

il faut connaitre le fonctionnement de quelques commandes DOS :
cd dudullle: Change Directory (changement de répértoire) vers dudulle
cd..
: ChangeDirectory vers répertoire parent (remonte au repertoire précédent contenant celui sur lequel on se trouve).
md: MakeDirectory dudulle (fabrique un répertoire) nommé dudulle
copy duglu.txt c:\dudulle : copie duglu.txt dans le répertoire dudulle (l'aide vous sera utile pour cette fonction de DOS).
a: ou c: : change l'unité de stockage
dir : Directory affiche le contenu du répertoire courant
dir/p : Directory avec Pause, idem ci-dessus, mais affiche page à page, il faut taper sur espace pour la page suivante.
Pour connaitre le fonctionnement d'une commande DOS, il faut taper :
nom_commande /? ¬    exemple: dir/?
ceci marche pour toutes les versions de DOS, mais essayez aussi la commande :
help ¬
Si vous avez la chance qu'elle fonctionne, vous pourrez voir toutes les
commandes DOS disponibles.

Les langages de programmation :

Il existe un seul langage de programmation compréhensible par les ordinateurs, c'est le langage machine, constitué uniquement de 1 et de 0 (en fait des tensions éléctriques de +5V et 0V -voire moins dans les ordinateurs les plus modernes). Un ensemble de 1 et de 0 peut représenter pour la machine deux choses, soit une commande, soit des données à traiter selon la commande. Les premiers ordinateurs étaient programmés et utilisés à l'aide de cartes perforées. Cela était trés compliqué et trés lent, par exemple rentrer la valeur 25 demande en langage machine d'écrire : 11001 , pour 345, il faut écrire : 101011001, en fait on traduit de base 10 (décimale) en base 2 (binaire). Pour se simplifier la tâche, les informaticiens ont écrit un programme de traduction en langage machine que l'on appelle ASSEMBLEUR, qui représente aujourd'hui le seul langage réellement proche de la machine utilisée. L'ASSEMBLEUR utilise une base numérique intermédiaire pour communiquer avec la machine, c'est la base 16 (héxadécimale) -nous verrons tout cela ultèrieurement-. Comme c'est le langage le plus proche de celui de la machine, l'assembleur est appellé langage de bas niveau. Cependant, l'utilisation de l'assembleur reste assez fastidieuse, aussi les informaticiens ont écrit des langages plus proches du langage humain pour faciliter la programmation, ce sont les langages de haut niveau : dont le BASIC,le C, le PASCAL, le FORTH, etc...
L'inconvénient des langages de haut niveau, c'est qu'ils utilisent des "traducteurs", et que les traducteurs ne font pas toujours les phrases les plus courtes que l'on aurait pu faire pour se faire comprendre. Ce qui fait qu'un programme écrit en langage de haut niveau est toujours plus lent que le même programme écrit en assembleur (sauf à le faire exprès). C'est pour cela que l'assembleur est toujours utilisé. Les langages de programmation de haut niveau se divisent en deux groupes : les langages INTERPRÈTES (ex: Basic), et les langages COMPILÉS (ex: C).Les langages compilés sont traduits en entier une seule fois, et convertisen langage machine et sauvegardés sous cette forme. Les langages interprétés sont traduits au vol en langage machine, et chaque ligne est traduite, puis exécutée, avant de traiter la suivante. Les langages compilés ont le défaut que l'on ne peut pas les exécuter directement, et il faut recompiler à chaque modification du programme, par contre, cela fait, ils sont d'une très grande rapidité d'exécution. Les langages interprétes sont exécutables directement, mais sont en contrepartie beaucoup plus lents à l'exécution. Le Forth est quand à lui un langage atypique , qui est alternativement interprété et compilé, et qui est aussi alternativement de haut et de bas niveau. C'est un langage struturé (pas de GOTO), basé sur l'utilisation d'une pile (comme les piles d'assiettes), sa syntaxe utilise la notation polonaise inversée (comme les calculatrices HP), et qui contient son propre assembleur.

Mini théorie :

La mémoire des ordinateurs et les ordinateurs eux même ne comprennent que les 1 et les 0. Ainsi, une position binaire (qui prend une valeur 1 ou 0) est appellée un bit; quatre positions binaires sont appellées un quartet (ou nibble en anglais), huit positions binaires sont appellées octet (ou byte en anglais -attention aux confusions avec bit-), seize positions binaires sont appellées mot (ou word en anglais), trente deux positions binaires sont appellées mot-long (ou double-word en anglais). Ces notions sont suffisantes pour débuter, mais très importantes, résumons les en un tableau :

Nbre positions binaires
Appellation
Relations diverses
1
Bit  
4
Quartet (nibble) = 4 bits
8
Octet (Byte) = 8 bits = 2 quartets
16
Mot (Word) = 16 bits = 2 octets
32
Mot-long (Double-word) = 32 bits = 4 octets

Responsabilité :

La version de Forth que nous allons utiliser (Turbo Forth), est une version16 bits. Il est primordial de bien comprendre que la machine n'est dotée d'aucune intelligence, tout ce qu'elle sait faire, c'est manipuler des 1 et des 0 très rapidement et en très grande quantité, et seulement de la façon dont on le lui a demandé de le faire. La machine ne fait pas d'erreurs, ses concepteurs, ses programmeurs  et ses utilisateurs si. La machine ne réfléchit pas elle fait bêtement sans comprendre et sans chercher à le faire (elle ne peut pas). Ainsi si nous demandons a la machine d'additionner 2 et 3, celà ne signifiera rien pour elle, par contre elle saura faire cette opération sur les 1 et 0 qui représenteront ces deux nombres.

Revenons a notre langage Forth. La version est 16 bits, cela signifie que les élements de base manipulés par TF ont une largeur de 16 bits qui peuvent prendre les valeurs 1 ou 0, autrement dit les valeurs manipulées par TF varieront entre 0000 0000 0000 0000 et 1111 1111 1111 1111 en binaire, soit pour faire plus court et plus compréhensible pour nous entre 0 et 2^16 ( l' accent circonflexe note l'opération exposant) soit 65536 en décimal. Nous voyons donc que ce langage ne sait manipuler que des entiers, et dans un intervale restreint. De plus, pour manipuler les entiers négatifs, les valeurs de 32768 a 65536 représentent les entiers négatifs de -32768 à -1. Donc pour avoir des résultats cohérents dans les opérations sous TF, il faut que le résultat soit compris entre 0 et 32767 pour un résultat positif, et entre -1 et -32768 pour un résultat négatif. Il existe tout de même, une possibilité en utilisant des opérateurs spéciaux de travailler sur des nombres 32 bits, dont l'intervalle de valeurs varie de 0 a 2^32, soit de 0 à 4294967296, et qui permettent de travailler sur les entiers entre -2147483648 et 2147483647. Pour effectuer des calculs en virgule flottante, il existe des extensions au langage de base, qui représentent les nombres en deux parties, la mantisse et l'exposant, ainsi, par exemple 2,75468 sera représenté par la mantisse 275468 (entier) et l'exposant -5 (entier), car 2,75468 = 275468*10^-5 (* est le signe de la multiplication), évidement, cette représentation exige un programme particulier pour effectuer les opérations, et les opérations sont beaucoup plus lentes que sur des entiers. Ces considérations sont importantes, car un obtient quelquefois des résultats qui paraissent incohérents, à cause de ces limitations, et il faut alors user d'astuce pour les contourner. Le Forth est un langage qui utilise un vocabulaire (un ensemble de mots qui ont chacun une fonction particulière), et une syntaxe (quelques règles grammaticales). Le vocabulaire de Forth peut être étendu, c'est a dire qu'on peut lui apprendre des mots nouveaux, en les définissants à partir des mots existants (c'est d'ailleurs ainsi que l'on programme en Forth). En ce qui concerne la syntaxe, il convient de noter qu'un ou plusieurs espaces doivent séparer deux mots, et que l'ordre des mots est primordial, le premier mot rencontré est exécuté avant le second, etc... Les mots Forth comprennent de 1 à 31 caractères ( ces caractères doivent avoir un code ASCCI compris entre 1 et 127 - voir plus bas ), y compris les signes de ponctuation et les chiffres, à l'exception de l'espace, on pourrait ainsi définir le mot : C'est_la_mere_Michelle_qui_a_p (c'est un peu long pour être pratique d'emploi,mais c'est possible).

Quelques mots :

Voici quelques mots Forth, et leur action :
+      Addition
-      Soustraction
/      Division entière
*      Multiplication
.      Affichage destructif du sommet de la pile
.s      Affichage non destructif de la pile

Qu'est ce que c'est cette histoire de pile? Le Forth est un langage à pile, c'est à dire qu'il faut déposer sur une pile les données que l'on veut faire traiter par Forth, et qu'il renvoie lui même les résultats sur cette pile. Ainsi si je veux additionner 2 et 3, je dois les déposer sur la pile en tapant (les commentaires sont entre parenthèses) :
              ( il y a 2 sur la pile )
              ( il y a 2 et 3 sur la pile, 3 au dessus de 2 )
              ( Forth utilise 2 et 3, et renvoie 5 sur la pile )
              ( On affiche le résultat, et la pile est a nouveau vide )
On aurait pu écrire la même phrase Forth comme ceci :
2 3 + .¬

  Notons que la multiplication et l'addition sont commutatives, et que donc l'ordre des opérandes est sans importance, ce qui n'est pas le cas pour la soustraction ou la division, ainsi :
3 2 - .¬        (affichera 1)
2 3 - .¬        (affichera -1)
4 2 / .¬        (affichera 2)
2 4 / .¬        (affichera 0 -division entiere-)

L'état de la pile est très important, c'est pourquoi, on représente souvent l'état de la pile avant et après une opération par un descripteur de pile noté entre parenthèses, ainsi pour l'addition le descripteur est :
( n1 n2 -- n1+n2 ), c'est à dire on prend l'entier n1 et l'entier n2 sur la pile, on fait l'opération symbolisée par les deux tirets ( certains en utilisent trois ), et la pile se retrouve avec un entier étant la somme de n1 et n2 au sommet, on aurait aussi pu écrire le descripteur de pile comme ceci ( n1 n2 -- n3 ), mais on n'aurait moins de précision sur la valeur de n3. Notons que dans le descripteur de pile, l'élément le plus à droite (de part et d'autre des tirets) représente le sommet de la pile. Si l'on veut exécuter l'opération suivante : (1+2)*(5-1), comme Forth ne connait pas les parenthèses pour les calculs, il faudra écrire :
1 2 + 5 1 - * .¬        (déposer 1 et 2 les additionner-première parenthèse- déposer 5 et 1 soustraire le second du premier-deuxième parenthèse- multiplier et afficher)  Décomposons cette formule et affichons l'état de la pile :
1 2¬    ( -- 1 2 )
      ( 1 2 -- 3 )
5 1¬    ( 3 -- 3 5 1 )
      ( 3 5 1 -- 3 4 )
      ( 3 4 -- 12 )
¬      ( 12 -- )

NB : Lorsque Forth attends des ordres, il affiche OK.

ENTRAINEMENTS :

taper dans TF :
HELP +¬
HELP -¬
HELP /¬
HELP *¬
HELP .¬
HELP .s¬


additionner 45 et 65
additionner 5200 et 35000
soustraire 56 et 14
multiplier 55 et 25
multiplier 1375 et 56
diviser 6 par 2
diviser 6 par 4
diviser 4 par 6
effectuer l'opération (15-2)/(5+2)
effectuer l'opération (15*3-5*3)/(12/5+13)
se familiariser avec tout ce bazar! poser des questions s'il y en a (il faut bien saisir le fonctionnement de la pile, et se remémorer qu'elle fonctionne exclusivement en LIFO -dernier empilé, premier dépilé-). Donc en cas de problème pour ces petits entrainements : mèl !

4 mots de vocabulaire :

Continuons par un peu de vocabulaire Forth supplémentaire, ensuite, nous serons capables de créer des mots nouveaux. Les mots nouveaux sont représentés en début de ligne sur les lignes suivantes, avec leurs appellations entre parenthèses :

: (deux points)
; (point-virgule)
( (parenthèse ouvrante)
) (parenthèse fermante)
Comme ces quatres mots font partie du vocabulaire Forth ils ont les fonctions suivantes :
: marque le début de la definition d'un nouveau mot Forth
; marque la fin d'un nouveau mot Forth
( marque le début d'un commentaire dans une définition _les commentaires ne seront pas exécutés_. Notons qu'il faut un espace entre les parenthèses et les mots qui les entourent, comme d'ailleurs tous les autres mots Forth.
) marque la fin d'un commentaire dans une définition.
( et ) sont utilisés en général pour inclure le descripteur de pile dans la définition du nouveau mot. Par exemple, créons un mot qui additionne les deux derniers éléments de la pile, et les multiplie par l'avant-avant dernier, appellons ce mot ADDITION_MULTIPLICATION, le descripteur de pile de ADDITION_MULTIPLICATION sera donc : ( n1 n2 n3 -- (n2+n3)*n1 ), ou bien ( n1 n2 n3 -- n4 ) qui serait moins explicite. Pour créer ADDITION_MULTIPLICATION, nous taperons ceci :
: ADDITION_MULTIPLICATION + * ; ¬ ou bien :
: ADDITION_MULTIPLICATION ( n1 n2 n3 -- n4 ) + * ;¬
puisque les commentaires ne sont pas exécutés.

Mot de pile :

Comme la pile est l'élément central de Forth, il existe des mot spécifiques pour modifier le contenu de la pile :
DUP ( n1 -- n1 n1 ),duplique le nombre au sommet de la pile, et l'empile. ce mot est utile par exemple pour définir un mot qui élèvera un nombre au carré (CARRE) ou au cube (CUBE) :

: CARRE ( n1 -- n1^2 ) DUP * ;¬ CARRE duplique l'élèment au sommet de la pile et en calcule le produit
tapons :
2 CARRE .¬
l'affichage donne 4 OK

EXERCICE 1 :
écrire CUBE ( n1 -- n1^3 ) et l'essayer.

Mot de pile 2 :

DROP ( n1 -- ), enlève le nombre au sommet de la pile.

SWAP ( n1 n2 -- n2 n1 ), échange l'ordre des deux valeurs au sommet de la pile.
EXERCICE 2 : écrire OTEDE ( n1 n2 -- n2-n1 ) et l'essayer (qui fasse par exemple 2 oté de 3)

OVER ( n1 n2 -- n1 n2 n1 ), duplique l'avant dernier élèment de la pile et le dépose au sommet.
EXERCICE 3 : écrire CARREMUL ( n1 n2 -- n1^2*n2 ) et l'essayer qui fasse par exemple 3^2*5

ROT ( n1 n2 n3 -- n2 n3 n1 ), effectue une rotation des trois derniers élèments sur la pile. En fait enlève n1 de sa position et le dépose au sommet.

-ROT ( n1 n2 n3 -- n3 n1 n2 ), effectue une rotation inverse des trois derniers élèments sur la pile. En fait enlève n3 du sommet, et l'insère avant n1.

PICK ( n(a) n(a+1) ... n(a+x) a -- n(a) n(a+1) ... n(a+x) n(a) ), empile l'élèment situé au a-ième rang avant le sommet de la pile, ainsi, si on a la pile de départ : 5 4 3 2 1 , et que l'on fasse 3 PICK , on aura la pile d'arrivée : 5 4 3 2 1 4 , c'est à dire que le nombre 3, que l'on empile avant le PICK, est un paramètre consommé par PICK, et n'est pas compté, et que de plus la numérotation des élèments sur la pile commence au rang zéro pour le sommet de la pile. ( voir HELP PICK dans TF83).

TUCK ( n1 n2 __ n2 n1 n2 ), recopie le sommet de la pile sous les deux derniers élèments empilés.

ROLL ( n(a) n(a+1) ... n(a+x) a -- n(a+x) n(a) ... n(a+x-1) ), effectue une rotation du a-ième élèment vers le sommet de la pile, ainsi si on a la pile de départ : 5 4 3 2 1, et que l'on fasse 3 ROLL, on aura la pile d'arrivée : 5 3 2 1 4, c'est à dire que le nombre 3 que l'on empile avant ROLL, est un paramètre consommé par ROLL, et n'est pas compté, et que de plus la numérotation des élèments sur la pile commence au rang zéro pour le sommet de la pile. ( voir HELP ROLL dans TF83).

NIP ( n1 n2 -- n2 ), enlève l'avant dernier élèment empilé. D'une manière générale, il est toujours bon de faire HELP LE_MOT dans TF83 pour chaque mot dont je donne la définition ci-dessus. Et il est toujours profitable d'empiler quatre ou cinq nombres sur la pile, d'exècuter le mot nouveau défini, et de faire .S pour bien visualiser son action sur la pile. Voici ci-dessous quelques exercices de redéfinition de mots de manipulation de la pile à l'aide d'autres mots de manipulation de la pile. Ces nouvelles définitions sont juste là pour apprendre a bien maitriser l'utilisation de ces mots, il faut bien comprendre que ces mots prédéfinis dans TF83, sont écrits en langage machine, et donc plus rapides dans leurs versions originales : EXERCICE 4 : ecrire -ROTE qui fasse exactement la même chose que -ROT, avec un seul des mots définis ci-dessus ( utilisé deux fois, genre : : -ROTE MOT MOT ; )
EXERCICE 5 : ecrire TUQUE qui fasse exatement la même chose que TUCK, avec deux des mots que nous connaissons déjà.
EXERCICE 6 : écrire NIPPE qui fasse exactement la même chose que NIP à l'aide de deux mots que nous connaissons déjà.
EXERCICE 7 : écrire SWAPE qui fasse exatement la même chose que SWAP à l'aide d'un nombre et d'un mot connu.
EXERCICE 8 : écrire OVEUR qui fasse exactement la même chose qu'OVER à l'aide de mots connus.
EXERCICE 9 : écrire ROTE qui fasse exactement la même chose que ROT à l'aide de... de de débrouillez-vous!
EXERCICE 10 : écrire DUPE qui fasse exactement la même chose que DUP à l'aide de... de de débrouillez-vous!

Lumière sur l'ordinateur :

Revenons à un peu d'architecture d'ordinateurs pour nous changer les idées, et assimiler ce vocabulaire. On peut comparer les ordinateurs a des machines à états successifs, c'est a dire par exemple à l'éclairage d'une scène de théâtre. On éclaire tantôt tel acteur, tantôt tel autre, ou tel élément du décor, etc... Un ordinateur fonctionne exactement de cette façon, mais avec des millions de lampes ( chaque bit de la mémoire peut être assimilé à une lampe ). Seulement, qui dit états successifs, sous-entend temps, un temps pour l'état n, un temps pour l'état n+1. C'est pourquoi tous les ordinateurs sont dotés d'une horloge qui va battre la mesure des temps successifs. La conséquence de cet état de faits, c'est qu'un ordinateur ne sait pas faire plusieurs choses à la fois ( Lorsqu'on ouvre par exemple plusieurs programmes sous Windows, on a l'impression qu'ils s'exécutent en même temps, on dit en parallèle, mais il s'agit juste d'une impression. En réalité les programmes s'exécutent les uns après les autres petits bouts par petits bouts, et on a l'illusion de la simultanéité. ), l'ordinateur fonctionne de manière séquentielle ( il exécute une tâche, puis une autre, et encore une autre, etc... ). Le fonctionnement séquentiel de l'ordinateur est primordial, il permet de définir le programme, comme l'ensemble des tâches successives effectuées par l'ordinateur. La programmation consistant elle a définir les tâches que doit effectuer l'ordinateur pour passer d'un état initial à un état final, en fonction de certaines contraintes. Lorsque l'on a une tâche a programmer, il y a quelques étapes clefs de la construction du programme, certaines peuvent se confondre, mais elles ont forcément fait partie du raisonnement qui conduit au programme final : - définition des buts et des contraintes - définition d'un algorithme (taches successives et points clef du futur programme) - écriture du programme dans le langage de programmation choisi - essais - corrections éventuelles.

Boucle d'or :

Revenons un peu sur les algorithmes. Lorsque nous devons faire une vérification du résultat d'une action précédente, pour atteindre un certain but, on peut être amené a executer cette action plusieures fois ( comme faire un pas pour aller d'un point à un autre, il nous faut le refaire tant qu'on n'est pas arrivés. )On appelle ces renvois en arrière dans l'exècution des programmes des boucles, et chaque parcour de la boucle est appellé itération. Il existe diffèrentes sortes de boucles : Les boucles infinies qui ne se terminent jamais, les boucles indéfinies dont on ne connait pas à l'avance le nombre de fois que l'on va les parcourir et les boucles définies, dont on sait avant d'entrer dedans que l'on va les parcourir n fois. Les boucles et les conditions qui y font entrer ou en sortir sont les élèments les plus importants a maitriser en programmation. Il faut bien comprendre que parce que ce sont des machines binaires, les ordinateurs ne savent répondre que oui ou non ( 1 ou 0 ), et que si l'on veut par exemple savoir si x est compris entre a et b ( a<x><b ) nous devrions tester si a><x, et si x>b, et seulement lorsque ces deux conditions seront remplies, l'ordinateur sera capable de dire a<x><b. une condition très complexe peut toujours traduite plusieures conditions simples ( heureusement, sinon on ne pourrait pas faire grand chose des ordinateurs), c'est la toute la difficulté de la programmation ( diviser en tâches et conditions de plus en plus simples ). Nous reviendrons sur les boucles un peu plus loin.

Les variables :

Une autre notion capitale en informatique, maintenant : les variables. Les variables, peuvent être considérées comme des cellules mémoire d'emplacement fixe et définie, et dont le contenu peut être appelé a évoluer au cours de l'exécution d'un programme. Par exemple, si je veux connaître les valeurs de x qui résolvent l'équation ax+4=0, pour a compris entre -5 et +5, je peux définir une variable a qui contiendra successivement le valeurs -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 à chaque parcours de la boucle (tiens tiens) de résolution de l'équation. Les variables servent aussi à 'passer' des données d'une partie d'un programme à une autre. En Forth, les variables sont aussi utilisées, mais beaucoup moins que dans d'autres langages, du fait de l'utilisation intensive de la pile pour 'passer' des données d'une partie de programme à l'autre ( d'un mot à l'autre en Forth ), en fait on les utilise lorsqu'on a une gestion de pile qui se complique trop à vouloir les éviter. En Forth, les variables doivent être déclarées, c'est à dire qu'on doit signaler à Forth, qu'on crée une variable, ainsi si on veut créer la variable A, on écrira : VARIABLE A , et A sera créée, et contiendra par défaut la valeur 0. Pour changer le contenu de la variable, on se sert du mot ! , oui vous lisez bien le point d'exclamation qui en Forth se nomme 'store', et pour lire le contenu d'une variable on utilise le mot @ , l'arobase qui en Forth se nomme 'fetch'; nous allons illustrer tout cela par un exemple en Forth, mais il nous faut un autre mot, c'est '   \ ', l'anti-slash suivi d'un espace qui indique au Forth que la suite de la ligne constitue un commentaire, et ne doit pas être interprétée ( et ne nécessite donc pas d'être tapée ), donc exemple : ((maintenant que vous savez qu'il faut revenir à la ligne pour plus de clarté, nous n'allons plus indiqué les retours de lignes))

VARIABLE ESSAI   \ Crée la variable essai
ESSAI @ .   \ Lit la variable ESSAI, et affiche son contenu
3 ESSAI !   \ Affecte 3 dans ESSAI¬
ESSAI @ .   \ Lit la variable ESSAI, et affiche son contenu
Il est important de noter qu'une variable, même si son nom est très long ( maximum 31 caractères), ne représente en fait qu'une cellule mémoire de 16 bits ( un mot ), que l'on peut invoquer indifféremment par son nom ou son adresse. Par exemple, si nous tapons simplement maintenant :
ESSAI . , Forth nous affichera un chiffre ( par exemple 15666 -ça peut varier d'un système à l'autre- ) qui est en réalité l'adresse de la variable, et si nous faisons à présent :
15666 @ . nous aurons 3 en réponse. De même les mots @ lit une variable et ! affecte une variable de 16 bits.

Le système Forth lui même utilise des variables pour son fonctionnement, ainsi, il existe une variable nommée BASE, à laquelle il suffit d'affecter la valeur de la base numérique dans laquelle on veut travailler ( par défaut, au démarrage, c'est la valeur 10 ). Donc si on veut passer en base 2, il suffira de taper :
2 BASE !
le mieux étant même de créer un mot qui fasse cela :
: BIN ( -- ) 2 BASE ! ;   \ mot permettant de passer en base 2
Il existe des mots prédéfinis permettant de passer d'une base à l'autre, ce sont les mots :
DECIMAL (passe en base 10),
OCTAL (base 8 -pour les octets-),
HEX (base 16 hexadécimale -pour les mots-).
BIN n'est pas défini d'origine.
Il faut noter que lorsqu'on est passé dans une base, le retour à la base d'origine doit être demandé, sinon on reste dans la dernière base affectée à BASE (logique non ?). Par exemple si on veut connaître la valeur hexadécimale de 62, on tapera
62 HEX .
et on obtiendra l'affichage de 3E, mais si ensuite on tape par exemple 55, on le fera dans le système hexadécimal, ce qui donnera si on fait à la suite DECIMAL . la valeur 85 en base 10. Grâce a ce système de gestion des bases dans Forth, on peut se créer une table de conversion décimal, binaire, hexadécimal, il suffit de créer le mot CVB (CVB pour conversion de base -ou le nom que vous voudrez lui donner) :

: CVB ( -- ) DUP DUP   \ on duplique deux fois le dernier nombre sur la pile
. ." "   \ on en a donc trois copies
    \ . affiche le nombre dans la base courante, ." permet
    \ d'afficher une chaîne de caractères ( ici des espaces
    \ " termine la chaîne de caractères a afficher
BIN   \ il faut l'avoir défini avant, passe en base 2.
. ." "   \ voir ci dessus.
HEX   \ passe en base hexadécimale
. ." "   \ voir ci dessus.
CR   \ 'Carriage Return' , Retour Chariot, renvoie à la
    \ ligne.
DECIMAL ;   \ Repasse en base 10 avant de terminer la définition du
    \ mot.

Si maintenant on tape :
10 CVB¬
on aura :
10 1010 A
Si vous créez une table, il vous suffit d'aller de 0 à 15 en décimal, mais essayez 16 pour visualiser ce qui se passe ensuite en base 2, et surtout en base 16 (pensez alors au quartet). Ensuite vous essayerez 255 et 256 (pensez alors à l'octet). Ensuite vous essayerez 32767 et -32767 (pensez alors au mot, et au problème de la représentation du signe des nombres).

Les constantes :

Il existe aussi une sorte de pseudo-variable en Forth, que l'on appelle constante, qui elle, a une valeur définie une fois pour toute par le mot : CONSTANT . Par exemple si on veut définir la constante AGE avec la valeur 25, on écrira :
25 CONSTANT AGE¬
mais là, contrairement a une variable, on récupérera la valeur de la constante en tapant simplement son nom, ici on tapera : AGE ., et l'affichage renverra 25.

ENTRAINEMENTS (2):

Faire:
HELP VARIABLE
HELP !
HELP @
HELP BASE
HELP DECIMAL
HELP HEX
HELP OCTAL
HELP ."
HELP "

Un autre mot Forth utile : SEE .

SEE permet de voir la définition d'un mot.
Donc, vous ferez aussi par curiosité :
SEE BIN     SEE DECIMAL     SEE HEX     SEE OCTAL .

Personnalisation:

Comme nous l'avons déjà vu Forth utilise un vocabulaire que l'on peut étendre en définissant des mots nouveaux, j'aurais du dire des vocabulaires car il y en a plusieurs, mais nous n'en avons besoin que d'un pour le moment, c'est celui qui est présent au lancement de TF83. Il y a un mot que vous pouvez essayer, c'est WORDS, qui affiche le vocabulaire courant, et si vous frappez tout de suite sur un touche, vous arrêtez le défilement, et vous verrez que les mots en tête de liste sont ceux que vous avez définis.
Vous avez peut être déjà noté un problème, c'est que lorsque vous quittez TF83, et que vous y retournez plus tard, tous les mots que vous aviez définis n'existent plus. Pour remédier à ce problème je vous propose la solution suivante ( il y en a d'autres, mais vous les découvrirez plus tard par vous-même ) : Vous quittez TF83, vous le relancez, vous vérifiez avec WORDS qu'il ne se souvient plus des derniers mots que vous lui aviez appris, et ensuite, nous allons définir le mot ED ( qui appellera le programme EDIT.COM du DOS ) :
: ED ( -- ) " program c:\windows   \command   \edit.com" $EXECUTE ;
ensuite vous taperez les commandes suivantes :
SAVE-SYSTEM c:\forth   \tf83   \tf_a_moi.exe¬ , puis vous allez retourner sous Windows, et vous allez supprimer le raccourci que vous avez vers TFX386.EXE. Vous ouvrirez le lecteur C, le répertoire Forth, le sous-répertoire TF83, et vous sélectionnerez le fichier TF_A_MOI.EXE que vous déplacerez sur le bureau, vous disposerez alors d'un nouveau raccourci vers un système Forth avec la commande ED intégrée, et qui ne se perdra plus. L'utilité de ED, est la suivante, vous pouvez désormais appeler EDIT.COM en tapant : ED¬ Là vous pouvez vous servir d'EDIT normalement, charger, écrire, sauvegarder des fichier, etc.., et lorsque vous ferez 'Fichier''Quitter', vous vous retrouverez directement sous Forth, en fait on a juste remplacé l'éditeur par défaut de Forth. Maintenant, lorsqu'on définira des mots, vous pourrez les taper dans EDIT, et vous sauvegarderez les fichiers sous le nom que vous aurez choisi ( pour les exemples ou les exercices ). par exemple : EXEMP.FTH, l'extension .FTH est importante car elle est reconnue par Turbo-Forth par défaut. Par ailleurs, il serait bon que vous les enregistriez ( les fichiers ) dans le répertoire c:\forth   \tf83, car TF83 ne reconnaît pas les noms longs de répertoire ou de fichier de Windows, il ne connait que ceux du DOS à 8 lettres, un point et 3 lettres d'extension. Ainsi supposons que nous créions un mot, nous tapons ED et nous sommes sous EDIT.COM, là, nous tapons la définition de notre mot :
: BASE? ( -- ) ." La base courante est la base : " BASE @ DUP DECIMAL . BASE ! ;
Puis nous faisons 'Fichier''Enregistrer sous' nous tapons le nom du fichier ( ici EXEMP.FTH ) nous sélectionnons le répertoire de sauvegarde, et nous cliquons sur OK. Nous faisons 'Fichier''Quitter' et nous sommes à nouveau sous TF83, là un WORDS nous montre que BASE? n'existe pas. Nous allons donc l'inclure a l'aide du mot INCLUDE . Si EXEMP.FTH a bien été enregistré sous c:\forth   \tf83, répertoire ou se trouve normalement TF_A_MOI.EXE, il suffit de taper :
INCLUDE EXEMP¬ et un WORDS nous montrera que tout se passe comme si on avait tapé BASE? directement au clavier sous TF. D'ailleurs vous pouvez essayer BASE? à ce niveau là, en changeant la base courante, pour voir s'il fonctionne bien. Dans le cas ou le fichier à charger ne se trouve pas dans le même sous répertoire que TF, il faut indiquer le chemin d'accès complet, par exemple :
INCLUDE c:\forth   \tf83   \essais   \EXEMP.FTH¬
ou bien :
CHDIR c:\forth   \tf83   \essais   \ INCLUDE EXEMP.FTH¬
L'avantage de ce système, vous l'avez déjà deviné, c'est de pouvoir rappeler des mots déjà défini, et de pouvoir corriger les éventuelles fautes de frappe ou de programmation, et de pouvoir 'recharger' le fichier corrigé, ou augmenté.

EXERCICE 11 :

Commenter la définition du mot BASE? pour voir si vous avez
bien tout ce qui précède.

A présent, un peu de vocabulaire supplémentaire :

FORGET <mot> ( -- ), efface les mots définis dans Forth par l'utilisateur, après le mot <mot>, y compris celui ci. TF se retrouve alors avec le vocabulaire qu'il avait avant la définition de <mot>. Par exemple, définissons les mots suivants :
: TOTO ( mot vide ) ;
: BECASSINE ( mot vide ) ;
: DONALD ( mot vide ) ;

si nous faisons WORDS¬ suivi d'une frappe rapide sur une touche, les premiers mots qui apparaissent en haut à gauche de l'écran sont dans l'ordre :
DONALD BECASSINE TOTO ...
faisons maintenant :
FORGET BECASSINE¬
un nouveau WORDS¬ affichera désormais :
TOTO ...

HERE ( -- adr ), renvoie l'adresse du premier emplacement libre du dictionnaire de Forth. C'est là que nous commençons vraiment à jouer avec l'outil qu'est le Forth, ca nous allons le faire se modifier lui même.

FENCE ( -- ), Variable qui contient l'adresse limite en dessous de laquelle une définition ne peut plus être supprimée par FORGET <mot>. Reprenons l'exemple précèdent, après avoir défini nos trois mots, si nous faisons :

HERE

  \ nous empilons l'adresse du premier emplacement libre dans le dictionnaire.

FENCE !

  \ nous affectons l'adresse renvoyée par HERE à la variable FENCE

 

  \ autrement dit nous demandons à Forth de placer la limite en dessous

 

  \ de laquelle il ne doit plus supprimer les définitions par FORGET au

 

  \ niveau de DONALD.

Si maintenant, nous tentons de faire mettons FORGET TOTO¬ , TF nous renverra le message d'erreur suivant : "Partie du dictionnaire protégée"

Continuons notre jeu avec le dictionnaire de Forth, mais pour cela, il nous faut définir quelques notions nouvelles sur le fonctionnement de Forth :
comment est organisé un mot dans le dictionnaire ?
Un mot Forth est constitué de plusieurs parties accolées les unes aux autres, dans TF, l'organisation est la suivante :

  • un VFA ( View Field Adress ) adresse du champs de vue, qui sert a Forth pour faire ses recherches avec HELP.
    un LFA ( Link Field Adress ) adresse du champs de lien, qui pointe vers la définition du mot précèdent dans le dictionnaire.
    un NFA ( Name Field Adress ) adresse du champs de nom, qui contient le nom du mot.
    un CFA ( Code Field Adress ) adresse du champs de code, qui contient le code machine nécessaire à l'exécution du mot.
    un PFA ( Parameters Field Adress ) adresse du champs de paramètres, qui contient les adresses des mots qui constituent la définition du présent mot.

Le code ASCII:

c'est un code qui affecte une lettre à une valeur numérique codée sur un octet (soit 256 valeurs). En réalité, seuls les codes de 0 à 127 servent a coder l'alphabet majuscules/minuscules, les signes de ponctuation et les nombres ( soit 7 bits ) , les autres de 128 à 256 ( 8 bits ) sont les codes semi-graphiques. Le code ASCII est très important, car de très nombreuses choses en informatiques sont codées par son intermédiaire. Ainsi, en Forth aussi, les mots sont codés en ASCII, en ASCII pur, puisque Forth n'admet pas les caractères semi-graphiques dans les noms de mots. Donc les noms de mots sont codés à l'aide d'octets dont le bit 7 est à 0.

Très souvent ( mais pas toujours, puisqu'il faut des exceptions pour confirmer les règles, on commence les numérotation à 0 ), il en est ainsi dans un octet qui rappelons-le contient 8 bits. Par exemple un octet contient la valeur 177 (décimale),

nous l'écrirons en binaire :
1 0 1 1
0 0 0 1
et nous numéroterons les bits ainsi :
7 6 5 4
3 2 1 0

Si j'ai séparé les 2 quartets, c'est pour introduire la notion de poids fort et de poids faible : on appelle par exemple ici les bits 7, 6, 5, 4 le quartet de poids fort, parce que dans l'octet, ce sont eux qui représentent la valeur la plus grande, et les bits 3, 2, 1, 0 le quartet de poids faible, parce qu'ils représentent la valeur la plus petite. Ainsi dans un groupe, le sous groupe le plus à gauche est de poids fort, et le plus à droite de poids faible, on parlera d'octet de poids faible et de poids fort dans un mot de 16 bits, de mot de poids faible et de poids fort dans un mot-long, etc... Attention, le fait d'être de poids faible ne signifie pas négligeable les humhum de poids faibles sont tout aussi indispensables que ceux de poids fort, les uns n'existent pas sans les autres. Dans des groupes de deux entités ou plus, comme dans les octets de huit bits, chaque bit plus à gauche que le ou les précédents a un poids plus fort, si on parle par exemple des bits n°1 et 3, le bit n°3 a un poids plus fort que le n°1.

Revenons à nos noms de mots Forth qui ne contiennent que des caractères codés en ASCII pur, avec le bit de poids fort à 0, ce n'est pas tout à fait vrai, puisque la dernière lettre du nom du mot est codée en ASCII sur 7 bits, mais pour savoir que c'est la fin du nom du mot, à sa création Forth met le bit n°7 à 1, nous allons le vérifier à l'aide des mots suivants :
C@ ( adr -- c )      \ lit un octet à l'adresse adr(sur 16 bits) et l'empile
' <mot> ( -- cfa )      \ il s'agit de l'apostrophe -prononcer tick- empile
                                \ l'adresse du champs de code du mot <mot>
>NAME ( cfa -- nfa )      \ empile l'adresse du champs de nom en consommant celle
                                        \ du champs de code.
EMIT ( c -- )     \ affiche le caractère correspondant à la valeur empilée

Tapons maintenant la séquence suivante :
' DONALD¬      \ empile l'adresse de champs de code du mot DONALD
>NAME¬     \ la transforme en adresse du champs de nom
¬                   \ l'affiche.
nous obtenons par exemple 31305 ( ça peut varier d'un système à l'autre,
mais le principe reste identique, ajoutons 1 à cette adresse pour nous
trouver sur l'adresse contenant la première lettre, et faisons :
31305 c@ .¬   \ nous affichons la valeur contenue à l'adresse 31305
31306 c@ .¬
31307 c@ .¬
31308 c@ .¬
jusqu'à 31311, en nous obtenons logiquement les valeurs suivantes :
68, 79, 78, 65, 76, 196. Nous nous arrêtons à 196 puisque c'est une valeur
supérieure à 127, et que nous avons donc atteint la fin du nom du mot Donc
dans la suite, nous soustrairons 128 à 196 pour obtenir le rang ASCII de la
dernière lettre du nom du mot ( soit ici 196-128=68 ).
Continuons notre expérience en tapant à présent :
68 EMIT   \ l'affichage renvoie : D
79 EMIT   \ " " O
78 EMIT   \ " " N
65 EMIT   \ " " A
76 EMIT   \ " " L
68 EMIT   \ " " D