Forth/Conserver des données

Début de la boite de navigation du chapitre

N'importe quel programme a besoin de conserver des informations en mémoire. Un jeu vidéo, par exemple, a besoin à tout moment de pouvoir accéder à des données telles que la vie, la force ou la position d'un personnage. De telles données sont appelées des variables : les valeurs sont entreposées à un certain emplacement dans la mémoire, emplacement qu'on pourra lire (accéder à une variable) ou sur lequel on pourra écrire (modifier une variable).

Conserver des données
Icône de la faculté
Chapitre no 3
Leçon : Forth
Chap. préc. :Structure d'un programme
Chap. suiv. :Branchements
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Forth : Conserver des données
Forth/Conserver des données
 », n'a pu être restituée correctement ci-dessus.

En bricolant nous-mêmes

modifier

Manipuler la mémoire est une opération triviale en Forth. Pour l’heure, la mémoire que nous allons être ammenés à manipuler est celle du dictionnaire, c'est-à-dire l'espace où nos mots sont conservés sous forme compilée (ce n'est donc absolument pas au même endroit que la pile).

DP, @ et !

modifier

Un mot permet d'obtenir l'adresse du prochain emplacement libre dans le dictionnaire ; c’est à cet emplacement que nous stockerons nos données. Ce mot est HERE (ici). Un appel à HERE place donc une adresse sur la pile :

HERE . -1221991536  ok

Cette adresse est libre. Ça ne signifie pas qu’il n'y a rien d'écrit à cet emplacement, mais plutôt que ce qui est écrit n'a pas d'importance et n’est pas défini. Vous savez désormais que le dictionnaire se remplit au fur et à mesure qu'on y ajoute des définitions, par conséquent la valeur que nous donne HERE est loin d’être constante : à chaque fois qu'on crée un mot ou une variable, on progresse dans la mémoire :

HERE  ok
: TEST  ;  ok
HERE SWAP - . 28  ok

Que se passe-t-il ici ?

  • on pose l'adresse du prochain espace libre du dictionnaire sur la pile ;
  • on défini un nouveau mot, donc on repousse l'adresse du prochain espace libre ;
  • on soustrait l'ancienne adresse à l'actuelle, et on s'aperçoit que HERE pointe 28 octets plus loin dans la mémoire : notre mot TEST a occupé 28 octets du dictionnaire.

Et si on regardait la définition de HERE ?

SEE HERE
: HERE
   DP @ ; ok

Que peut bien signifier DP @ ? C'est très simple :


Il est maintenant important de saisir une nuance :

  • HERE récupère une valeur (l'adresse du prochain espace libre) à une adresse donnée, et la pose sur la pile ;
  • DP donne cette adresse.


Nous savons désormais lire des informations grâce à @ (fetch). Étudions maintenant le mot qui nous permet d'écrire de l'information :


Rien de bien compliqué :

42 HERE !  ok
HERE @ . 42  ok

Il est toutefois nécessaire d’être prudent lorsqu'on utilise ! (store), il ne vérifie parfois pas la validité de l'adresse, auquel cas vous pourriez par mégarde écraser des données importantes pour le système.

Amusons-nous à éditer DP :

0 DP !  ok
HERE . 0  ok

Voilà, DP pointe désormais vers l'adresse 0. Comme un certain nombre de mots se basent sur HERE pour fonctionner, cette petite fantaisie risque bien de paralyser rapidement le système Forth. Ne faites donc pas n’importe quoi avec store !

 

Cette section est difficile à comprendre. Même si elle ne fait intervenir que des notions du niveau indiqué, il est conseillé d'avoir du recul sur les notions présentées pour bien assimiler ce qui suit.


En Forth, une variable est un mot qui pointe vers un endroit en mémoire : sa valeur. DP est donc une variable :

  • de nom DP ;
  • qui vaut DP @, la prochaine adresse libre du dictionnaire.

Vous savez placer une information en mémoire, mais vous ne savez pas associer cet espace à un nom ; c’est le travail du mot CREATE :


Un exemple pour mieux comprendre :

CREATE QUATRE  ok
4 HERE !  ok
HERE @ . 4  ok
QUATRE @ . 4  ok

TROIS permet donc de récupérer une adresse bien précise, celle qui suivait la sienne propre lors de sa création via CREATE. Définissons une autre variable :

CREATE DEUX  ok
2 HERE !  ok
DEUX @ . 2  ok
QUATRE @ . -1222577264  ok

Aïe, en définissant DEUX (qui vient se placer sur HERE) on a écrasé la valeur vers laquelle pointait QUATRE ; désormais QUATRE pointe sur l'adresse de DEUX ! Afin d’éviter cela, il suffit d'avancer DP en conséquence :

CREATE QUATRE 4 HERE !  ok
CELL DP +!  ok
CREATE DEUX 2 HERE !  ok
QUATRE ? DEUX ? 4 2  ok

Normalement, +! (plus-store) doit vous déconcerter. Il signifie « stocker en additionnant » :


Et si on automatisait tout cela ? Définissons le mot VAR, qui crée une variable et l'initialise avec une valeur donnée :

: VAR ( value "<spaces>name" -- )
   CREATE HERE !
   CELL DP +!
;
4 VAR QUATRE  ok
2 VAR DEUX  ok
QUATRE ? DEUX ? 4 2  ok
2 DEUX +! DEUX ? 4  ok

Pas mal, n'est-ce pas ? Mais il est clair que tout ces préparatifs sont franchement agaçants pour une opération aussi triviale que la définition d'une variable. Comparez avec un code Perl :

my ($quatre, $deux) = (4, 2);

Y'a pas photo, c’est beaucoup plus simple que de réécrire VAR dans chacun de nos programmes. Heureusement, la norme impose aux systèmes Forth un ensemble de mots très pratiques pour créer des variables, et même plus.

En Forth standard

modifier

Reprenons notre définition du mot VAR :

: VAR ( value "<spaces>name" -- )
   CREATE HERE !
   CELL DP +!
;

Allouer de la mémoire

modifier

Lorsque nous souhaitons conserver une information, nous la plaçons au premier espace libre et nous avançons de x le pointeur du dictionnaire : on dit qu'on a alloué x de mémoire.

Notre façons de faire (CELL DP +!) est loin d’être irréprochable :

  • que se passe-t-il s'il n'y a plus de mémoire disponible ?
  • à suivre

Pour cela, ANS Forth défini le mot ALLOT :