Rechercher et remplacer un caractère particulier


Dans le texte, nous voulons introduire le "gras" sous la forme :
acolade ouvrant texte gras acolade fermant.
Cela suppose que l'on sait rechercher et remplacer un caractère.

Préalables : affecter un contenu textuel à une variable


Création de la variable

Dans l'ordre :
- Définition de la longueur de la chaine à l'aide d'une variable
- création de la variable, appelée ici boite, par analogie avec le fait qu'on va la remplir d'un contenu.
Remarque : On a simplement réservé un espace de 256 caractères et associé une adresse au mot boite.
256 Constant max-line
create boite max-line allot

Comment introduire une chaîne de caractère ?


Rappel :
Dans Gforth, le transfert du contenu d'une chaine se fait par l'utilisation du mot s" ".
Exemple :
s" blablabla"
- place le texte blablabla dans une zone tampon provisoire
- retourne sur la pile : l'adresse de ce tampon et la longueur de la chaine. Cela se traduit par la représentation conventionnelle :
s" " ( -- adresse-tampon-provisoire longueur )

Que se passe-t-il quand on appelle une variable ?


Quand on appelle une variable, son adresse est empilée (placée au sommet de la pile. Il s'agit en fait d'un pointeur.
Exemple :
boite ( -- adresse-de-la-variable )

Transférer une chaîne dans une variable


Le mot Gforth est cmove.
La syntaxe est la suivante :
Adresse-initiale Adresse-de-destination longueur cmove
Le mot cmove détruit les trois valeurs du sommet de la pile.

Exemple :
s" Il est revenu, {le} temps du muguet" boite cmove

Afficher le contenu d'une chaîne


Le mot Gforth est type.
La syntaxe est la suivante :
Adresse longueur type
Exemple :
boite type ne marchera pas : il manque la longueur à afficher.
Remarquons que celle-ci a été "mangée" par cmove.
Il faut donc la conserver dans une variable numérique.

Le seul moyen provisoire est de faire par exemple
boite 10 type
... qui fonctionne. Mais boite 100 type donnera des choses curieuse...

Chaines implicite ou explicites


Ces deux adjectifs permettent de caractériser le fait que la chaîne de caractère "transporte avec elle" (ou non) sa longueur.
Dans le Pascal, la longueur d'une chaîne (de type String) est stockée dans le premier octet de celle-ci. A cause de cela, elle ne peut pas dépasser la longueur de 255 caractères.
Dans le C, la fin d'une chaîne est marquée par le caractère 0 et, si l'on veut conserver la longueur il faut la stocker dans une variable numérique.
Dans Gforth, on fait comme on veut...
Dans les exemples donnés ici la longueur de la chaîne est stockée dans une variable numérique annexe.

Déclaration et utilisation d'une variable numérique


Pour la suite du travail, nous allons <éer deux variables numériques :
variable lg 0 ( longueur de la boite lue dans le fichier )
variable n2 0 ( position dans la boite )
Il s'agit en fait de pointeurs.

Pour affecter une valeur à une variable numérique on fait :
adresse-de-la-variable nombre !
Exemple :
lg 12 ! ( affecte la variable 12 à la variable lg )

Pour empiler la valeur d'une variable numérique on fait :
adresse-de-la-variable @
Exemple :
lg @ . (le . permet de "voir" la valeur empilée )

Créer un mot qui affecte le texte et conserve la longueur de celui-ci


Ce mot s'appelle affecte (idée d'affectation).
Il est appelé ainsi :
s" contenu" variable affecte

Code du mot


: affecte ( adr1 u adr2 -- )
swap dup lg ! cmove ;

Seul point obscur : swap.
Ce mot échange u et adr2 au sommet de la pile de façon à respecter la syntaxe de cmove.
dup permet de dupliquer la longueur avant qu'elle ne soit "mangée" par l'affectation à lg (par le mot !).

Appel du mot affecte


s" Il est revenu, {le} temps du muguet" boite affecte

Incrémenter une variable numérique


Le mot s'appelle incr.
Il est appelé ainsi :
variable-numérique incr

Code du mot

: incr ( adr -- ) dup @ 1 + swap ! ;
Logique de codage :
Au moment de l'appel du mot, l'adresse de la variable numérique a été emplilée.
dup duplique cette adresse
@ charge le contenu de cette adresse sur la pile (et la "mange", ce qui explique le recours à dup)
1 + augmente de 1 le nombre contenu sur la pile
swap met dans le bon ordre adresse et valeur
! charge le nombre dans la variable située à l'adresse empilée.

Remplacer { par <b>


Pour cette expérimentation, le résultat s'affiche à l'écran, ce qui explique l'usage du mot "type".

Code du mot

: si{ ( adr --) dup 1 s" {" compare 0 =
if s" <b>" type
else si}
endif ;

Explications complémentaires


s" {" compare 0 = le caractère pointé par "adr" est-il { ?
if s" <b>" type si oui, affiche <b>
sinon exécute le mot si}

Et maintenant tout le code


Le programme s'appelle "parcours.fs".
Se souvenir qu'on lui a fait
chmod +x parcours.fs
et que le s<ipt se lance par ./parcours.fs

#! /usr/local/bin/gforth

256 Constant max-line
<eate boite max-line allot
variable lg 0 ( longueur de la boite lue dans le fichier )
variable n2 0 ( position dans la boite )

: affecte ( adr1 u adr2 -- )
swap dup lg ! cmove ;

s" Il est revenu, {le} temps du muguet" boite affecte

: incr ( adr -- ) dup @ 1 + swap ! ;

: si} ( adr --) dup 1 s" }" compare 0 =
if s" </b>" type
else 1 type
endif ;

: si{ ( adr --) dup 1 s" {" compare 0 =
if s" <b>" type
else si}
endif ;


: boucle begin
boite n2 @ + si{
n2 incr
lg @ n2 @ =
until ;

boucle

bye




Haut de page